问题
Back in ASP.NET Core 1, authentication would be hooked manually into the request pipeline on its configuration: For a custom authentication process, you would simply define a AuthenticationMiddleware
and hook it into your pipeline at the point where the authentication was supposed to happen.
In ASP.NET Core 2, there's no more AuthenticationMiddleware
and you're supposed to do a UseAuthentication()
at some point in the pipeline where all authentication necessarily happens.
The difference is documented here: https://docs.microsoft.com/en-us/aspnet/core/security/authorization/limitingidentitybyscheme
To distinguish different ways of authentication, there are policies identified by magic strings (lots of magic strings in ASP.NET Core).
I'm then told that I can select the desired scheme with attributes on my controller, but I don't use MVC at all in the scenario in question. So how do I specify for a specific branch of the pipeline:
app.UseWhen(c => ..., app2 =>
{
// auth number 1 desired
...
});
app.UseWhen(c => ..., app2 =>
{
// auth number 2 desired
...
});
And even in MVC, authentication happens before routing, so how can the information which scheme to use possibly be available at the UseAuthentication()
point in the pipeline?
回答1:
You can target a specific authentication-scheme using an imperative approach, by calling AuthenticateAsync. Here's an example:
app2.Use(async (ctx, next) =>
{
var authenticateResult = await ctx.AuthenticateAsync("SchemeName");
if (!authenticateResult.Succeeded)
{
ctx.Response.StatusCode = 401; // e.g.
return;
}
// ...
});
AuthenticateAsync
takes the authentication-scheme as an argument and returns an instance of AuthenticateResult, which indicates success or failure via Succeeded
and provides the authenticated ClaimsPrincipal
via Principal.
You can also perform authorisation against a specific policy using IAuthorizationService. Here's an example of how the Principal
from AuthenticateResult
can be passed through AuthorizeAsync
:
var authorizationService = ctx.RequestServices.GetService<IAuthorizationService>();
var authorizationResult = await authorizationService.AuthorizeAsync(
authenticateResult.Principal, "PolicyName");
if (!authorizationResult.Succeeded)
{
ctx.Response.StatusCode = 403; // e.g.
return;
}
// ...
As with AuthenticateResult
, AuthorizationResult indicates success or failure via Succeeded
- it also provides information about why authorisation failed via Failure.
来源:https://stackoverflow.com/questions/55597848/multiple-authentication-schemes-in-asp-net-core