Files
BeWoPlaner/Service/Security/SecurityContextInitializer.cs
2026-01-23 16:28:47 +01:00

125 lines
3.7 KiB
C#

using System;
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;
using System.Xml;
using BeWo.Data;
using BeWo.Data.Access;
using BeWo.Data.Entities;
using BeWo.Service.Attributes;
using BeWo.Service.Core;
using BS.Shared.Extensions;
using DevExpress.Charts.Native;
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 (lServiceInterface, lMethodName) = ServiceHelper.GetInterfaceAndMethodWCF(pMessage, pChannel);
if (ALLOW_ALWAYS.Contains(lMethodName))
return 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");
XmlReader lReader = pMessage.Headers.GetReaderAtHeader(lSecurityHeaderIndex);
string lUserName = null, lPassword = null;
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))
throw new SecurityException("Nicht autorisiert");
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;
}
catch (Exception e)
{
throw Utils.CreateBeWoFaultException(e);
}
}
private bool HasMethodAuthorization(ApplicationUser pUser, string pServiceInterface, string pMethodName)
{
if (ALLOW_ONLY_WITH_LOGIN.Contains(pMethodName))
return true;
try
{
var attribute = ServiceHelper.GetCustomAttribute<RequireWcfAuthorizationAttribute>(pServiceInterface, pMethodName);
if (attribute is null)
return true;
var rights = Utils.GetGrantedRights(pUser);
return attribute.HasPermission(rights);
}
catch (Exception e)
{
}
return true;
}
}
}