Files
BeWoPlaner/Service/Security/SecurityContextInitializer.cs

158 lines
5.5 KiB
C#

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;
}
}
}