AuthorizeAttribute: How to try with all available Authentication Schemas?

1.4k views Asked by At

I have a ASP.NET Core 3.1 Web Application which have ASP.NET Identity authentication and Role based authorization for interactive users (Pages)

Now I implemented some API Controller too within the same ASP.NET Core 3.1 application

[ApiController]
public class ConnectController : ControllerBase {...

I realized, that bearer token endpoint is not out of the box, so I successfully implemented it using OpenIddict, and it is working perfectly.

I would like to use Authorize attribute with Roles.

This is working:

[HttpGet]
[Authorize(Roles = "test01",
    AuthenticationSchemes = OpenIddictValidationAspNetCoreDefaults.AuthenticationScheme)]
//[Authorize(Roles = "test01")] // This is not working, why?
public ActionResult<string> Ping01(string message)
{ ...

The pure [Authorize(Roles = "test01")] is not working, and I do not understand why? For diagnostic purpose I examined all available Authentication Schemas, there are six, and the explicitly named "OpenIdDict.Validation.AspNetCore" is in the six (the last one, see debugger screenshot below). With other words I would like remain free change API Authentication methods and implementation in the future without touching the Controllers.

Question

How can I achieve that not specifying explicitly the Authentication Schemas in the AuthorizeAttribute constructor the authorization will try to Authorize with all available Authentication schemas?

Why I would like to do that?

...because I would not like to be specific to any Authentication Schema in my controllers. I would like to have a simple Role based authorization, and would not like the controller authorization code depend on anything else than the Role names.

enter image description here

1

There are 1 answers

0
Gheorghe Volosenco On

How can I achieve that not specifying explicitly the Authentication Schemas in the AuthorizeAttribute constructor the authorization will try to Authorize with all available Authentication schemas?

If you don't want to specify the schemas explicitly, you have to create a Default Policy in the ConfigureServices method, like this:

services.AddAuthorization(options =>
                {
                    options.DefaultPolicy = new AuthorizationPolicyBuilder()
                        .RequireAuthenticatedUser()
                        .AddAuthenticationSchemes(OpenIddictValidationAspNetCoreDefaults.AuthenticationScheme)
                        .Build();
                });

So now when you use [Authorize] the default policy will be included automatically.

By using this attribute now, you will have the user authorized by the role:

[Authorize, Authorize(Roles="admin")]

You may ask, why should Authorize attribute be used twice?
The answer to this can be found here: https://github.com/dotnet/aspnetcore/issues/18954