Require authenticated user in asp.net core but require custom policy in some actions require custom policy
Asked Answered
S

4

7

My Asp.net core site required authentication by default

services.AddMvc(config =>
{
    //only allow authenticated users
    var policy = new AuthorizationPolicyBuilder()
    .RequireAuthenticatedUser()
    .Build();

    config.Filters.Add(new AuthorizeFilter(policy));
});

but for one action I would need to allow anonymous access (/Account/AddUser if there are no users in the database).

I created this custom policy which checks that the user is either authenticated or that the user db is empty.

[Authorize(Policy = "NoUsersInDatabaseOrUserAuthenticated")]
public IActionResult AddUser()
{
    return View();
}

There seems to be an AND between the global policy and this so it won't work. If I add [AllowAnonymous] the policy is not evaluated at all.

How can I replace the global policy with a custom policy for one action?

Snowblink answered 5/4, 2016 at 16:43 Comment(0)
S
8

I ended up leaving the global authentication requirement and put AllowAnonymous on the actions. I then solved the requirement by adding code in the action that checks that the user is either authenticated or that the user db is empty.

Snowblink answered 6/4, 2016 at 8:7 Comment(1)
blogs.msdn.microsoft.com/webdev/2016/03/15/… .. this could helpSerous
A
5

You can't. Policies are additive. So, global will always be there, and then any extra policies are evaluated after. In addition policies require authentication, you can't have a policy that allows unauthenticated users or something else, they must always be authenticated, as authentication acts upon the results of authorization.

Assure answered 5/4, 2016 at 18:42 Comment(3)
Can you have a policy on the controller and then a different one on the route, thus "overriding" the controller policy?Windburn
@Assure You stated that "... polices require authentication ... they must always be authenticated, as authentication acts upon the results of authorization". I'm curious, if Authorize(Policy="SomePolicy") always results in an authenticated user what is the purpose of policy.RequireAuthenticatedUser()?Racemic
Yes, it is 8 years later, but in Dot Net 8 the [AllowAnonymous] tag will override the other wise global policy. See my answer titled "Update DOTNET 8.0" for referenceUteutensil
L
4

You could just remove the global authorization policy, and just authorize at the controller level. If you have a controller labelled with [Authorize] and an action labelled [AllowAnnonymous] (or your own custom policy), then the action specific tag takes precedent.

Leis answered 6/4, 2016 at 7:56 Comment(0)
U
0

Update DOTNET 8.0

Configure global required authenticated user for all controllers, and then add the [AllowAnonymous] tag at your controller or action level for public access

public void ConfigureServices(IServiceCollection services)
{
    /*
        Your other existing config code here
    */

    //Require authenticated user for all controllers
    services.AddAuthorization(options =>
    {
        options.FallbackPolicy = new AuthorizationPolicyBuilder()
            .RequireAuthenticatedUser()
            .Build();
    });
}

Then at your controller level, either Option A for the entire controller, or Option B as shown below

[AllowAnonymous] //Option A: Controller Level
[Route("api/[controller]")]
[ApiController]
public class PublicController : MyControllerBase
{

    [AllowAnonymous] //OptionB at the individual level
    [HttpGet]
    public IActionResult CurrentTime()
    {
        return Ok(new { date = DateTime.UtcNow.ToString() });
    }
}

The [AllowAnonymous] tag will override the global authorisation as stated by Microsoft https://learn.microsoft.com/en-us/aspnet/core/security/authorization/simple?view=aspnetcore-8.0

[AllowAnonymous] bypasses authorization statements. If you combine [AllowAnonymous] and an [Authorize] attribute, the [Authorize] attributes are ignored. For example if you apply [AllowAnonymous] at the controller level:

Any authorization requirements from [Authorize] attributes on the same controller or action methods on the controller are ignored. Authentication middleware is not short-circuited but doesn't need to succeed.

Uteutensil answered 29/6, 2024 at 6:26 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.