ASP.NET 5 Non-Called Policy-Based Authorization Management

Following the docs here, I tried to implement a rule-based authentication scheme. http://docs.asp.net/en/latest/security/authorization/policies.html#security-authorization-handler-example

I ran into a problem that my Handle method was not called in my custom AuthorizationHandler. (He does not rush here). It also introduces the dependency that is currently in the constructor.

Here is the handler authorization code.

using WebAPIApplication.Services; using Microsoft.AspNet.Authorization; namespace WebAPIApplication.Auth { public class TokenAuthHandler : AuthorizationHandler<TokenRequirement>, IAuthorizationRequirement { private IAuthService _authService; public TokenAuthHandler(IAuthService authService) { _authService = authService; } protected override void Handle(AuthorizationContext context, TokenRequirement requirement) { throw new Exception("Handle Reached"); } } public class TokenRequirement : IAuthorizationRequirement { public TokenRequirement() { } } } 

In startup, I have

 // Authorization services.AddSingleton<IAuthorizationHandler, TokenAuthHandler>() .AddAuthorization(options => { options.AddPolicy("ValidToken", policy => policy.Requirements.Add(new TokenRequirement())); }); 

Controller method

 // GET: api/values [HttpGet, Authorize(Policy="ValidToken")] public string Get() { return "test"; } 

Clicking this endpoint returns nothing in the console.

a warning appears.
 warn: Microsoft.AspNet.Mvc.Controllers.ControllerActionInvoker[0] Authorization failed for the request at filter 'Microsoft.AspNet.Mvc.Filters.AuthorizeFilter'. 

I can hit other endpoints that do not have the attribute successfully.

SOS, Jack

+5
source share
4 answers

The answer to this question is mentioned in the commentary on adem caglin, so that he props to it.

The problem is that AuthorizeFilter rejects the request before calling AuthorizationHandler . This is because for each use of the Authorize tag, MVC adds an AuthorizeFilter before the AuthorizationHandler in the pipeline. This AuthorizeFilter checks to see if permissions for current user authentication are allowed. In my case, there were no authorized credentials associated with any user, so this always fails.

The solution (which IMO is somewhat hacky) is to insert a piece of middleware that will execute before any MVC code. This middleware will add a common user identifier to the user (if the user does not already have one).

Therefore, the AuthorizeFilter check will pass, and the Handle method using the AuthenticationHandler method will be executed, and our problem will be solved. The middleware code (which must be added to Configure before calling app.UseMvc(); ) is as follows

  app.Use(async (context, next) => { if (!context.User.Identities.Any(i => i.IsAuthenticated)) { context.User = new ClaimsPrincipal(new GenericIdentity("Unknown")); } await next.Invoke(); }); 

An alternative way to override AuthorizeFilter given below ( Override global authorization filter in ASP.NET Core MVC 1.0 )

Referring to the answer from here ( Authorization based on the main Asp.Net policy ends with 401 Unauthorized )

+3
source

I put this here for reference because I have been thinking about it for too long ...

I met the special requirement and the handler (empty for testing):

 using Microsoft.AspNetCore.Authorization; using System.Threading.Tasks; public class TestHandler : AuthorizationHandler<TestRequirement>, IAuthorizationRequirement { protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, TestRequirement requirement) { context.Succeed(requirement); return Task.CompletedTask; } } public class TestRequirement : IAuthorizationRequirement { } 

Register it in the Startup.cs ConfigureServices() section:

 services.AddAuthorization(options => { options.AddPolicy("Test", policy => policy.Requirements.Add(new TestRequirement())); // Other policies here } 

Added it to my controller method:

 [HttpGet] [Authorize(Policy = "Test")] public IActionResult Index() { Return View(); } 

But it turned out a 403 error (not 401) with each request to the controller method!

Turns out I didn't register TestHandler with the ConfigureServices() (Injection of Dependency) Startup.cs in Startup.cs .

 services.AddSingleton<IAuthorizationHandler, TestHandler>(); 

I hope this saves someone from hitting his head on the table .: |

+9
source

error below, "PermissionHandler.Handle (AuthorizationContext, PermissionRequirement)": no suitable method was found to override

guide me to solve the error

0
source

All Articles