using System; using System.Linq; using System.Net; using System.Security; using System.ServiceModel; using System.ServiceModel.Channels; using System.ServiceModel.Dispatcher; using System.Xml; using BeWo.Data; using BeWo.Data.Access; using BeWo.Data.Entities; using BeWo.Service.Core; using BS.Shared.Extensions; namespace BeWo.Service.Security { public class SecurityContextInitializer : ICallContextInitializer { public void AfterInvoke(object pCorrelationState) { if (pCorrelationState is LoggedInUserOperationContextExt) { OperationContext.Current.Extensions.Remove((LoggedInUserOperationContextExt)pCorrelationState); } } public object BeforeInvoke(InstanceContext pInstanceContext, IClientChannel pChannel, Message pMessage) { try { ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12; var lTemp = pMessage.Headers.Action.Split("/"); string lMethodName = lTemp[lTemp.Count - 1]; string lServiceInterface = lTemp[lTemp.Count - 2]; // TODO Hier kann man jetzt etwas bauen wer sich für welchen service autorisieren muss... var skip = new string[] { "Download", "Download2", "DownloadInfo", "GetUpdatePlan", "GetUpdateFile" }; if (lMethodName == "IsUserValid" || lMethodName == "IsUserValidTwoFactor" || lMethodName == "ResetTenant" || lMethodName == "ResetAllTenant" || lMethodName == "GetEmailForUserName") { return null; } else if (skip.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 > -1) { XmlReader lReader = pMessage.Headers.GetReaderAtHeader(lSecurityHeaderIndex); if (lReader.ReadToFollowing("Username")) { lUserName = lReader.ReadString(); } if (lReader.ReadToFollowing("Password")) { lPassword = lReader.ReadString(); } ApplicationUser lUser = DAOFactory.UserDAO.FindUserByLoginName(lUserName); if (lUser != null && DAOFactory.UserDAO.CheckPassword(lUser, lPassword)) { if (!HasMethodAuthorization(lUser, 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"); } catch (Exception e) { throw Utils.CreateBeWoFaultException(e); } } private bool HasMethodAuthorization(ApplicationUser lUser, string methodName) { var alwaysAllowed = new string[] { "LoadUserByNameAndPassword", "LoadUserByLoginName", "GetMandator", "LoadEmployee", "GetPersonsHavingBirthday", "GetLastLogins", "GetSupportConceptsWithConferenceDate", "GetExpiringSupportConcepts", "GetPublishedNewsItemsForEmployee", "GetAllActiveEmployeesCompact", "GetHomeViewPanels", "LoadCompactEmployee", "GetTranslationDictionary", "ConvertToNewSubstitutionType" }; if (alwaysAllowed.Contains(methodName)) { return true; } var rights = Utils.GetGrantedRights(lUser); var dict = Method2Rights.GetAuthorizedMethodDictionary(); if (dict.ContainsKey(methodName)) { bool allowed = false; var minimumRechte = dict[methodName]; foreach (var right in minimumRechte) { if (rights.Contains(right)) { allowed = true; } } return allowed; } //var dict = Right2Methods.GetAuthorizedMethodDictionary(); //foreach (var right in rights) //{ // if (dict.ContainsKey(right)) // { // var names = dict[right]; // if (names.Contains(methodName)) // { // return true; // } // return true; // } //} return true; } } }