Kann jetzt TemplateURI /= Methodname finden

This commit is contained in:
2025-02-25 11:50:47 +01:00
parent 11aef4b249
commit c41537b56f
9 changed files with 180 additions and 48 deletions

View File

@@ -216,12 +216,12 @@
<SecurityExtension />
</behavior>
<behavior name="webHttpBehaviorConfig">
<!--wichtig: JsonErrorExtension >>> Security(ip) >>> Multitenancy >>> Hibernate!-->
<JsonErrorExtension/>
<!--wichtig: Security(ip) >>> Multitenancy >>> Hibernate >>> JsonErrorExtension-->
<AdminSecurityExtension />
<AdminMultitenancyExtension />
<AdminHibernateSessionExtension />
<webHttp />
<JsonErrorExtension/>
</behavior>
</endpointBehaviors>
<serviceBehaviors>

View File

@@ -122,7 +122,7 @@ namespace BeWo.Service.Security
}
}
private bool HasMethodAuthorization(ApplicationUser lUser, string methodName, Message pMessage)
private bool HasMethodAuthorization(ApplicationUser pUser, string methodName, Message pMessage)
{
if (ALLOW_ONLY_WITH_LOGIN.Contains(methodName))
{
@@ -133,11 +133,24 @@ namespace BeWo.Service.Security
// Vergessen neue Methode einzutragen?
}
var rights = Utils.GetGrantedRights(lUser);
var rights = Utils.GetGrantedRights(pUser);
// Finde Action
var lTemp = pMessage.Headers.Action?.Split("/");
if (lTemp is null)
lTemp = pMessage.Headers.To.Segments.ToList();
if (lTemp is null)
throw new ArgumentException("Kann Action nicht finden");
// Extrahiere MethodeName + ServiceInterface
string lMethodName = lTemp[lTemp.Count - 1].Trim('/');
string lServiceInterface = lTemp[lTemp.Count - 2].Trim('/');
try
{
var attribute = pMessage.GetCustomAttribute<RequirePermissionAttribute>();
var attribute = ServiceHelper.GetCustomAttribute<RequirePermissionAttribute>(lServiceInterface, lMethodName);
if (attribute != null)
{
return attribute.HasPermission(rights);

View File

@@ -530,6 +530,7 @@
<Compile Include="ServiceUtils\DistanceCalculator\OpenrouteServiceAPI.cs" />
<Compile Include="ServiceUtils\ServiceTranslator.cs" />
<Compile Include="ServiceUtils\ServiceHelper.cs" />
<Compile Include="ServiceUtils\UriTemplateResolver.cs" />
<Compile Include="UnitOfWork\HibernateSessionEndpointBehavior.cs" />
<Compile Include="UnitOfWork\HibernateSessionBehaviorExtension.cs" />
<Compile Include="UnitOfWork\HibernateSessionContextInitializer.cs" />

View File

@@ -31,38 +31,37 @@ namespace BeWo.Service.ServiceBehavior
{
string lTenant = null;
try
// RequireNoTenant
var lTemp = ServiceHelper.GetCustomAttribute<RequireNoTenantAttribute>(pChannel.LocalAddress.Uri, pMessage.Headers.To);
if (lTemp is object)
{
// RequireNoTenant
var lTemp = pMessage.GetCustomAttribute<RequireNoTenantAttribute>();
if (lTemp is object)
{
return null;
}
// Hole tenant aus Query
if (pMessage.Properties?.Via is Uri uri)
{
var query = HttpUtility.ParseQueryString(uri.Query);
var tenant = query["tenant"];
lTenant = 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;
return null;
}
catch (Exception e)
//// Hole tenant aus Query
if (pMessage.Properties?.Via is Uri uri)
{
throw Utils.CreateBeWoFaultException(e);
var query = HttpUtility.ParseQueryString(uri.Query);
var tenant = query["tenant"];
lTenant = tenant;
}
// Hole tenant aus Header
if (string.IsNullOrWhiteSpace(lTenant))
{
}
// 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;
}
}
}

View File

@@ -18,6 +18,9 @@ namespace BeWo.Service.ServiceBehavior.JsonError
[DataMember]
public string Message { get; set; }
[DataMember]
public string StackTrace { get; set; }
[DataMember]
public string ExceptionType { get; set; }
}
@@ -30,6 +33,7 @@ namespace BeWo.Service.ServiceBehavior.JsonError
var jsonError = new JsonError
{
Message = error.Message,
StackTrace = error.StackTrace,
ExceptionType = error.GetType().Name
};

View File

@@ -21,5 +21,9 @@ namespace BeWo.Service.ServiceContracts
[WebInvoke(UriTemplate = "/Echo/{echo}", Method ="POST", ResponseFormat = WebMessageFormat.Json)]
[RequireNoTenant]
string Echo(string echo);
[OperationContract]
[WebInvoke(UriTemplate = "/GetGkvSum?start={start}&end={end}", Method = "POST", ResponseFormat = WebMessageFormat.Json)]
object GetGkvAbrechnungSumme(DateTime start, DateTime end);
}
}

View File

