60 lines
1.7 KiB
C#
60 lines
1.7 KiB
C#
using System.Net;
|
|
using Microsoft.AspNetCore.Authorization;
|
|
using Microsoft.Extensions.Options;
|
|
using MxGateway.Server.Configuration;
|
|
using MxGateway.Server.Security.Authorization;
|
|
|
|
namespace MxGateway.Server.Dashboard;
|
|
|
|
public sealed class DashboardAuthorizationHandler(
|
|
IHttpContextAccessor httpContextAccessor,
|
|
IOptions<GatewayOptions> options) : AuthorizationHandler<DashboardAuthorizationRequirement>
|
|
{
|
|
protected override Task HandleRequirementAsync(
|
|
AuthorizationHandlerContext context,
|
|
DashboardAuthorizationRequirement requirement)
|
|
{
|
|
GatewayOptions gatewayOptions = options.Value;
|
|
|
|
if (gatewayOptions.Authentication.Mode == AuthenticationMode.Disabled)
|
|
{
|
|
context.Succeed(requirement);
|
|
|
|
return Task.CompletedTask;
|
|
}
|
|
|
|
if (gatewayOptions.Dashboard.AllowAnonymousLocalhost && IsLoopbackRequest())
|
|
{
|
|
context.Succeed(requirement);
|
|
|
|
return Task.CompletedTask;
|
|
}
|
|
|
|
if (context.User.Identity?.IsAuthenticated != true)
|
|
{
|
|
return Task.CompletedTask;
|
|
}
|
|
|
|
if (!gatewayOptions.Dashboard.RequireAdminScope || HasAdminScope(context))
|
|
{
|
|
context.Succeed(requirement);
|
|
}
|
|
|
|
return Task.CompletedTask;
|
|
}
|
|
|
|
private bool IsLoopbackRequest()
|
|
{
|
|
IPAddress? remoteAddress = httpContextAccessor.HttpContext?.Connection.RemoteIpAddress;
|
|
|
|
return remoteAddress is not null && IPAddress.IsLoopback(remoteAddress);
|
|
}
|
|
|
|
private static bool HasAdminScope(AuthorizationHandlerContext context)
|
|
{
|
|
return context.User.HasClaim(
|
|
DashboardAuthenticationDefaults.ScopeClaimType,
|
|
GatewayScopes.Admin);
|
|
}
|
|
}
|