Authorization rules for MediatR. This library uses pipline behavior IPipelineBehavior<,>
in mediator middleware.
You should install MediatR.RequestAuthorization with NuGet:
Install-Package MediatR.RequestAuthorization
Or via the .NET Core command line interface:
dotnet add package MediatR.RequestAuthorization
Simple implementation for aspnetcore:
public class HttpUserContext : IUserContext
{
public IHttpContextAccessor Http { get; }
public HttpUserContext(IHttpContextAccessor http)
{
Http = http;
User = http?.HttpContext?.User;
}
public virtual string? ExtraAttribute(string key)
{
return null;
}
public ClaimsPrincipal? User { get; }
public string? Id
{
get
{
if (User?.Identity != null && User.Identity.IsAuthenticated)
{
return User.Claims.FirstOrDefault(p => p.Type == ClaimTypes.NameIdentifier)?.Value ?? User.Claims.FirstOrDefault(p => p.Type == "sub")?.Value;
}
return null;
}
}
public string Name => User?.Identity.Name;
public bool IsAuthenticated => User?.Identity != null && User.Identity.IsAuthenticated;
public virtual string? ClaimValue(string claimType)
{
return User?.Claims?.FirstOrDefault(p => p.Type == claimType)?.Value;
}
public virtual bool HasClaim(string type, string value)
{
return User?.HasClaim(type, value) ?? false;
}
public virtual bool HasClaim(Predicate<Claim> match)
{
return User?.HasClaim(match) ?? false;
}
}
services.AddTrancient<IAuthorizationRule<YourQueryOrCommand>,MySecurityRuleImplementation>();
services.AddMediatR(cfg =>
{
cfg.RegisterServicesFromAssemblies(coreAsms); // all core handlers
cfg.AddOpenBehavior(typeof(RequestAuthorizationBehavior<,>)); // enable security
});
Define authorization rule for your IRequest impl class
//your IRequest class
public class GetProfileQuery:IRequest<UserProfile>
{
}
// your IAuthorizationRule class
class GetProfileQuerySecurityRule:IAuthorizationRule<GetProfileQuery>
{
private readonly ISomeService _someService;
public GetProfileQuerySecurityRule(ISomeService someService)
{
_someService = someService;
}
public Task Authorize(TRequest request, IUserContext userContext, CancellationToken cancellationToken)
{
if(userContext.IsAuthenticated)
{
return SecurltyResult.Ok();
}
return SecurityResult.AnonimousUser(request);
}
}
SecurityResult
is a static helper class, that wraps throwing Exceptions
AccessDeniedException
is a helper Exception class. You may use your own exceptions.