@@ -1,4 +1,6 @@
using BeWo.Service.ServiceContracts;
using BeWo.Data.Access;
using BeWo.Service.ServiceContracts;
using DevExpress.Pdf.Native.BouncyCastle.Ocsp;
using System;
using System.Collections.Generic;
using System.Linq;
@@ -20,5 +22,29 @@ namespace BeWo.Service.ServiceImplementations
{
return echo;
}
public object GetGkvAbrechnungSumme(DateTime start, DateTime end)
{
if(start == default(DateTime))
{
return "Start darf nicht default(DateTime) sein";
}
if(end == default(DateTime))
{
return "End darf nicht default(DateTime) sein";
}
var sum = DAOFactory.ScriptDAO.GetGkvSumByDateRange(start, end);
if (sum is decimal s)
{
return sum;
}
else
{
return "Sum ist null";
};
}
}
}

View File

@@ -6,6 +6,7 @@ using System.Reflection;
using System.ServiceModel.Channels;
using System.Text;
using System.Threading.Tasks;
using BeWo.Service.ServiceContracts;
using BS.Shared.Attributes;
using BS.Shared.Extensions;
using NHibernate.Hql.Ast.ANTLR.Tree;
@@ -14,25 +15,63 @@ namespace BeWo.Service.ServiceUtils
{
public static class ServiceHelper
{
public static T GetCustomAttribute<T>(this Message pMessage) where T : Attribute
public static T GetCustomAttribute<T>(Uri baseAddress, Uri request) where T : Attribute
{
// Finde Action
var lTemp = pMessage.Headers.Action?.Split("/");
// Hole Interface
string lInterface = null;
var segments = baseAddress.Segments;
for (int i = 0; i < segments.Length; i++)
{
var seg = segments[i].Trim('/');
if (lTemp is null)
lTemp = pMessage.Headers.To.Segments.ToList();
if (seg.EndsWith(".svc"))
{
lInterface = seg.Substring(0, seg.Length - 4);
}
}
if (lTemp is null)
throw new ArgumentException("Kann Action nicht finden");
// Falls kein Interface gefunden wird
if (string.IsNullOrWhiteSpace(lInterface) )
{
throw new ArgumentException($"Zugriff verweigert. Interface unbekannt");
}
// Extrahiere MethodeName + ServiceInterface
string lMethodName = lTemp[lTemp.Count - 1].Trim('/');
string lServiceInterface = lTemp[lTemp.Count - 2].Trim('/');
// Hole entsprechende Methode
var name = $"BeWo.Service.ServiceContracts.I{lServiceInterface}";
// Wird für URLTemplate != Methodname verwendet
var name = $"BeWo.Service.ServiceContracts.I{lInterface}";
var t = Type.GetType(name);
var methodInfo = t.GetMethod(lMethodName);
var resolver = new UriTemplateResolver(baseAddress, t);
var method = resolver.ResolveMethod(request.AbsoluteUri);
var methodInfo = t.GetMethod(method);
// Rückgabe
return getCustomAttribute<T>(methodInfo);
}
public static T GetCustomAttribute<T>(string pServiceInterface, string pMethodName) where T : Attribute
{
MethodInfo methodInfo = null;
try
{
// Hole entsprechende Methode
var name = $"BeWo.Service.ServiceContracts.I{pServiceInterface}";
var t = Type.GetType(name);
methodInfo = t.GetMethod(pMethodName);
}
catch (Exception)
{
throw new ArgumentException($"Zugriff verweigert. Interface oder Methode unbekannt");
}
return getCustomAttribute<T>(methodInfo);
}
private static T getCustomAttribute<T>(MethodInfo methodInfo) where T : Attribute
{
if (methodInfo == null)
{
throw new ArgumentException($"Zugriff verweigert. Interface oder Methode unbekannt");
}
// Hole Custome Attribute
var attribute = methodInfo.GetCustomAttribute<T>();

View File

@@ -0,0 +1,46 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.ServiceModel.Web;
using System.Text;
using System.Threading.Tasks;
namespace BeWo.Service.ServiceUtils
{
public class UriTemplateResolver
{
private UriTemplateTable _uriTemplateTable;
public UriTemplateResolver(Uri baseAddress, Type serviceType)
{
_uriTemplateTable = new UriTemplateTable(baseAddress);
foreach (var method in serviceType.GetMethods())
{
var webGet = method.GetCustomAttribute<WebGetAttribute>();
var webInvoke = method.GetCustomAttribute<WebInvokeAttribute>();
if (webGet != null)
{
_uriTemplateTable.KeyValuePairs.Add(new KeyValuePair<UriTemplate, object>(
new UriTemplate(webGet.UriTemplate), method.Name));
}
else if (webInvoke != null)
{
_uriTemplateTable.KeyValuePairs.Add(new KeyValuePair<UriTemplate, object>(
new UriTemplate(webInvoke.UriTemplate), method.Name));
}
}
_uriTemplateTable.MakeReadOnly(false);
}
public string ResolveMethod(string requestUri)
{
var match = _uriTemplateTable.MatchSingle(new Uri(requestUri));
return match?.Data as string;
}
}
}