How can I access current HttpContext to check for route and parameters inside AuthorizationHandlerContext of Custom Policy-Based Authorization inside ASP.NET Core 2?
Ref example: Custom Policy-Based Authorization
How can I access current HttpContext to check for route and parameters inside AuthorizationHandlerContext of Custom Policy-Based Authorization inside ASP.NET Core 2?
Ref example: Custom Policy-Based Authorization
You should inject an instance of an IHttpContextAccessor into your AuthorizationHandler.
In the context of your example, this may look like the following:
public class BadgeEntryHandler : AuthorizationHandler<EnterBuildingRequirement>
{
IHttpContextAccessor _httpContextAccessor = null;
public BadgeEntryHandler(IHttpContextAccessor httpContextAccessor)
{
_httpContextAccessor = httpContextAccessor;
}
protected override Task HandleRequirementAsync(
AuthorizationContext context,
EnterBuildingRequirement requirement)
{
HttpContext httpContext = _httpContextAccessor.HttpContext; // Access context here
if (context.User.HasClaim(c => c.Type == ClaimTypes.BadgeId &&
c.Issuer == "http://microsoftsecurity"))
{
context.Succeed(requirement);
return Task.FromResult(0);
}
}
}
You may need to register this in your DI setup (if one of your dependencies has not already), as follows:
services.AddHttpContextAccessor();
IActionContextAccessor). You may need to do something simillar to what is detailed in this post - How to get params from AuthrizationHandler .net core. The author of this answer is the ASP.NET security guy at Microsoft, so it is authoritative. Whether things have moved on since this post I cannot be sure. Note: I have updated my post with detail regarding DI registration (it may be required).IAuthorizationService to invoke authorization, you can pass anything in the resource.This is from Microsoft docs (for ASP.NET Core 6):
The
HandleRequirementAsyncmethod has two parameters: anAuthorizationHandlerContextand theTRequirementbeing handled. Frameworks such as MVC or SignalR are free to add any object to the Resource property on theAuthorizationHandlerContextto pass extra information.When using endpoint routing, authorization is typically handled by the Authorization Middleware. In this case, the
Resourceproperty is an instance of HttpContext. The context can be used to access the current endpoint, which can be used to probe the underlying resource to which you're routing. For example:if (context.Resource is HttpContext httpContext) { var endpoint = httpContext.GetEndpoint(); var actionDescriptor = endpoint.Metadata.GetMetadata<ControllerActionDescriptor>(); ... }
As others have mentioned, injecting IHttpContextAccessor is another way to access HttpContext.
You can inject an IHttpContextAccessor into your AuthorizationHandlers constructor.
e.g.
public class MyAuthorizationHandler : AuthorizationHandler<MyRequirement>
{
private IHttpContextAccessor _contextAccessor;
public MyAuthorizationHandler (IHttpContextAccessor contextAccessor)
{
_contextAccessor = contextAccessor;
}
protected override Task HandleRequirementAsync(AuthorizationHandlerContext context,
MinimumPermissionLevelRequirement requirement) {
var httpContext = _contextAccessor.HttpContext;
// do things
}
}
If it is an MVC context you can access HttpContext, RouteData and everything else MVC provides like this from AuthorizationContext context:
var mvcContext = context.Resource as Microsoft.AspNetCore.Mvc.Filters.AuthorizationFilterContext;
if (mvcContext != null)
{
// Examine MVC specific things like routing data.
}
In .NET 5 you can use this code:
if(context.Resource.GetType().FullName == "Microsoft.AspNetCore.Http.DefaultHttpContext")
{
var httpContext = context.Resource as Microsoft.AspNetCore.Http.DefaultHttpContext;
}
Without injecting, simple solution!
protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, MyRequirement requirement)
{
var authFilterCtx = (Microsoft.AspNetCore.Mvc.Filters.AuthorizationFilterContext)context.Resource;
var httpContext = authFilterCtx.HttpContext;
}