Autorisieren eines bestimmten Schemas in ASP.NET Core

Eine Einführung in Authentifizierungsschemas in ASP.NET Core finden Sie im Authentifizierungsschema.

In einigen Szenarien, z. B. Single Page Applications (SPAs), ist es üblich, mehrere Authentifizierungsmethoden zu verwenden. Die App kann beispielsweise die -basierte Authentifizierung verwenden cookie, um sich anzumelden, und die JWT-Bearerauthentifizierung für JavaScript-Anforderungen. In einigen Fällen verfügt die App möglicherweise über mehrere Instanzen eines Authentifizierungshandlers. Beispielsweise werden zwei cookie Handler, in denen eine grundlegende Identität enthält, erstellt, und eine wird erstellt, wenn eine mehrstufige Authentifizierung (Multi-Factor Authentication, MFA) ausgelöst wurde. MFA kann ausgelöst werden, weil der Benutzer einen Vorgang angefordert hat, der zusätzliche Sicherheit erfordert. Weitere Informationen zum Erzwingen von MFA, wenn ein Benutzer eine Ressource anfordert, die MFA erfordert, finden Sie im Abschnitt "GitHub-Problemschutz " mit MFA.

Ein Authentifizierungsschema wird benannt, wenn der Authentifizierungsdienst während der Authentifizierung konfiguriert wird. Beispiel:

using Microsoft.AspNetCore.Authentication;

var builder = WebApplication.CreateBuilder(args);

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

builder.Services.AddAuthentication()
        .AddIdentityServerJwt();

builder.Services.AddControllersWithViews();
builder.Services.AddRazorPages();

var app = builder.Build();

if (app.Environment.IsDevelopment())
{
    app.UseMigrationsEndPoint();
}
else
{
    app.UseHsts();
}

app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();

app.UseAuthentication();
app.UseIdentityServer();
app.UseAuthorization();

app.MapDefaultControllerRoute();
app.MapRazorPages();

app.MapFallbackToFile("index.html");

app.Run();

Im vorherigen Code wurden zwei Authentifizierungshandler hinzugefügt: eine für cookies und eine für Bearer.

Hinweis

Wenn Sie das Standardschema angeben, wird die HttpContext.User Eigenschaft auf diese Identität festgelegt. Wenn dieses Verhalten nicht gewünscht ist, deaktivieren Sie es, indem Sie die parameterlose Form von AddAuthentication.

Auswählen des Schemas mit dem Attribut "Autorisieren"

An der Autorisierungsstelle gibt die App den zu verwendenden Handler an. Wählen Sie den Handler aus, mit dem die App autorisiert wird, indem Sie eine durch Kommas getrennte Liste der Authentifizierungsschemas an [Authorize]. Das [Authorize] Attribut gibt das Authentifizierungsschema oder schemas an, das verwendet werden soll, unabhängig davon, ob ein Standard konfiguriert ist. Beispiel:

using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Mvc;

namespace AuthScheme.Controllers;

[Authorize(AuthenticationSchemes = AuthSchemes)]
public class MixedController : Controller
{
    private const string AuthSchemes =
        CookieAuthenticationDefaults.AuthenticationScheme + "," +
        JwtBearerDefaults.AuthenticationScheme;
    public ContentResult Index() => Content(MyWidgets.GetMyContent());

}

Im vorherigen Beispiel werden sowohl die Handler als auch die cookie Bearerhandler ausgeführt und haben die Möglichkeit, eine Identität für den aktuellen Benutzer zu erstellen und anzufügen. Wenn Sie nur ein einzelnes Schema angeben, wird der entsprechende Handler ausgeführt:

[Authorize(AuthenticationSchemes=JwtBearerDefaults.AuthenticationScheme)]
public class Mixed2Controller : Controller
{
    public ContentResult Index() => Content(MyWidgets.GetMyContent());
}

Im vorherigen Code wird nur der Handler mit dem Schema "Bearer" ausgeführt. Alle cookie-basierten Identitäten werden ignoriert.

Auswählen des Schemas mit Richtlinien

Wenn Sie die gewünschten Schemas in der Richtlinie angeben möchten, können Sie die AuthenticationSchemes Auflistung beim Hinzufügen einer Richtlinie festlegen:

