Search code examples
asp.netasp.net-coreauthorizationasp.net-core-webapiasp.net-authorization

Override AuthorizeAttribute with Policy in aspnet core


Using ASP.NET 5 I've implemented a policy with a requirement that I'd like to apply to most but not all methods within a controller. For the other methods I just want to verify that the current user is authenticated. Is there a way to do this, or do I need to add the [Authorize(Policy="MyPolicy")] to each method individually, instead of on the class?

e.g. I'd like this (but I have lots more methods that should be authorized with the policy):

[ApiController]
[Authorize(Policy="MyPolicy")]
[Route("api/DoStuff")]
public class MyController : ControllerBase
{ 

    // this one is authorized by MyPolicy, based on the class Authorize attribute
    [HttpGet("foo")]
    public GetFoo() 
    {
    }

    // this one is authorized by MyPolicy, based on the class Authorize attribute
    [HttpGet("bah")]
    public GetBah() 
    {
    }

    // This one I just want to check they're authenticated, not enforce "MyPolicy"
    [Authorize] 
    [HttpGet("anybody")]
    public GetForAnybody() 
    {
    }
}

I think in .net webapi I could do this sort of thing with OverrideAuthorizationAttribute.


Solution

  • As far as I know, Asp.net Core doesn't support the OverrideAuthorizationAttribute, and it not suggest to override the controller authorize attribute. You can check this thread.

    So, in your scenario, I think the best workaround is change your code as below:

    [ApiController]
    [Authorize]
    [Route("api/DoStuff")]
    public class MyController : ControllerBase
    { 
    
        // this one is authorized by MyPolicy, based on the class Authorize attribute
        [HttpGet("foo")]
        [Authorize(Policy="MyPolicy")]
        public GetFoo() 
        {
        }
    
        // this one is authorized by MyPolicy, based on the class Authorize attribute
        [HttpGet("bah")]
        [Authorize(Policy="MyPolicy")]
        public GetBah() 
        {
        }
    
        // This one I just want to check they're authenticated, not enforce "MyPolicy"
        //[Authorize]   //since the controller already set the Authorize attribute, there is no need to add it in the action method.
        [HttpGet("anybody")]
        public GetForAnybody() 
        {
        }
    
        // everybody could access
        [AllowAnonymous]  //By using the `[AllowAnonymous]` attribute, you can restrict the controller and then allow anonymous access to specific actions.
        [HttpGet("everybody")]
        public GetForEverybody() 
        {
        }
    }