diff --git a/Service/Security/SecurityContextInitializer.cs b/Service/Security/SecurityContextInitializer.cs index 2ec993fcf..ecd2cb5c2 100644 --- a/Service/Security/SecurityContextInitializer.cs +++ b/Service/Security/SecurityContextInitializer.cs @@ -13,8 +13,10 @@ using BeWo.Data.Access; using BeWo.Data.Entities; using BeWo.Service.Core; using BeWo.Service.ServiceContracts; +using BeWo.Service.ServiceUtils; using BS.Shared.Attributes; using BS.Shared.Extensions; +using NHibernate.Hql.Ast.ANTLR.Tree; namespace BeWo.Service.Security { @@ -101,7 +103,7 @@ namespace BeWo.Service.Security if (lUser != null && DAOFactory.UserDAO.CheckPassword(lUser, lPassword)) { - if (!HasMethodAuthorization(lUser, lMethodName, lServiceInterface)) + if (!HasMethodAuthorization(lUser, lMethodName, pMessage)) { throw new SecurityException("Methode nicht autorisiert: " + lMethodName); } @@ -120,7 +122,7 @@ namespace BeWo.Service.Security } } - private bool HasMethodAuthorization(ApplicationUser lUser, string methodName, string serviceInterface) + private bool HasMethodAuthorization(ApplicationUser lUser, string methodName, Message pMessage) { if (ALLOW_ONLY_WITH_LOGIN.Contains(methodName)) { @@ -135,10 +137,7 @@ namespace BeWo.Service.Security try { - var name = $"BeWo.Service.ServiceContracts.{serviceInterface}"; - var t = Type.GetType(name); - var methodInfo = t.GetMethod(methodName); - var attribute = methodInfo.GetCustomAttribute(); + var attribute = pMessage.GetCustomAttribute(); if (attribute != null) { return attribute.HasPermission(rights); diff --git a/Service/Service.csproj b/Service/Service.csproj index d80c4bcf7..d74c33099 100644 --- a/Service/Service.csproj +++ b/Service/Service.csproj @@ -529,6 +529,7 @@ + diff --git a/Service/ServiceBehavior/AdminHibernateContextInitializer.cs b/Service/ServiceBehavior/AdminHibernateContextInitializer.cs index 8517ad83f..9d61eb743 100644 --- a/Service/ServiceBehavior/AdminHibernateContextInitializer.cs +++ b/Service/ServiceBehavior/AdminHibernateContextInitializer.cs @@ -14,12 +14,36 @@ namespace BeWo.Service.ServiceBehavior { public void AfterInvoke(object pCorrelationState) { - + if (pCorrelationState != null) + { + WCFHibernateSessionManager.CloseSession(); + OperationContext.Current.Extensions.Remove((SessionOperationContextExt)pCorrelationState); + } } public object BeforeInvoke(InstanceContext pInstanceContext, IClientChannel pChannel, Message pMessage) { - return null; + if (LoggedInUserOperationContextExt.Current?.User is null) + return null; + + try + { + //System.Threading.Monitor.Enter + SessionOperationContextExt lExt = new SessionOperationContextExt(); + //int c = OperationContext.Current.Extensions.Count; + //if (c > 0) + //{ + // int te st = 0; + //} + OperationContext.Current.Extensions.Add(lExt); + WCFHibernateSessionManager.OpenSession(); + return lExt; + } + catch (Exception e) + { + throw new FaultException(e.ToString()); + return null; + } } } } diff --git a/Service/ServiceBehavior/AdminMultitenancyContextInitializer.cs b/Service/ServiceBehavior/AdminMultitenancyContextInitializer.cs index 6974f261e..718d34335 100644 --- a/Service/ServiceBehavior/AdminMultitenancyContextInitializer.cs +++ b/Service/ServiceBehavior/AdminMultitenancyContextInitializer.cs @@ -10,6 +10,10 @@ using System.Web; using System.Xml; using System.ServiceModel.Dispatcher; using BeWo.Service.Core; +using BS.Shared.Extensions; +using BeWo.Service.ServiceUtils; +using BS.Shared.Attributes; +using static System.Windows.Forms.VisualStyles.VisualStyleElement.StartPanel; namespace BeWo.Service.ServiceBehavior { @@ -29,6 +33,14 @@ namespace BeWo.Service.ServiceBehavior try { + // RequireNoTenant + var lTemp = pMessage.GetCustomAttribute(); + if (lTemp is object) + { + return null; + } + + // Hole tenant aus Query if (pMessage.Properties?.Via is Uri uri) { var query = HttpUtility.ParseQueryString(uri.Query); @@ -37,14 +49,15 @@ namespace BeWo.Service.ServiceBehavior lTenant = tenant; } - if (!string.IsNullOrEmpty(lTenant)) + // Wenn kein Tenant gefunden wird, + if (string.IsNullOrWhiteSpace(lTenant)) { - var lExt = new MultitenancyOperationContextExt { Tenant = lTenant }; - OperationContext.Current.Extensions.Add(lExt); - return lExt; + throw new ArgumentException($"Zugriff verweigert. Tenant (\'{lTenant}\') darf nicht leer sein.", nameof(lTenant)); } - return null; + var lExt = new MultitenancyOperationContextExt { Tenant = lTenant }; + OperationContext.Current.Extensions.Add(lExt); + return lExt; } catch (Exception e) { diff --git a/Service/ServiceBehavior/AdminServiceMessageInspector.cs b/Service/ServiceBehavior/AdminServiceMessageInspector.cs index 58c4f196b..24360875a 100644 --- a/Service/ServiceBehavior/AdminServiceMessageInspector.cs +++ b/Service/ServiceBehavior/AdminServiceMessageInspector.cs @@ -30,11 +30,11 @@ namespace BeWo.Service.ServiceBehavior } // Hole erlaubten API Key aus den appSettings - string allowedApikey = ConfigurationManager.AppSettings["AdminServiceIPAddress"]; + string allowedApikey = ConfigurationManager.AppSettings["AdminServiceAPIKey"]; // Extrahiert den API Key von Remote var prop = (HttpRequestMessageProperty)request.Properties[HttpRequestMessageProperty.Name]; - var remoteApikey = prop?.Headers["AdminServiceAPIKey"]; + var remoteApikey = prop?.Headers["admin-service-api-key"]; // Vergleicht die API Keys if(remoteApikey == null || !string.Equals(remoteApikey, allowedApikey, StringComparison.Ordinal)) diff --git a/Service/ServiceContracts/IAdminService.cs b/Service/ServiceContracts/IAdminService.cs index 68351d725..36aab6c82 100644 --- a/Service/ServiceContracts/IAdminService.cs +++ b/Service/ServiceContracts/IAdminService.cs @@ -1,4 +1,5 @@ -using System; +using BS.Shared.Attributes; +using System; using System.Collections.Generic; using System.Linq; using System.ServiceModel; @@ -13,10 +14,12 @@ namespace BeWo.Service.ServiceContracts { [OperationContract] [WebGet(UriTemplate = "/Test", ResponseFormat = WebMessageFormat.Json)] + [RequireNoTenant] string Test(); [OperationContract] [WebInvoke(UriTemplate = "/Echo/{echo}", Method ="POST", ResponseFormat = WebMessageFormat.Json)] + [RequireNoTenant] string Echo(string echo); } } diff --git a/Service/ServiceUtils/ServiceHelper.cs b/Service/ServiceUtils/ServiceHelper.cs new file mode 100644 index 000000000..1602264b2 --- /dev/null +++ b/Service/ServiceUtils/ServiceHelper.cs @@ -0,0 +1,43 @@ +using System; +using System.Collections.Generic; +using System.IdentityModel.Claims; +using System.Linq; +using System.Reflection; +using System.ServiceModel.Channels; +using System.Text; +using System.Threading.Tasks; +using BS.Shared.Attributes; +using BS.Shared.Extensions; +using NHibernate.Hql.Ast.ANTLR.Tree; + +namespace BeWo.Service.ServiceUtils +{ + public static class ServiceHelper + { + public static T GetCustomAttribute(this Message pMessage) where T : Attribute + { + // 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('/'); + + // Hole entsprechende Methode + var name = $"BeWo.Service.ServiceContracts.I{lServiceInterface}"; + var t = Type.GetType(name); + var methodInfo = t.GetMethod(lMethodName); + + // Hole Custome Attribute + var attribute = methodInfo.GetCustomAttribute(); + + return attribute; + } + } +} diff --git a/Shared/Attributes/RequireNoTenantAttribute.cs b/Shared/Attributes/RequireNoTenantAttribute.cs new file mode 100644 index 000000000..ec3a1be3f --- /dev/null +++ b/Shared/Attributes/RequireNoTenantAttribute.cs @@ -0,0 +1,17 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace BS.Shared.Attributes +{ + [AttributeUsage(AttributeTargets.Method, Inherited = true)] + public class RequireNoTenantAttribute : Attribute + { + public RequireNoTenantAttribute() + { + + } + } +} diff --git a/Shared/Shared.csproj b/Shared/Shared.csproj index eea15e1fe..0bb0b2395 100644 --- a/Shared/Shared.csproj +++ b/Shared/Shared.csproj @@ -133,6 +133,7 @@ +