using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.JwtBearer;

var builder = WebApplication.CreateBuilder(args);

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

builder.Services.AddAuthentication()
                .AddIdentityServerJwt();

builder.Services.AddControllersWithViews();
builder.Services.AddRazorPages();

var app = builder.Build();

if (app.Environment.IsDevelopment())
{
    app.UseMigrationsEndPoint();
}
else
{
    app.UseHsts();
}

app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();

app.UseAuthentication();
app.UseIdentityServer();
app.UseAuthorization();

app.MapDefaultControllerRoute();
app.MapRazorPages();

app.MapFallbackToFile("index.html");

app.Run();

Im vorherigen Beispiel wird die Richtlinie "Over18" nur für die identität ausgeführt, die vom Handler "Bearer" erstellt wurde. Verwenden Sie die Richtlinie, indem Sie die Eigenschaft des [Authorize] Attributs Policy festlegen:

using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;

namespace AuthScheme.Controllers;
[Authorize(Policy = "Over18")]
public class RegistrationController : Controller
{
    // Do Registration

Verwenden mehrerer Authentifizierungsschemas

Einige Apps müssen möglicherweise mehrere Authentifizierungstypen unterstützen. Ihre App kann z. B. Benutzer aus Azure Active Directory und aus einer Benutzerdatenbank authentifizieren. Ein weiteres Beispiel ist eine App, die Benutzer von Active Directory-Verbunddienste (AD FS) und Azure Active Directory B2C authentifiziert. In diesem Fall sollte die App ein JWT-Bearertoken von mehreren Ausstellern akzeptieren.

Fügen Sie alle Authentifizierungsschemas hinzu, die Sie annehmen möchten. Der folgende Code fügt beispielsweise zwei JWT-Bearerauthentifizierungsschemas mit unterschiedlichen Ausstellern hinzu:

using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Authorization;

var builder = WebApplication.CreateBuilder(args);

// Authentication
builder.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-7f436/";
        });

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

builder.Services.AddAuthentication()
        .AddIdentityServerJwt();

builder.Services.AddControllersWithViews();
builder.Services.AddRazorPages();

var app = builder.Build();

if (app.Environment.IsDevelopment())
{
    app.UseMigrationsEndPoint();
}
else
{
    app.UseHsts();
}

app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();

app.UseAuthentication();
app.UseIdentityServer();
app.UseAuthorization();

app.MapDefaultControllerRoute();
app.MapRazorPages();

app.MapFallbackToFile("index.html");

app.Run();

Hinweis

Nur eine JWT-Bearerauthentifizierung wird mit dem Standardauthentifizierungsschema JwtBearerDefaults.AuthenticationSchemeregistriert. Zusätzliche Authentifizierung muss bei einem eindeutigen Authentifizierungsschema registriert werden.

Aktualisieren Sie die Standardautorisierungsrichtlinie, um beide Authentifizierungsschemas zu akzeptieren. Beispiel:

using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Authorization;

var builder = WebApplication.CreateBuilder(args);

// Authentication
builder.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-7f436/";
        });

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

builder.Services.AddAuthentication()
        .AddIdentityServerJwt();

builder.Services.AddControllersWithViews();
builder.Services.AddRazorPages();

var app = builder.Build();

if (app.Environment.IsDevelopment())
{
    app.UseMigrationsEndPoint();
}
else
{
    app.UseHsts();
}

app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();

app.UseAuthentication();
app.UseIdentityServer();
app.UseAuthorization();

app.MapDefaultControllerRoute();
app.MapRazorPages();

app.MapFallbackToFile("index.html");

app.Run();

Da die Standardautorisierungsrichtlinie außer Kraft gesetzt wird, ist es möglich, das [Authorize] Attribut in Controllern zu verwenden. Der Controller akzeptiert dann Anforderungen mit JWT, die vom ersten oder zweiten Aussteller ausgestellt wurden.

Dieses GitHub-Problem finden Sie unter Verwendung mehrerer Authentifizierungsschemas.

Im folgenden Beispiel wird Azure Active Directory B2C und ein anderer Azure Active Directory-Mandant verwendet:

