Autoryzuj z określonym schematem w ASP.NET CoreAuthorize with a specific scheme in ASP.NET Core

W niektórych scenariuszach, takich jak aplikacje jednostronicowe (aplikacji jednostronicowych), często używane są wiele metod uwierzytelniania.In some scenarios, such as Single Page Applications (SPAs), it's common to use multiple authentication methods. Na przykład aplikacja może używać cookie uwierzytelniania opartego na usłudze do logowania i uwierzytelniania JWT dla żądań języka JavaScript.For example, the app may use cookie-based authentication to log in and JWT bearer authentication for JavaScript requests. W niektórych przypadkach aplikacja może mieć wiele wystąpień programu obsługi uwierzytelniania.In some cases, the app may have multiple instances of an authentication handler. Na przykład dwa cookie programy obsługi, w których jeden zawiera podstawową tożsamość, a jedna jest tworzona podczas wyzwalania uwierzytelniania wieloskładnikowego (MFA).For example, two cookie handlers where one contains a basic identity and one is created when a multi-factor authentication (MFA) has been triggered. Uwierzytelnianie wieloskładnikowe może być wyzwalane, ponieważ użytkownik zażądał operacji wymagającej dodatkowych zabezpieczeń.MFA may be triggered because the user requested an operation that requires extra security. Aby uzyskać więcej informacji na temat wymuszania usługi MFA, gdy użytkownik zażąda zasobu wymagającego uwierzytelniania wieloskładnikowego, zobacz sekcję dotyczącą ochrony za pomocąusługi GitHub i usługi MFAFor more information on enforcing MFA when a user requests a resource that requires MFA, see the GitHub issue Protect section with MFA.

Schemat uwierzytelniania ma nazwę, gdy usługa uwierzytelniania jest konfigurowana podczas uwierzytelniania.An authentication scheme is named when the authentication service is configured during authentication. Na przykład:For example:

