191 lines
4.8 KiB
C#
191 lines
4.8 KiB
C#
using System;
|
|
using System.Linq;
|
|
using System.Net;
|
|
using System.Reflection;
|
|
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 BeWo.Service.ServiceContracts;
|
|
using BS.Shared.Attributes;
|
|
using BS.Shared.Extensions;
|
|
|
|
namespace BeWo.Service.Security
|
|
{
|
|
public class SecurityContextInitializer : ICallContextInitializer
|
|
{
|
|
private readonly string[] ALLOW_ALWAYS = new string[]
|
|
{
|
|
//"Download",
|
|
//"Download2",
|
|
//"DownloadInfo",
|
|
//"GetUpdatePlan",
|
|
//"GetUpdateFile",
|
|
"ResetAllTenants",
|
|
"IsUserValid",
|
|
"IsUserValidTwoFactor",
|
|
"ResetTenant",
|
|
"GetEmailForUserName",
|
|
"GetTranslationDictionary",
|
|
};
|
|
|
|
private readonly string[] ALLOW_ONLY_WITH_LOGIN = new string[] {
|
|
"LoadUserByNameAndPassword",
|
|
"LoadUserByLoginName",
|
|
"GetMandator",
|
|
"LoadEmployee",
|
|
"GetPersonsHavingBirthday",
|
|
"GetLastLogins",
|
|
"GetSupportConceptsWithConferenceDate",
|
|
"GetExpiringSupportConcepts",
|
|
"GetPublishedNewsItemsForEmployee",
|
|
"GetAllActiveEmployeesCompact",
|
|
"GetHomeViewPanels",
|
|
"LoadCompactEmployee",
|
|
"GetTranslationDictionary",
|
|
"ConvertToNewSubstitutionType" };
|
|
|
|
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...
|
|
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 > -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, lServiceInterface))
|
|
{
|
|
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, string serviceInterface)
|
|
{
|
|
if (ALLOW_ONLY_WITH_LOGIN.Contains(methodName))
|
|
{
|
|
return true;
|
|
}
|
|
else
|
|
{
|
|
// Vergessen neue Methode einzutragen?
|
|
}
|
|
|
|
var rights = Utils.GetGrantedRights(lUser);
|
|
|
|
try
|
|
{
|
|
var name = $"BeWo.Service.ServiceContracts.{serviceInterface}";
|
|
var t = Type.GetType(name);
|
|
var methodInfo = t.GetMethod(methodName);
|
|
var attribute = methodInfo.GetCustomAttribute<RequirePermissionAttribute>();
|
|
if (attribute != null)
|
|
{
|
|
return attribute.HasPermission(rights);
|
|
}
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
|
|
}
|
|
|
|
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;
|
|
}
|
|
|
|
}
|
|
}
|