using Microsoft.AspNetCore.Authentication;
using Microsoft.IdentityModel.Tokens;
using Microsoft.Net.Http.Headers;
using System.IdentityModel.Tokens.Jwt;

var builder = WebApplication.CreateBuilder(args);

// Authentication
builder.Services.AddAuthentication(options =>
{
    options.DefaultScheme = "B2C_OR_AAD";
    options.DefaultChallengeScheme = "B2C_OR_AAD";
})
.AddJwtBearer("B2C", jwtOptions =>
{
    jwtOptions.MetadataAddress = "B2C-MetadataAddress";
    jwtOptions.Authority = "B2C-Authority";
    jwtOptions.Audience = "B2C-Audience";
})
.AddJwtBearer("AAD", jwtOptions =>
{
    jwtOptions.MetadataAddress = "AAD-MetadataAddress";
    jwtOptions.Authority = "AAD-Authority";
    jwtOptions.Audience = "AAD-Audience";
    jwtOptions.TokenValidationParameters = new TokenValidationParameters
    {
        ValidateIssuer = true,
        ValidateAudience = true,
        ValidateIssuerSigningKey = true,
        ValidAudiences = builder.Configuration.GetSection("ValidAudiences").Get<string[]>(),
        ValidIssuers = builder.Configuration.GetSection("ValidIssuers").Get<string[]>()
    };
})
.AddPolicyScheme("B2C_OR_AAD", "B2C_OR_AAD", options =>
{
    options.ForwardDefaultSelector = context =>
    {
        string authorization = context.Request.Headers[HeaderNames.Authorization];
        if (!string.IsNullOrEmpty(authorization) && authorization.StartsWith("Bearer "))
        {
            var token = authorization.Substring("Bearer ".Length).Trim();
            var jwtHandler = new JwtSecurityTokenHandler();

            return (jwtHandler.CanReadToken(token) && jwtHandler.ReadJwtToken(token).Issuer.Equals("B2C-Authority"))
                ? "B2C" : "AAD";
        }
        return "AAD";
    };
});

builder.Services.AddAuthentication()
        .AddIdentityServerJwt();

builder.Services.AddControllersWithViews();
builder.Services.AddRazorPages();

var app = builder.Build();

if (app.Environment.IsDevelopment())
{
    app.UseMigrationsEndPoint();
}
else
{
    app.UseHsts();
}

app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();

app.UseAuthentication();
app.UseIdentityServer();
app.UseAuthorization();

app.MapDefaultControllerRoute().RequireAuthorization();
app.MapRazorPages().RequireAuthorization();

app.MapFallbackToFile("index.html");

app.Run();

Im vorherigen Code wird verwendet, um ein Standardschema für die aktuelle Anforderung auszuwählen, ForwardDefaultSelector an die Authentifizierungshandler alle Authentifizierungsvorgänge standardmäßig weiterleiten sollten. Die Standardweiterleitungslogik überprüft zuerst die spezifischste ForwardAuthenticate, ForwardChallengeForwardForbid, , ForwardSignIn, und ForwardSignOut Einstellung, gefolgt von der Überprüfung der ForwardDefaultSelector, gefolgt von ForwardDefault. Das erste Nicht-Null-Ergebnis wird als Zielschema verwendet, an das weitergeleitet werden soll. Weitere Informationen finden Sie unter Richtlinienschemas in ASP.NET Core.

Eine Einführung in Authentifizierungsschemas in ASP.NET Core finden Sie im Authentifizierungsschema.

In einigen Szenarien, z. B. Single Page Applications (SPAs), ist es üblich, mehrere Authentifizierungsmethoden zu verwenden. Die App kann beispielsweise die -basierte Authentifizierung verwenden cookie, um sich anzumelden, und die JWT-Bearerauthentifizierung für JavaScript-Anforderungen. In einigen Fällen verfügt die App möglicherweise über mehrere Instanzen eines Authentifizierungshandlers. Beispielsweise werden zwei cookie Handler, in denen eine grundlegende Identität enthält, erstellt, und eine wird erstellt, wenn eine mehrstufige Authentifizierung (Multi-Factor Authentication, MFA) ausgelöst wurde. MFA kann ausgelöst werden, weil der Benutzer einen Vorgang angefordert hat, der zusätzliche Sicherheit erfordert. Weitere Informationen zum Erzwingen von MFA, wenn ein Benutzer eine Ressource anfordert, die MFA erfordert, finden Sie im Abschnitt "GitHub-Problemschutz " mit MFA.

