diff --git a/Service/Attributes/RequireApiAuthorizationAttribute.cs b/Service/Attributes/RequireApiAuthorizationAttribute.cs new file mode 100644 index 000000000..be78af10c --- /dev/null +++ b/Service/Attributes/RequireApiAuthorizationAttribute.cs @@ -0,0 +1,22 @@ +using BS.Shared; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace BeWo.Service.Attributes +{ + [AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, Inherited = true)] + public class RequireApiAuthorizationAttribute : Attribute + { + public RequireApiAuthorizationAttribute() + { + + } + + public WebSecretConfigSetting ApiKeyName { get; set; } = WebSecretConfigSetting.None; + public IPAddressList IPAddressList { get; set; } = IPAddressList.None; + public bool IgnoreTenant { get; set; } = false; + } +} diff --git a/Service/Attributes/RequireApiKeyAttribute.cs b/Service/Attributes/RequireApiKeyAttribute.cs deleted file mode 100644 index 2ec9cfe95..000000000 --- a/Service/Attributes/RequireApiKeyAttribute.cs +++ /dev/null @@ -1,19 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace BeWo.Service.Attributes -{ - [AttributeUsage(AttributeTargets.Method, Inherited = true)] - public class RequireApiKeyAttribute : Attribute - { - public WebSecretConfigSetting ApiKeyName { get; set; } - - public RequireApiKeyAttribute(WebSecretConfigSetting api_key_name) - { - ApiKeyName = api_key_name; - } - } -} diff --git a/Service/Attributes/RequireIPAddressAttribute.cs b/Service/Attributes/RequireIPAddressAttribute.cs deleted file mode 100644 index d8bfe6109..000000000 --- a/Service/Attributes/RequireIPAddressAttribute.cs +++ /dev/null @@ -1,27 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace BeWo.Service.Attributes -{ - [AttributeUsage(AttributeTargets.Method, Inherited = true)] - public class RequireIPAddressAttribute : Attribute - { - //public List AllowedIPs { get; set; } - public IPAddressList IPAddressList { get; set; } - - //public RequireIPAddressAttribute(List allowed_ips) - //{ - // AllowedIPs = allowed_ips; - //} - - //public RequireIPAddressAttribute(string allowedIP) : this(new List() { allowedIP }) { } - - public RequireIPAddressAttribute(IPAddressList iPAddressList) - { - IPAddressList = iPAddressList; - } - } -} diff --git a/Service/Attributes/RequireNoTenantAttribute.cs b/Service/Attributes/RequireNoTenantAttribute.cs deleted file mode 100644 index b375e09c1..000000000 --- a/Service/Attributes/RequireNoTenantAttribute.cs +++ /dev/null @@ -1,17 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace BeWo.Service.Attributes -{ - [AttributeUsage(AttributeTargets.Method, Inherited = true)] - public class RequireNoTenantAttribute : Attribute - { - public RequireNoTenantAttribute() - { - - } - } -} diff --git a/Service/Attributes/RequirePermissionAttribute.cs b/Service/Attributes/RequireWcfAuthorizationAttribute.cs similarity index 71% rename from Service/Attributes/RequirePermissionAttribute.cs rename to Service/Attributes/RequireWcfAuthorizationAttribute.cs index 16e52f74d..ee5d55156 100644 --- a/Service/Attributes/RequirePermissionAttribute.cs +++ b/Service/Attributes/RequireWcfAuthorizationAttribute.cs @@ -1,22 +1,22 @@ -using System; +using BS.Shared; +using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; -using BS.Shared; namespace BeWo.Service.Attributes { - [AttributeUsage(AttributeTargets.Method, Inherited = true)] - public class RequirePermissionAttribute : Attribute + [AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, Inherited = true)] + public class RequireWcfAuthorizationAttribute : Attribute { - public UserRightType[] Permissions { get; } - - public RequirePermissionAttribute(params UserRightType[] permissions) + public RequireWcfAuthorizationAttribute(params UserRightType[] pPermissions) { - Permissions = permissions; + Permissions = pPermissions; } + public UserRightType[] Permissions { get; } + public bool HasPermission(IEnumerable rights) { if (Permissions is null || Permissions.Length == 0) diff --git a/Service/BeWoServiceEnums.cs b/Service/BeWoServiceEnums.cs index 91d76649a..6cd2c3516 100644 --- a/Service/BeWoServiceEnums.cs +++ b/Service/BeWoServiceEnums.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.ComponentModel; using System.Linq; using System.Text; using System.Threading.Tasks; @@ -19,8 +20,10 @@ namespace BeWo.Service ApiServiceTestFilePath } + [DefaultValue(None)] public enum WebSecretConfigSetting { + None = -1, OpenWebUIKey, GetGkvSumApiKey, DownloadReportApiKey, @@ -29,8 +32,10 @@ namespace BeWo.Service GkvSecretKey, } + [DefaultValue(None)] public enum IPAddressList { + None = -1, AdminApi } } diff --git a/Service/Core/ConfigReader.cs b/Service/Core/ConfigReader.cs index f3f996909..bb175d1a0 100644 --- a/Service/Core/ConfigReader.cs +++ b/Service/Core/ConfigReader.cs @@ -12,6 +12,9 @@ namespace BeWo.Service.Core { public static List GetIPAddressList(IPAddressList iPAddressList) { + if(iPAddressList == IPAddressList.None) + throw new ArgumentException(nameof(iPAddressList)); + var lConfigPath = iPAddressList.GetConfigPath(); var lines = File.ReadAllLines(lConfigPath); diff --git a/Service/Core/MergedConfig.cs b/Service/Core/MergedConfig.cs index 8e1e1621d..158666349 100644 --- a/Service/Core/MergedConfig.cs +++ b/Service/Core/MergedConfig.cs @@ -1,4 +1,5 @@ -using System; +using BeWo.Data.Entities; +using System; using System.Collections.Generic; using System.Configuration; using System.IO; @@ -18,6 +19,9 @@ namespace BeWo.Service.Core public static string GetSecretSetting(WebSecretConfigSetting webSecretConfigSetting) { + if (webSecretConfigSetting == WebSecretConfigSetting.None) + throw new ArgumentNullException("webSecretConfigSetting"); + return getSecretSetting(webSecretConfigSetting.ToString()); } diff --git a/Service/Core/ServiceHelper.cs b/Service/Core/ServiceHelper.cs index e2f11b6af..956598193 100644 --- a/Service/Core/ServiceHelper.cs +++ b/Service/Core/ServiceHelper.cs @@ -1,9 +1,12 @@ using System; using System.Reflection; +using System.Runtime.Remoting.Channels; using System.ServiceModel; using System.ServiceModel.Channels; using System.ServiceModel.Dispatcher; +using BeWo.Service.Attributes; using BeWo.Service.ServiceUtils; +using BS.Shared.Extensions; namespace BeWo.Service.Core { @@ -13,7 +16,14 @@ namespace BeWo.Service.Core public static FileLogger WCFErrorLogger { get; } = new FileLogger(MergedConfig.GetSetting(WebConfigSetting.ServiceLogFilePath)); public static FileLogger JsonErrorLogger { get; } = new FileLogger(MergedConfig.GetSetting(WebConfigSetting.ServiceLogFilePath)); - public static Tuple GetInterfaceAndMethodASP(Message request , IClientChannel channel) + public static Tuple GetInterfaceAndMethodWCF(Message request, IClientChannel channel) + { + var lTemp = request.Headers.Action.Split("/"); + string lMethodName = lTemp[lTemp.Count - 1]; + string lServiceInterface = lTemp[lTemp.Count - 2]; + return new Tuple(lServiceInterface, lMethodName); + } + public static Tuple GetInterfaceAndMethodASP(Message request, IClientChannel channel) { // Hole Interface string lInterface = null; @@ -59,7 +69,7 @@ namespace BeWo.Service.Core } // Falls kein Interface gefunden wird - if (string.IsNullOrWhiteSpace(lInterface) ) + if (string.IsNullOrWhiteSpace(lInterface)) { throw new ArgumentException($"Zugriff verweigert. Interface unbekannt"); } @@ -75,6 +85,12 @@ namespace BeWo.Service.Core return getCustomAttribute(methodInfo); } + public static T GetCustomAttribute(Message request, IClientChannel channel) where T : Attribute + { + var (inter, method) = GetInterfaceAndMethodASP(request, channel); + var authentification = GetCustomAttribute(inter, method); + return authentification; + } public static T GetCustomAttribute(string pServiceInterface, string pMethodName) where T : Attribute { MethodInfo methodInfo = null; diff --git a/Service/Core/ServiceValidator.cs b/Service/Core/ServiceValidator.cs index cc225ff66..e514342c0 100644 --- a/Service/Core/ServiceValidator.cs +++ b/Service/Core/ServiceValidator.cs @@ -1,9 +1,15 @@ -using BS.Shared.DataContracts; +using BeWo.Data; +using BeWo.Service.Attributes; +using BS.Shared; +using BS.Shared.DataContracts; using System; using System.Collections.Generic; using System.IO; using System.Linq; +using System.Runtime.Remoting.Channels; using System.Runtime.Serialization; +using System.ServiceModel; +using System.ServiceModel.Channels; using System.Text; using System.Threading.Tasks; @@ -34,5 +40,107 @@ namespace BeWo.Service.Core return true; } + + public static void ValidateConnection(ref Message request, IClientChannel channel) + { + var authentification = ServiceHelper.GetCustomAttribute(request, channel); + + if (authentification is null) + return; + + if (authentification.IPAddressList is IPAddressList ipAddressList && ipAddressList != default) + ValidateIP(ref request, channel, ipAddressList); + + if (authentification.ApiKeyName is WebSecretConfigSetting secret && secret != default) + ValidateMethodApiKey(ref request, channel, secret); + } + + public static object ValidateTenant(ref Message request, IClientChannel channel) + { + var authentification = ServiceHelper.GetCustomAttribute(request, channel); + + if (authentification is object && authentification.IgnoreTenant) + return null; + + string lTenant = null; + + // Hole tenant aus Header + var prop = (HttpRequestMessageProperty)request.Properties[HttpRequestMessageProperty.Name]; + lTenant = prop?.Headers["tenant"]; + + // Wenn kein Tenant gefunden wird, + if (string.IsNullOrWhiteSpace(lTenant)) + { + throw new ArgumentException($"Zugriff verweigert. Tenant (\'{lTenant}\') darf nicht leer sein.", nameof(lTenant)); + } + + var lExt = new MultitenancyOperationContextExt { Tenant = lTenant }; + OperationContext.Current.Extensions.Add(lExt); + return lExt; + } + + private static void ValidateIP(ref Message request, IClientChannel channel, IPAddressList ipAddressList) + { + // Extrahiere die RemoteEndpoint-IP-Adresse + string remoteIP = request.Properties.ContainsKey(RemoteEndpointMessageProperty.Name) + ? ((RemoteEndpointMessageProperty)request.Properties[RemoteEndpointMessageProperty.Name]).Address + : null; + + if (remoteIP == null) + { + throw new UnauthorizedAccessException($"Zugriff verweigert. Remote IP (\"null\") ist nicht erlaubt."); + } + + var allowedIPs = ConfigReader.GetIPAddressList(ipAddressList); + + if (allowedIPs is null || allowedIPs.Count == 0) + { + throw new UnauthorizedAccessException($"Zugriff verweigert. Konfigurationsfehler."); + } + + if (allowedIPs.All(x => !string.Equals(remoteIP, x, StringComparison.OrdinalIgnoreCase))) + { + throw new UnauthorizedAccessException($"Zugriff verweigert. Remote IP ({remoteIP}) ist nicht erlaubt."); + } + } + + //public void ValidateServiceApiKey(ref Message request) + //{ + // //// Hole erlaubten API Key aus den appSettings + // //string allowedApikey = MergedConfig.GetSecretSetting(WebSecretConfigSetting.AdminServiceAPIKey); + + // //// Extrahiert den API Key von Remote + // //var prop = (HttpRequestMessageProperty)request.Properties[HttpRequestMessageProperty.Name]; + // //var remoteApikey = prop?.Headers["admin-service-api-key"]; + + // //// Vergleicht die API Keys + // //if (remoteApikey == null || !string.Equals(remoteApikey, allowedApikey, StringComparison.Ordinal)) + // //{ + // // throw new UnauthorizedAccessException($"Zugriff verweigert. API Key ({remoteApikey ?? "Unbekannt"}) ist nicht erlaubt."); + // //} + //} + + private static void ValidateMethodApiKey(ref Message request, IClientChannel channel, WebSecretConfigSetting secret) + { + // Hole erlaubten API Key aus den appSettings + string allowedApikey = MergedConfig.GetSecretSetting(secret); + + if (string.IsNullOrEmpty(allowedApikey)) + { + return; + + throw new UnauthorizedAccessException($"Zugriff verweigert. Api Key kann nicht geladen werden."); + } + + // Extrahiert den API Key von Remote + var prop = (HttpRequestMessageProperty)request.Properties[HttpRequestMessageProperty.Name]; + var remoteApikey = prop?.Headers[secret.ToString()]; + + // Vergleicht die API Keys + if (remoteApikey == null || !string.Equals(remoteApikey, allowedApikey, StringComparison.Ordinal)) + { + throw new UnauthorizedAccessException($"Zugriff verweigert. API Key ({remoteApikey ?? "Unbekannt"}) ist nicht erlaubt."); + } + } } } diff --git a/Service/Security/SecurityContextInitializer.cs b/Service/Security/SecurityContextInitializer.cs index 60ef4f501..b9e9f1572 100644 --- a/Service/Security/SecurityContextInitializer.cs +++ b/Service/Security/SecurityContextInitializer.cs @@ -2,6 +2,7 @@ using System.Linq; using System.Net; using System.Security; +using System.Security.Cryptography.X509Certificates; using System.ServiceModel; using System.ServiceModel.Channels; using System.ServiceModel.Dispatcher; @@ -13,6 +14,7 @@ using BeWo.Service.Attributes; using BeWo.Service.Core; using BS.Shared.DataContracts; using BS.Shared.Extensions; +using DevExpress.Charts.Native; namespace BeWo.Service.Security { @@ -63,54 +65,34 @@ namespace BeWo.Service.Security { ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12; - var lTemp = pMessage.Headers.Action.Split("/"); - string lMethodName = lTemp[lTemp.Count - 1]; - string lServiceInterface = lTemp[lTemp.Count - 2]; + var (lServiceInterface, lMethodName) = ServiceHelper.GetInterfaceAndMethodWCF(pMessage, pChannel); - // TODO Hier kann man jetzt etwas bauen wer sich für welchen service autorisieren muss... if (ALLOW_ALWAYS.Contains(lMethodName)) - { return null; - } - else - { - // Vergessen neue Methode einzutragen? - } - - string lUserName = null, lPassword = null; int lSecurityHeaderIndex = pMessage.Headers.FindHeader("Security", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"); + if (lSecurityHeaderIndex < 0) + throw new SecurityException("Nicht autorisiert"); - if (lSecurityHeaderIndex > -1) - { - XmlReader lReader = pMessage.Headers.GetReaderAtHeader(lSecurityHeaderIndex); + XmlReader lReader = pMessage.Headers.GetReaderAtHeader(lSecurityHeaderIndex); - if (lReader.ReadToFollowing("Username")) - { - lUserName = lReader.ReadString(); - } + string lUserName = null, lPassword = null; + if (lReader.ReadToFollowing("Username")) + lUserName = lReader.ReadString(); + if (lReader.ReadToFollowing("Password")) + lPassword = lReader.ReadString(); - if (lReader.ReadToFollowing("Password")) - { - lPassword = lReader.ReadString(); - } + ApplicationUser lUser = DAOFactory.UserDAO.FindUserByLoginName(lUserName); - ApplicationUser lUser = DAOFactory.UserDAO.FindUserByLoginName(lUserName); + if (lUser == null || !DAOFactory.UserDAO.CheckPassword(lUser, lPassword)) + throw new SecurityException("Nicht autorisiert"); - if (lUser != null && DAOFactory.UserDAO.CheckPassword(lUser, lPassword)) - { - if (!HasMethodAuthorization(lUser, lMethodName, pMessage)) - { - throw new SecurityException("Methode nicht autorisiert: " + lMethodName); - } + if (!HasMethodAuthorization(lUser, lServiceInterface, lMethodName)) + throw new SecurityException("Methode nicht autorisiert: " + lMethodName); - var lExt = new LoggedInUserOperationContextExt { User = lUser, LoginName = lUserName, UnhashedPassword = lPassword }; - OperationContext.Current.Extensions.Add(lExt); - return lExt; - } - } - - throw new SecurityException("Nicht autorisiert"); + var lExt = new LoggedInUserOperationContextExt { User = lUser, LoginName = lUserName, UnhashedPassword = lPassword }; + OperationContext.Current.Extensions.Add(lExt); + return lExt; } catch (Exception e) { @@ -118,39 +100,19 @@ namespace BeWo.Service.Security } } - private bool HasMethodAuthorization(ApplicationUser pUser, string methodName, Message pMessage) + private bool HasMethodAuthorization(ApplicationUser pUser, string pServiceInterface, string pMethodName) { - if (ALLOW_ONLY_WITH_LOGIN.Contains(methodName)) - { + if (ALLOW_ONLY_WITH_LOGIN.Contains(pMethodName)) return true; - } - else - { - // Vergessen neue Methode einzutragen? - } - - var rights = Utils.GetGrantedRights(pUser); - - // Finde Action - var lTemp = pMessage.Headers.Action?.Split("/"); - - if (lTemp is null) - lTemp = pMessage.Headers.To.Segments.ToList(); - - if (lTemp is null) - throw new ArgumentException("Kann Action nicht finden"); - - // Extrahiere MethodeName + ServiceInterface - string lMethodName = lTemp[lTemp.Count - 1].Trim('/'); - string lServiceInterface = lTemp[lTemp.Count - 2].Trim('/'); try { - var attribute = ServiceHelper.GetCustomAttribute(lServiceInterface, lMethodName); - if (attribute != null) - { - return attribute.HasPermission(rights); - } + var attribute = ServiceHelper.GetCustomAttribute(pServiceInterface, pMethodName); + if (attribute is null) + return true; + + var rights = Utils.GetGrantedRights(pUser); + return attribute.HasPermission(rights); } catch (Exception e) { @@ -159,6 +121,5 @@ namespace BeWo.Service.Security return true; } - } } diff --git a/Service/Service.csproj b/Service/Service.csproj index a1dd6d471..910a3a1ae 100644 --- a/Service/Service.csproj +++ b/Service/Service.csproj @@ -224,10 +224,8 @@ - - - - + + diff --git a/Service/ServiceBehavior/AdminMultitenancyContextInitializer.cs b/Service/ServiceBehavior/AdminMultitenancyContextInitializer.cs index 6d0b84eef..06882171f 100644 --- a/Service/ServiceBehavior/AdminMultitenancyContextInitializer.cs +++ b/Service/ServiceBehavior/AdminMultitenancyContextInitializer.cs @@ -29,43 +29,7 @@ namespace BeWo.Service.ServiceBehavior public object BeforeInvoke(InstanceContext pInstanceContext, IClientChannel pChannel, Message pMessage) { - string lTenant = null; - - var (lInterface, lMethod) = ServiceHelper.GetInterfaceAndMethodASP(pMessage, pChannel); - - var lTemp = ServiceHelper.GetCustomAttribute(lInterface, lMethod); - if (lTemp is object) - { - return null; - } - - // Hole tenant aus Query - // Wird erstmal nicht benötigt. Per Header besser - // Ungefähr auf einem Level wie Username - //if (pMessage.Properties?.Via is Uri uri) - //{ - // var query = HttpUtility.ParseQueryString(uri.Query); - // var tenant = query["tenant"]; - - // lTenant = tenant; - //} - - // Hole tenant aus Header - if (string.IsNullOrWhiteSpace(lTenant)) - { - var prop = (HttpRequestMessageProperty)pMessage.Properties[HttpRequestMessageProperty.Name]; - lTenant = prop?.Headers["tenant"]; - } - - // Wenn kein Tenant gefunden wird, - if (string.IsNullOrWhiteSpace(lTenant)) - { - throw new ArgumentException($"Zugriff verweigert. Tenant (\'{lTenant}\') darf nicht leer sein.", nameof(lTenant)); - } - - var lExt = new MultitenancyOperationContextExt { Tenant = lTenant }; - OperationContext.Current.Extensions.Add(lExt); - return lExt; + return ServiceValidator.ValidateTenant(ref pMessage, pChannel); } } } diff --git a/Service/ServiceBehavior/AdminServiceMessageInspector.cs b/Service/ServiceBehavior/AdminServiceMessageInspector.cs index e6a3880a1..2fbc06076 100644 --- a/Service/ServiceBehavior/AdminServiceMessageInspector.cs +++ b/Service/ServiceBehavior/AdminServiceMessageInspector.cs @@ -20,9 +20,7 @@ namespace BeWo.Service.ServiceBehavior { public object AfterReceiveRequest(ref Message request, IClientChannel channel, InstanceContext instanceContext) { - ValidateIP(ref request, channel); - - ValidateApiKey(ref request, channel); + ServiceValidator.ValidateConnection(ref request, channel); return null; // Keine Zustandsinformationen erforderlich } @@ -31,91 +29,5 @@ namespace BeWo.Service.ServiceBehavior { // Keine zusätzliche Logik erforderlich vor dem Senden der Antwort } - - public void ValidateIP(ref Message request, IClientChannel channel) - { - var (inter, method) = ServiceHelper.GetInterfaceAndMethodASP(request, channel); - - var attr = ServiceHelper.GetCustomAttribute(inter, method); - - if (attr is null) - return; - - // Extrahiere die RemoteEndpoint-IP-Adresse - string remoteIP = request.Properties.ContainsKey(RemoteEndpointMessageProperty.Name) - ? ((RemoteEndpointMessageProperty)request.Properties[RemoteEndpointMessageProperty.Name]).Address - : null; - - if (remoteIP == null) - { - throw new UnauthorizedAccessException($"Zugriff verweigert. Remote IP ({remoteIP ?? "Unbekannt"}) ist nicht erlaubt."); - } - - var ipList = attr.IPAddressList; - var allowedIPs = ConfigReader.GetIPAddressList(ipList); - - if(allowedIPs is null ||allowedIPs.Count == 0) - { - throw new UnauthorizedAccessException($"Zugriff verweigert. Konfigurationsfehler."); - } - - if(allowedIPs.All(x => !string.Equals(remoteIP, x, StringComparison.OrdinalIgnoreCase))) - { - throw new UnauthorizedAccessException($"Zugriff verweigert. Remote IP ({remoteIP ?? "Unbekannt"}) ist nicht erlaubt."); - } - } - - public void ValidateApiKey(ref Message request, IClientChannel channel) - { - ValidateMethodApiKey(ref request, channel); - } - - //public void ValidateServiceApiKey(ref Message request) - //{ - // //// Hole erlaubten API Key aus den appSettings - // //string allowedApikey = MergedConfig.GetSecretSetting(WebSecretConfigSetting.AdminServiceAPIKey); - - // //// Extrahiert den API Key von Remote - // //var prop = (HttpRequestMessageProperty)request.Properties[HttpRequestMessageProperty.Name]; - // //var remoteApikey = prop?.Headers["admin-service-api-key"]; - - // //// Vergleicht die API Keys - // //if (remoteApikey == null || !string.Equals(remoteApikey, allowedApikey, StringComparison.Ordinal)) - // //{ - // // throw new UnauthorizedAccessException($"Zugriff verweigert. API Key ({remoteApikey ?? "Unbekannt"}) ist nicht erlaubt."); - // //} - //} - - public void ValidateMethodApiKey(ref Message request, IClientChannel channel) - { - var (inter, method) = ServiceHelper.GetInterfaceAndMethodASP(request, channel); - - var attr = ServiceHelper.GetCustomAttribute(inter, method); - - if (attr is null) - return; - - var api_key_name = attr.ApiKeyName; - - // Hole erlaubten API Key aus den appSettings - string allowedApikey = MergedConfig.GetSecretSetting(api_key_name); - - if (string.IsNullOrEmpty(allowedApikey)) - { - return; - - throw new UnauthorizedAccessException($"Zugriff verweigert. Api Key kann nicht geladen werden."); - } - - // Extrahiert den API Key von Remote - var prop = (HttpRequestMessageProperty)request.Properties[HttpRequestMessageProperty.Name]; - var remoteApikey = prop?.Headers[api_key_name.ToString()]; - - // Vergleicht die API Keys - if (remoteApikey == null || !string.Equals(remoteApikey, allowedApikey, StringComparison.Ordinal)) - { - throw new UnauthorizedAccessException($"Zugriff verweigert. API Key ({remoteApikey ?? "Unbekannt"}) ist nicht erlaubt."); - } - } } } diff --git a/Service/ServiceContracts/Enhanced/IAiEnhancedService.cs b/Service/ServiceContracts/Enhanced/IAiEnhancedService.cs index e3d1ef6b6..1ea7acbc0 100644 --- a/Service/ServiceContracts/Enhanced/IAiEnhancedService.cs +++ b/Service/ServiceContracts/Enhanced/IAiEnhancedService.cs @@ -18,47 +18,47 @@ namespace BeWo.Service.ServiceContracts.Enhanced { [FaultContract(typeof(BeWoFault))] [OperationContract] - [RequirePermission(UserRightType.AiModuleView, UserRightType.AiModuleView2)] + [RequireWcfAuthorization(UserRightType.AiModuleView, UserRightType.AiModuleView2)] AiConfigDC GetAiConfig(); [FaultContract(typeof(BeWoFault))] [OperationContract] - [RequirePermission(UserRightType.AiModuleViewSetting)] + [RequireWcfAuthorization(UserRightType.AiModuleViewSetting)] AiConfigDC UpdateAiConfig(AiConfigDC toUpdate); [FaultContract(typeof(BeWoFault))] [OperationContract] - [RequirePermission(UserRightType.AiModuleView, UserRightType.AiModuleView2)] + [RequireWcfAuthorization(UserRightType.AiModuleView, UserRightType.AiModuleView2)] IEnumerable GetAiModels(); [FaultContract(typeof(BeWoFault))] [OperationContract] - [RequirePermission(UserRightType.AiModuleView, UserRightType.AiModuleView2)] + [RequireWcfAuthorization(UserRightType.AiModuleView, UserRightType.AiModuleView2)] IEnumerable GetAiConversations(int uicontext, long? oid); [FaultContract(typeof(BeWoFault))] [OperationContract] - [RequirePermission(UserRightType.AiModuleChatAdd)] + [RequireWcfAuthorization(UserRightType.AiModuleChatAdd)] AiConversationDC CreateAiConversation(AiConversationDC conversation, long modell_oid); [FaultContract(typeof(BeWoFault))] [OperationContract] - [RequirePermission(UserRightType.AiModuleChatAdd)] + [RequireWcfAuthorization(UserRightType.AiModuleChatAdd)] AiConversationDC CreateAiConversationWithMessage(AiConversationDC conversation, long modell_oid, string message); [FaultContract(typeof(BeWoFault))] [OperationContract] - [RequirePermission(UserRightType.AiModuleChatClone)] + [RequireWcfAuthorization(UserRightType.AiModuleChatClone)] AiConversationDC CloneAiConversation(long conversation_oid, long? message_oid); [FaultContract(typeof(BeWoFault))] [OperationContract] - [RequirePermission(UserRightType.AiModuleChatDelete)] + [RequireWcfAuthorization(UserRightType.AiModuleChatDelete)] void DeleteAiConversation(long conversation_oid); [FaultContract(typeof(BeWoFault))] [OperationContract] - [RequirePermission(UserRightType.AiModuleChatAdd)] + [RequireWcfAuthorization(UserRightType.AiModuleChatAdd)] AiConversationMessageDC[] SendNewMessage(long conversation, string message); } } \ No newline at end of file diff --git a/Service/ServiceContracts/IAdminService.cs b/Service/ServiceContracts/IAdminService.cs index ecd496e1e..fabd78d81 100644 --- a/Service/ServiceContracts/IAdminService.cs +++ b/Service/ServiceContracts/IAdminService.cs @@ -15,17 +15,17 @@ namespace BeWo.Service.ServiceContracts { [OperationContract] [WebGet(UriTemplate = "/Test", ResponseFormat = WebMessageFormat.Json)] - [RequireNoTenant] + [RequireApiAuthorization(IgnoreTenant = true)] string Test(); [OperationContract] [WebInvoke(UriTemplate = "/Echo/{echo}", Method ="POST", ResponseFormat = WebMessageFormat.Json)] - [RequireNoTenant] + [RequireApiAuthorization(IgnoreTenant = true)] string Echo(string echo); [OperationContract] [WebInvoke(UriTemplate = "/GetGkvSum", Method = "POST", RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)] - [RequireIPAddress(IPAddressList.AdminApi)] + [RequireApiAuthorization(IPAddressList = IPAddressList.AdminApi)] object GetGkvAbrechnungSumme(AdminServiceSumReqDC request); } } diff --git a/Service/ServiceContracts/IApiService.cs b/Service/ServiceContracts/IApiService.cs index 9a6429927..431e82af5 100644 --- a/Service/ServiceContracts/IApiService.cs +++ b/Service/ServiceContracts/IApiService.cs @@ -18,13 +18,12 @@ namespace BeWo.Service.ServiceContracts { [OperationContract] [WebGet(UriTemplate = "/Test", ResponseFormat = WebMessageFormat.Json)] - [RequireNoTenant] + [RequireApiAuthorization(IgnoreTenant = true)] ApiResponse Test(); [OperationContract] [WebInvoke(UriTemplate = "/GetGkvSum", Method = "POST", RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)] - [RequireApiKey(WebSecretConfigSetting.GetGkvSumApiKey)] - [RequireIPAddress(IPAddressList.AdminApi)] + [RequireApiAuthorization(ApiKeyName = WebSecretConfigSetting.GetGkvSumApiKey, IPAddressList = IPAddressList.AdminApi)] ApiResponse GetGkvAbrechnungSumme(AdminServiceSumReqDC request); } } diff --git a/Service/ServiceContracts/IApiStreamService.cs b/Service/ServiceContracts/IApiStreamService.cs index d3c0ebc69..42cf7c757 100644 --- a/Service/ServiceContracts/IApiStreamService.cs +++ b/Service/ServiceContracts/IApiStreamService.cs @@ -15,22 +15,14 @@ namespace BeWo.Service.ServiceContracts [ServiceContract] public interface IApiStreamService { - //[OperationContract] - //[WebGet(UriTemplate = "/DownloadReport", RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)] - //[RequireApiKey(WebSecretConfigSetting.DownloadReportApiKey)] - //[RequireNoTenant] - //Stream DownloadReport(); - [OperationContract] [WebGet(UriTemplate = "/GetPdf", RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)] - [RequireNoTenant] - [RequireIPAddress(IPAddressList.AdminApi)] + [RequireApiAuthorization(IPAddressList = IPAddressList.AdminApi, IgnoreTenant = true)] Stream GetPdf(); [OperationContract] [WebInvoke(UriTemplate = "/GetPdf", Method = "POST", RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)] - [RequireNoTenant] - [RequireIPAddress(IPAddressList.AdminApi)] + [RequireApiAuthorization(IPAddressList = IPAddressList.AdminApi, IgnoreTenant = true)] Stream GetPdf2(); } } diff --git a/Service/ServiceContracts/IGkvAccountingService.cs b/Service/ServiceContracts/IGkvAccountingService.cs index 7f48c3898..beacf7909 100644 --- a/Service/ServiceContracts/IGkvAccountingService.cs +++ b/Service/ServiceContracts/IGkvAccountingService.cs @@ -19,42 +19,42 @@ namespace BeWo.Service.ServiceContracts { [FaultContract(typeof(BeWoFault))] [OperationContract] - [RequirePermission(UserRightType.Finance_Gkv_View)] + [RequireWcfAuthorization(UserRightType.Finance_Gkv_View)] GkvAbrechnungLightDC GetGkvAbrechnung(long oid); [FaultContract(typeof(BeWoFault))] [OperationContract] - [RequirePermission(UserRightType.Finance_Gkv_View)] + [RequireWcfAuthorization(UserRightType.Finance_Gkv_View)] List GetAllGkvAbrechnungen(); [FaultContract(typeof(BeWoFault))] [OperationContract] - [RequirePermission(UserRightType.Finance_Gkv_View)] + [RequireWcfAuthorization(UserRightType.Finance_Gkv_View)] List GetAllGkvAbrechnungenBy(GkvAbrechnungViewFilterDC gkvAbrechnungViewFilter); [FaultContract(typeof(BeWoFault))] [OperationContract] - [RequirePermission(UserRightType.Finance_Gkv_View)] + [RequireWcfAuthorization(UserRightType.Finance_Gkv_View)] string GetProtokollRawDataString(long oid, GkvRawDataType gkvRawData); [FaultContract(typeof(BeWoFault))] [OperationContract] - [RequirePermission(UserRightType.Finance_Gkv_Create)] + [RequireWcfAuthorization(UserRightType.Finance_Gkv_Create)] GkvAbrechnungCreateResponseDC CreateNewGkvAbrechnung(GkvAbrechnungCreateRequestDC request); [FaultContract(typeof(BeWoFault))] [OperationContract] - [RequirePermission(UserRightType.Finance_Gkv_Create)] + [RequireWcfAuthorization(UserRightType.Finance_Gkv_Create)] GkvAbrechnungLightDC UpdateGkvAbrechnung(GkvAbrechnungLightDC abrechnung); [FaultContract(typeof(BeWoFault))] [OperationContract] - [RequirePermission(UserRightType.Finance_Gkv_Delete)] + [RequireWcfAuthorization(UserRightType.Finance_Gkv_Delete)] void DeleteGkvAbrechnung(long oid, long version); [FaultContract(typeof(BeWoFault))] [OperationContract] - [RequirePermission(UserRightType.Finance_Gkv_Send)] + [RequireWcfAuthorization(UserRightType.Finance_Gkv_Send)] GkvAbrechnungSendResponseDC SendNewGkvAbrechnung(GkvAbrechnungSendRequestDC req); [FaultContract(typeof(BeWoFault))] diff --git a/Service/ServiceContracts/IUserService.cs b/Service/ServiceContracts/IUserService.cs index 318f4b71b..6c79691d7 100644 --- a/Service/ServiceContracts/IUserService.cs +++ b/Service/ServiceContracts/IUserService.cs @@ -23,37 +23,37 @@ namespace BeWo.Service.ServiceContracts [FaultContract(typeof(BeWoFault))] [OperationContract] - [RequirePermission(UserRightType.UserView_Delete)] + [RequireWcfAuthorization(UserRightType.UserView_Delete)] void DeactivateUser(long pOid, long pVersion); [FaultContract(typeof(BeWoFault))] [OperationContract] - [RequirePermission(UserRightType.UserGroupView_Delete)] + [RequireWcfAuthorization(UserRightType.UserGroupView_Delete)] void DeactivateUserGroup(long pOid, long pVersion); [FaultContract(typeof(BeWoFault))] [OperationContract] - [RequirePermission(UserRightType.UserView_Delete)] + [RequireWcfAuthorization(UserRightType.UserView_Delete)] void DeactivateUsers(Dictionary pOid2Version); [FaultContract(typeof(BeWoFault))] [OperationContract] - [RequirePermission(UserRightType.UserView_Delete)] + [RequireWcfAuthorization(UserRightType.UserView_Delete)] void DeleteUser(long pOid, long pVersion); [FaultContract(typeof(BeWoFault))] [OperationContract] - [RequirePermission(UserRightType.UserGroupView_Delete)] + [RequireWcfAuthorization(UserRightType.UserGroupView_Delete)] void DeleteUserGroup(long pOid, long pVersion); [FaultContract(typeof(BeWoFault))] [OperationContract] - [RequirePermission(UserRightType.UserGroupView_Delete)] + [RequireWcfAuthorization(UserRightType.UserGroupView_Delete)] void DeleteUserGroups(Dictionary pOid2Version); [FaultContract(typeof(BeWoFault))] [OperationContract] - [RequirePermission(UserRightType.UserView_Delete)] + [RequireWcfAuthorization(UserRightType.UserView_Delete)] void DeleteUsers(Dictionary pOid2Version); [FaultContract(typeof(BeWoFault))] @@ -78,12 +78,12 @@ namespace BeWo.Service.ServiceContracts [FaultContract(typeof(BeWoFault))] [OperationContract] - [RequirePermission(UserRightType.UserView_Create)] + [RequireWcfAuthorization(UserRightType.UserView_Create)] long InsertNewUser(UserDC pUser); [FaultContract(typeof(BeWoFault))] [OperationContract] - [RequirePermission(UserRightType.UserGroupView_Create)] + [RequireWcfAuthorization(UserRightType.UserGroupView_Create)] long InsertNewUserGroup(UserGroupDC pUserGroup); [FaultContract(typeof(BeWoFault))] @@ -116,7 +116,7 @@ namespace BeWo.Service.ServiceContracts [FaultContract(typeof(BeWoFault))] [OperationContract] - [RequirePermission(UserRightType.UserGroupView_Edit, UserRightType.EditAll)] + [RequireWcfAuthorization(UserRightType.UserGroupView_Edit, UserRightType.EditAll)] long UpdateUserGroup(UserGroupDC pUserGroup); [FaultContract(typeof(BeWoFault))]