using BeWo.Data; using BeWo.Service.Attributes; using BS.Shared; using BS.Shared.DataContracts; using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Runtime.Remoting.Channels; using System.Runtime.Serialization; using System.ServiceModel; using System.ServiceModel.Channels; using System.Text; using System.Threading.Tasks; namespace BeWo.Service.Core { public static class ServiceValidator { public static void CheckSerializationError(T data) { var serializer = new DataContractSerializer(typeof(T)); using (var ms = new MemoryStream()) { serializer.WriteObject(ms, data); } } public static bool TryCheckSerializationError(T data) { try { CheckSerializationError(data); } catch (Exception ex) { File.WriteAllText("C:\\temp\\wcf-serialisierungsfehler.txt", ex.ToString()); return false; } return true; } public static void ValidateConnection(ref Message request, IClientChannel channel) { var authentification = ServiceHelper.GetCustomAttribute(request, channel); if (authentification is null) return; if (authentification.IPAddressList is IPAddressList ipAddressList && ipAddressList != IPAddressList.None) ValidateIP(ref request, channel, ipAddressList); if (authentification.ApiKeyName is WebSecretConfigSetting secret && secret != WebSecretConfigSetting.None) ValidateMethodApiKey(ref request, channel, secret); } public static object ValidateTenant(ref Message request, IClientChannel channel) { var authentification = ServiceHelper.GetCustomAttribute(request, channel); if (authentification is object && authentification.IgnoreTenant) return null; string lTenant = null; // Hole tenant aus Header var prop = (HttpRequestMessageProperty)request.Properties[HttpRequestMessageProperty.Name]; lTenant = prop?.Headers["tenant"]; // Wenn kein Tenant gefunden wird, if (string.IsNullOrWhiteSpace(lTenant)) { throw new ArgumentException($"Zugriff verweigert. Tenant (\'{lTenant}\') darf nicht leer sein.", nameof(lTenant)); } var lExt = new MultitenancyOperationContextExt { Tenant = lTenant }; OperationContext.Current.Extensions.Add(lExt); return lExt; } private static void ValidateIP(ref Message request, IClientChannel channel, IPAddressList ipAddressList) { // 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 (\"null\") ist nicht erlaubt."); } var allowedIPs = ConfigReader.GetIPAddressList(ipAddressList); 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}) ist nicht erlaubt."); } } //public void ValidateServiceApiKey(ref Message request) //{ // //// Hole erlaubten API Key aus den appSettings // //string allowedApikey = MergedConfig.GetSecretSetting(WebSecretConfigSetting.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."); // //} //} private static void ValidateMethodApiKey(ref Message request, IClientChannel channel, WebSecretConfigSetting secret) { // Hole erlaubten API Key aus den appSettings string allowedApikey = MergedConfig.GetSecretSetting(secret); 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[secret.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."); } } } }