Ein Authentifizierungsschema wird benannt, wenn der Authentifizierungsdienst während der Authentifizierung konfiguriert wird. Beispiel:

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/";
        });

Im vorherigen Code wurden zwei Authentifizierungshandler hinzugefügt: eine für cookies und eine für Bearer.

Hinweis

Wenn Sie das Standardschema angeben, wird die HttpContext.User Eigenschaft auf diese Identität festgelegt. Wenn dieses Verhalten nicht gewünscht ist, deaktivieren Sie es, indem Sie die parameterlose Form von AddAuthentication.

Auswählen des Schemas mit dem Attribut "Autorisieren"

An der Autorisierungsstelle gibt die App den zu verwendenden Handler an. Wählen Sie den Handler aus, mit dem die App autorisiert wird, indem Sie eine durch Kommas getrennte Liste der Authentifizierungsschemas an [Authorize]. Das [Authorize] Attribut gibt das Authentifizierungsschema oder schemas an, das verwendet werden soll, unabhängig davon, ob ein Standard konfiguriert ist. Beispiel:

[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;

Im vorherigen Beispiel werden sowohl die Handler als auch die cookie Bearerhandler ausgeführt und haben die Möglichkeit, eine Identität für den aktuellen Benutzer zu erstellen und anzufügen. Wenn Sie nur ein einzelnes Schema angeben, wird der entsprechende Handler ausgeführt.

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

Im vorherigen Code wird nur der Handler mit dem Schema "Bearer" ausgeführt. Alle cookie-basierten Identitäten werden ignoriert.

Auswählen des Schemas mit Richtlinien

Wenn Sie die gewünschten Schemas in der Richtlinie angeben möchten, können Sie die AuthenticationSchemes Auflistung festlegen, wenn Sie Ihre Richtlinie hinzufügen:

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

Im vorherigen Beispiel wird die Richtlinie "Over18" nur für die identität ausgeführt, die vom Handler "Bearer" erstellt wurde. Verwenden Sie die Richtlinie, indem Sie die Eigenschaft des [Authorize] Attributs Policy festlegen:

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

Verwenden mehrerer Authentifizierungsschemas

Einige Apps müssen möglicherweise mehrere Authentifizierungstypen unterstützen. Ihre App kann z. B. Benutzer aus Azure Active Directory und aus einer Benutzerdatenbank authentifizieren. Ein weiteres Beispiel ist eine App, die Benutzer von Active Directory-Verbunddienste (AD FS) und Azure Active Directory B2C authentifiziert. In diesem Fall sollte die App ein JWT-Bearertoken von mehreren Ausstellern akzeptieren.

Fügen Sie alle Authentifizierungsschemas hinzu, die Sie annehmen möchten. Im folgenden Code Startup.ConfigureServices werden beispielsweise zwei JWT-Bearerauthentifizierungsschemas mit unterschiedlichen Ausstellern hinzugefügt:

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/";
        });
}

Hinweis

Nur eine JWT-Bearerauthentifizierung wird mit dem Standardauthentifizierungsschema JwtBearerDefaults.AuthenticationSchemeregistriert. Zusätzliche Authentifizierung muss bei einem eindeutigen Authentifizierungsschema registriert werden.

Der nächste Schritt besteht darin, die Standardautorisierungsrichtlinie so zu aktualisieren, dass beide Authentifizierungsschemas akzeptiert werden. Beispiel:

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();
    });
}

Da die Standardautorisierungsrichtlinie außer Kraft gesetzt wird, ist es möglich, das [Authorize] Attribut in Controllern zu verwenden. Der Controller akzeptiert dann Anforderungen mit JWT, die vom ersten oder zweiten Aussteller ausgestellt wurden.

Dieses GitHub-Problem finden Sie unter Verwendung mehrerer Authentifizierungsschemas.