asp.net-coreasp.net-core-3.1

Evaluate AuthorizeAttribute in action


One can authorize an action by using the [Authorize] attribute. But I want to only perform authorization on the action in specific conditions, so I cannot use this attribute. I don't think I am able to use IAuthorizationService.AuthorizeAsync as I don't have any policy names. Here's my service configuration in Startup.

services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
            .AddMicrosoftIdentityWebApi(Configuration, "AzureAdB2C");

So my question is, how can I move the [Authorize] evaluation into the action code?


Solution

  • The AuthorizeAttribute will be converted (maybe with others) into an AuthorizeFilter and this filter will be executed with some code that is not equivalent to the simple IAuthorizationService.AuthorizeAsync. But if you want to use that anyway, we can get the default policy (which is used by [Authorize] without any policy specified) by using the IAuthorizationPolicyProvider.GetDefaultPolicyAsync. After that you can authorize the User to get an AuthorizationResult. It is succeeded if the property Succeeded is true. Otherwise, you can have the detailed failure in the property Failure (of type AuthorizationFailure). Here's the code:

    public class TestController 
    {
        readonly IAuthorizationService _authorizationService;
        readonly IAuthorizationPolicyProvider _authorizationPolicyProvider;
    
        public TestController(IAuthorizationService authorizationService,
            IAuthorizationPolicyProvider authorizationPolicyProvider)
        {
            
         _authorizationService = authorizationService;
         _authorizationPolicyProvider = authorizationPolicyProvider;
             
        }
    
        public async Task<IActionResult> SomeAction()
        {
            var defaultPolicy = await _authorizationPolicyProvider.GetDefaultPolicyAsync();
            var authResult = await _authorizationService.AuthorizeAsync(User, defaultPolicy);
    
            if(authResult.Succeeded)
            {
                //do something ...
            }
        }
    }