[Authorize(AuthenticationSchemes = TheOnlyAuthScheme)] also runs default scheme AuthenticationHandler
- Dominant language
- C#
- Stars
- 38.4k
- Forks
- 10.9k
- Avg merge
- 2d 6h
- Merged PRs (30d)
- 290
Description
### Is there an existing issue for this?
- [X] I have searched the existing issues
### Describe the bug
The documentation https://learn.microsoft.com/en-us/aspnet/core/security/authorization/limitingidentitybyscheme?view=aspnetcore-7.0 says:
> The [[Authorize]](https://learn.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.authorization.authorizeattribute) attribute specifies the authentication scheme or schemes to use **regardless of whether a default is configured**.
```
[Authorize(AuthenticationSchemes=JwtBearerDefaults.AuthenticationScheme)]
public class Mixed2Controller : Controller
{
public ContentResult Index() => Content(MyWidgets.GetMyContent());
}
```
> In the preceding code, only the handler with the "Bearer" scheme runs. Any cookie-based identities are ignored.
Note: `JwtBearerDefaults.AuthenticationScheme` is the "Bearer" string constant here.
This is not true for me.
When a default authentication scheme is registered, its authentication handler will be executed upon success of the "only" authentication scheme which is requested by the annotation `[Authorize(AuthenticationSchemes=JwtBearerDefaults.AuthenticationScheme)]` on the REST API controller or REST API controller method.
Repro project:
https://github.com/janseris/ASPNetCoreMultipleAuthentications
How to repro:
1) run project
2) in Swagger UI, click green Authorize button which enables you to enter HTTP Authorization header content to be passed in to the controller

3) In the Session ID form, enter in value `SessionID 123` which passes the validation in the SessionID `AuthenticationHandler` and click green Authorize button to apply
- this will add HTTP Authorization header value `SessionID 123` to all the HTTP requests executed via the Swagger UI

4) execute a controller method via Swagger UI by clicking the method, then Try it Out and then blue Execute button

5) see debug output in Visual Studio - you will see that the Session ID authentication handler executed and finished and then HTTP Basic authentication handler executed (**unexpected**) _which you can also observe in the browser because the a prompt for HTTP Basic authentication credentials will show as a result of failed HTTP Basic authentication (because the authentication/authorization header did not contain a valid HTTP Basic authentication value because it was `SessionID 123`_)

### Expected Behavior
When `[Authorize(AuthenticationSchemes=JwtBearerDefaults.AuthenticationScheme)]` annotation is used, only that single AuthenticationHandler (registered under the authentication scheme name `JwtBearerDefaults.AuthenticationScheme` is executed).
That in my case would be the session ID authentication handler specified on the controller method:
```
public class ItemsController : ControllerBase
{
//only "SessionID" authentication schema handler should be executed.
[Authorize(AuthenticationSchemes = SessionIDAuthenticationHandler.AuthenticationSchemeName)]
[HttpGet("", Name = "GetAllItems")]
[ProducesResponseType(typeof(IEnumerable), StatusCodes.Status200OK)]
public Task> GetAll()
{
var items = new List
{
new Item
{
Name = "item1"
},
new Item
{
Name = "item2"
}
};
return Task.FromResult(items.AsEnumerable());
}
}
```
### Steps To Reproduce
Repro project:
https://github.com/janseris/ASPNetCoreMultipleAuthentications
Repro steps:
1) run project
2) in Swagger UI, click green Authorize button which enables you to enter HTTP Authorization header content to be passed in to the controller

3) In the Session ID form, enter in value `SessionID 123` which passes the validation in the SessionID `AuthenticationHandler` and click green Authorize button to apply
- this will add HTTP Authorization header value `SessionID 123` to all the HTTP requests executed via the Swagger UI

4) execute a controller method via Swagger UI by clicking the method, then Try it Out and then blue Execute button

5) see debug output in Visual Studio - you will see that the Session ID authentication handler executed and finished and the HTTP Basic authentication handler executed (**unexpected**) which you can also observe in the browser because the default browser dialog for HTTP Basic authentication will show

### Exceptions (if any)
_No response_
### .NET Version
.NET SDK 7.0.200 commit 534117727b
### Anything else?
_No response_
Contributor guide
Assessment
This issue has not been assessed yet.