82 lines
2.7 KiB
C#
82 lines
2.7 KiB
C#
using e_suite.API.Common;
|
|
using e_suite.API.Common.exceptions;
|
|
using eSuite.API.security;
|
|
using eSuite.API.Utilities;
|
|
using Microsoft.AspNetCore.Mvc;
|
|
using System.Security.Claims;
|
|
using Microsoft.AspNetCore.Authorization;
|
|
using Autofac;
|
|
|
|
namespace eSuite.API.Middleware;
|
|
|
|
internal class SecurityAccessMiddleWare
|
|
{
|
|
private readonly RequestDelegate _next;
|
|
private readonly ILifetimeScope _lifetimeScope;
|
|
|
|
public SecurityAccessMiddleWare(RequestDelegate next, ILifetimeScope lifetimeScope)
|
|
{
|
|
_next = next;
|
|
_lifetimeScope = lifetimeScope;
|
|
}
|
|
|
|
public async Task InvokeAsync(HttpContext context)
|
|
{
|
|
var endpoint = context.GetEndpoint() ?? throw new NotFoundException("Endpoint not found");
|
|
|
|
if (endpoint is RouteEndpoint routeEndpoint)
|
|
{
|
|
if (routeEndpoint.RoutePattern.RawText != null)
|
|
{
|
|
var allowAnonymousAttribute = endpoint?.Metadata.OfType<AllowAnonymousAttribute>().FirstOrDefault();
|
|
|
|
var routePatternLower = routeEndpoint.RoutePattern.RawText.ToLower().TrimStart('/');
|
|
if (allowAnonymousAttribute != null || !(routePatternLower.StartsWith("api") || routePatternLower.StartsWith("account")))
|
|
{
|
|
await _next.Invoke(context);
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
var accessKeyAttribute = endpoint?.Metadata.OfType<AccessKeyAttribute>().FirstOrDefault() ?? throw new NotImplementedException("Unable to find AccessKeyAttribute for Endpoint");
|
|
|
|
var userId = GetUserIdFromContextUser(context.User).GetValueOrDefault();
|
|
|
|
var accessKey = accessKeyAttribute.SecurityAccess;
|
|
|
|
await using var requestLifetimeScope = _lifetimeScope.BeginLifetimeScope();
|
|
var roleManager = requestLifetimeScope.Resolve<IRoleManager>();
|
|
|
|
if (await roleManager.HasAnyAccess(userId, accessKey))
|
|
{
|
|
await _next.Invoke(context);
|
|
return;
|
|
}
|
|
|
|
var problemDetails = new ProblemDetails
|
|
{
|
|
Title = "Unauthorised",
|
|
Detail = "User does not have permission to call this method"
|
|
};
|
|
|
|
context.Response.StatusCode = StatusCodes.Status401Unauthorized;
|
|
context.Response.ContentType = "application/json";
|
|
|
|
await context.Response.WriteAsync(problemDetails.ToJson());
|
|
}
|
|
private static long? GetUserIdFromContextUser(ClaimsPrincipal user)
|
|
{
|
|
long? userId;
|
|
try
|
|
{
|
|
userId = user.Id();
|
|
}
|
|
catch
|
|
{
|
|
userId = null;
|
|
}
|
|
|
|
return userId;
|
|
}
|
|
} |