Files
BeWoPlaner/Service/ServiceBehavior/AdminServiceMessageInspector.cs

129 lines
4.0 KiB
C#

using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.ServiceModel.Channels;
using System.ServiceModel.Dispatcher;
using System.ServiceModel;
using System.Text;
using System.Threading.Tasks;
using BeWo.Data;
using BeWo.Service.Attributes;
using BeWo.Service.Core;
using System.Runtime.Remoting.Channels;
using DevExpress.PivotGrid.OLAP;
using BeWo.Service.ServiceUtils;
namespace BeWo.Service.ServiceBehavior
{
public class AdminServiceMessageInspector : IDispatchMessageInspector
{
public object AfterReceiveRequest(ref Message request, IClientChannel channel, InstanceContext instanceContext)
{
ValidateIP(ref request, channel);
ValidateApiKey(ref request, channel);
return null; // Keine Zustandsinformationen erforderlich
}
public void BeforeSendReply(ref Message reply, object correlationState)
{
// Keine zusätzliche Logik erforderlich vor dem Senden der Antwort
}
public void ValidateIP(ref Message request, IClientChannel channel)
{
var (inter, method) = ServiceHelper.GetInterfaceAndMethodASP(request, channel);
var attr = ServiceHelper.GetCustomAttribute<RequireIPAddressAttribute>(inter, method);
if (attr is null)
return;
// Extrahiere die RemoteEndpoint-IP-Adresse
string remoteIP = request.Properties.ContainsKey(RemoteEndpointMessageProperty.Name)
? ((RemoteEndpointMessageProperty)request.Properties[RemoteEndpointMessageProperty.Name]).Address
: null;
if (remoteIP == null)
{
throw new UnauthorizedAccessException($"Zugriff verweigert. Remote IP ({remoteIP ?? "Unbekannt"}) ist nicht erlaubt.");
}
var ipList = attr.IPAddressList;
var allowedIPs = ConfigReader.GetIPAddressList(ipList);
if(allowedIPs is null ||allowedIPs.Count == 0)
{
throw new UnauthorizedAccessException($"Zugriff verweigert. Konfigurationsfehler.");
}
if(allowedIPs.All(x => !string.Equals(remoteIP, x, StringComparison.OrdinalIgnoreCase)))
{
throw new UnauthorizedAccessException($"Zugriff verweigert. Remote IP ({remoteIP ?? "Unbekannt"}) ist nicht erlaubt.");
}
}
public void ValidateApiKey(ref Message request, IClientChannel channel)
{
try
{
ValidateServiceApiKey(ref request);
}
catch (Exception ex)
{
ValidateMethodApiKey(ref request, channel);
}
}
public void ValidateServiceApiKey(ref Message request)
{
// Hole erlaubten API Key aus den appSettings
string allowedApikey = ConfigurationManager.AppSettings["AdminServiceAPIKey"];
// Extrahiert den API Key von Remote
var prop = (HttpRequestMessageProperty)request.Properties[HttpRequestMessageProperty.Name];
var remoteApikey = prop?.Headers["admin-service-api-key"];
// Vergleicht die API Keys
if (remoteApikey == null || !string.Equals(remoteApikey, allowedApikey, StringComparison.Ordinal))
{
throw new UnauthorizedAccessException($"Zugriff verweigert. API Key ({remoteApikey ?? "Unbekannt"}) ist nicht erlaubt.");
}
}
public void ValidateMethodApiKey(ref Message request, IClientChannel channel)
{
var (inter, method) = ServiceHelper.GetInterfaceAndMethodASP(request, channel);
var attr = ServiceHelper.GetCustomAttribute<RequireApiKeyAttribute>(inter, method);
if (attr is null)
return;
var api_key_name = attr.ApiKeyName;
// Hole erlaubten API Key aus den appSettings
string allowedApikey = MergedConfig.GetSecretSetting(api_key_name);
if (string.IsNullOrEmpty(allowedApikey))
{
return;
throw new UnauthorizedAccessException($"Zugriff verweigert. Api Key kann nicht geladen werden.");
}
// Extrahiert den API Key von Remote
var prop = (HttpRequestMessageProperty)request.Properties[HttpRequestMessageProperty.Name];
var remoteApikey = prop?.Headers[api_key_name.ToString()];
// Vergleicht die API Keys
if (remoteApikey == null || !string.Equals(remoteApikey, allowedApikey, StringComparison.Ordinal))
{
throw new UnauthorizedAccessException($"Zugriff verweigert. API Key ({remoteApikey ?? "Unbekannt"}) ist nicht erlaubt.");
}
}
}
}