public void ConfigureServices(IServiceCollection services)
{
    // Code omitted for brevity

    services.AddAuthentication()
        .AddCookie(options => {
            options.LoginPath = "/Account/Unauthorized/";
            options.AccessDeniedPath = "/Account/Forbidden/";
        })
        .AddJwtBearer(options => {
            options.Audience = "http://localhost:5001/";
            options.Authority = "http://localhost:5000/";
        });

W poprzednim kodzie dodano dwa programy obsługi uwierzytelniania: jeden dla cookie s i jeden dla okaziciela.In the preceding code, two authentication handlers have been added: one for cookies and one for bearer.

Uwaga

Określenie schematu domyślnego powoduje, że HttpContext.User Właściwość jest ustawiana na tę tożsamość.Specifying the default scheme results in the HttpContext.User property being set to that identity. Jeśli takie zachowanie nie jest wymagane, należy je wyłączyć, wywołując formularz bez parametrów AddAuthentication .If that behavior isn't desired, disable it by invoking the parameterless form of AddAuthentication.

Wybieranie schematu z atrybutem AutoryzujSelecting the scheme with the Authorize attribute

W punkcie autoryzacji Aplikacja wskazuje program obsługi, który ma być używany.At the point of authorization, the app indicates the handler to be used. Wybierz program obsługi, za pomocą którego aplikacja będzie autoryzować, przekazując rozdzieloną przecinkami listę schematów uwierzytelniania do [Authorize] .Select the handler with which the app will authorize by passing a comma-delimited list of authentication schemes to [Authorize]. Ten [Authorize] atrybut określa schemat lub schematy uwierzytelniania, które mają być używane niezależnie od tego, czy skonfigurowano wartość domyślną.The [Authorize] attribute specifies the authentication scheme or schemes to use regardless of whether a default is configured. Na przykład:For example:

[Authorize(AuthenticationSchemes = AuthSchemes)]
public class MixedController : Controller
    // Requires the following imports:
    // using Microsoft.AspNetCore.Authentication.Cookies;
    // using Microsoft.AspNetCore.Authentication.JwtBearer;
    private const string AuthSchemes =
        CookieAuthenticationDefaults.AuthenticationScheme + "," +
        JwtBearerDefaults.AuthenticationScheme;

W poprzednim przykładzie zarówno program, cookie jak i programy obsługi oraz mogą tworzyć i dołączać tożsamość bieżącego użytkownika.In the preceding example, both the cookie and bearer handlers run and have a chance to create and append an identity for the current user. Określając tylko jeden schemat, zostanie uruchomiony odpowiedni program obsługi.By specifying a single scheme only, the corresponding handler runs.

[Authorize(AuthenticationSchemes = 
    JwtBearerDefaults.AuthenticationScheme)]
public class MixedController : Controller

W poprzednim kodzie jest tylko procedura obsługi ze schematem "Bearer".In the preceding code, only the handler with the "Bearer" scheme runs. Wszystkie cookie tożsamości oparte na usłudze są ignorowane.Any cookie-based identities are ignored.

Wybieranie schematu z zasadamiSelecting the scheme with policies

Jeśli wolisz określić żądane schematy w zasadach, możesz ustawić AuthenticationSchemes kolekcję podczas dodawania zasad:If you prefer to specify the desired schemes in policy, you can set the AuthenticationSchemes collection when adding your policy:

services.AddAuthorization(options =>
{
    options.AddPolicy("Over18", policy =>
    {
        policy.AuthenticationSchemes.Add(JwtBearerDefaults.AuthenticationScheme);
        policy.RequireAuthenticatedUser();
        policy.Requirements.Add(new MinimumAgeRequirement());
    });
});

W poprzednim przykładzie zasada "Over18" działa tylko w odniesieniu do tożsamości utworzonej przez procedurę obsługi "Bearer".In the preceding example, the "Over18" policy only runs against the identity created by the "Bearer" handler. Użyj zasad, ustawiając [Authorize] Policy właściwość atrybutu:Use the policy by setting the [Authorize] attribute's Policy property:

[Authorize(Policy = "Over18")]
public class RegistrationController : Controller

Używanie wielu schematów uwierzytelnianiaUse multiple authentication schemes

Niektóre aplikacje mogą wymagać obsługi wielu typów uwierzytelniania.Some apps may need to support multiple types of authentication. Na przykład aplikacja może uwierzytelniać użytkowników z Azure Active Directory i z bazy danych użytkowników.For example, your app might authenticate users from Azure Active Directory and from a users database. Innym przykładem jest aplikacja, która uwierzytelnia użytkowników zarówno z Active Directory Federation Services, jak i Azure Active Directory B2C.Another example is an app that authenticates users from both Active Directory Federation Services and Azure Active Directory B2C. W takim przypadku aplikacja powinna akceptować token okaziciela JWT z kilku wystawców.In this case, the app should accept a JWT bearer token from several issuers.

Dodaj wszystkie schematy uwierzytelniania, które chcesz zaakceptować.Add all authentication schemes you'd like to accept. Na przykład poniższy kod w programie Startup.ConfigureServices dodaje dwa systemy uwierzytelniania okaziciela JWT z różnymi wystawcami:For example, the following code in Startup.ConfigureServices adds two JWT bearer authentication schemes with different issuers:

public void ConfigureServices(IServiceCollection services)
{
    // Code omitted for brevity

    services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
        .AddJwtBearer(options =>
        {
            options.Audience = "https://localhost:5000/";
            options.Authority = "https://localhost:5000/identity/";
        })
        .AddJwtBearer("AzureAD", options =>
        {
            options.Audience = "https://localhost:5000/";
            options.Authority = "https://login.microsoftonline.com/eb971100-6f99-4bdc-8611-1bc8edd7f436/";
        });
}

Uwaga

Zarejestrowano tylko jedno uwierzytelnianie okaziciela JWT z domyślnym schematem uwierzytelniania JwtBearerDefaults.AuthenticationScheme .Only one JWT bearer authentication is registered with the default authentication scheme JwtBearerDefaults.AuthenticationScheme. Dodatkowe uwierzytelnianie musi być zarejestrowane przy użyciu unikatowego schematu uwierzytelniania.Additional authentication has to be registered with a unique authentication scheme.

Następnym krokiem jest zaktualizowanie domyślnych zasad autoryzacji w celu zaakceptowania obu schematów uwierzytelniania.The next step is to update the default authorization policy to accept both authentication schemes. Na przykład:For example:

public void ConfigureServices(IServiceCollection services)
{
    // Code omitted for brevity

    services.AddAuthorization(options =>
    {
        var defaultAuthorizationPolicyBuilder = new AuthorizationPolicyBuilder(
            JwtBearerDefaults.AuthenticationScheme,
            "AzureAD");
        defaultAuthorizationPolicyBuilder = 
            defaultAuthorizationPolicyBuilder.RequireAuthenticatedUser();
        options.DefaultPolicy = defaultAuthorizationPolicyBuilder.Build();
    });
}

Ponieważ domyślne zasady autoryzacji są zastępowane, można użyć [Authorize] atrybutu w kontrolerach.As the default authorization policy is overridden, it's possible to use the [Authorize] attribute in controllers. Kontroler akceptuje żądania z tokenem JWT wystawionym przez pierwszego lub drugiego wystawcy.The controller then accepts requests with JWT issued by the first or second issuer.

Ten problem z usługą GitHub można znaleźć w artykule dotyczącym wielu schematów uwierzytelniania.See this GitHub issue on using multiple authentication schemes.