Autorizace s využitím konkrétního schématu v ASP.NET Core
Úvod do schémat ověřování v ASP.NET Core najdete v tématu Schéma ověřování.
V některých scénářích, jako jsou jednostráňové aplikace (SPA), je běžné používat více metod ověřování. Aplikace může například použít cookieověřování na základě přihlašovacích údajů a ověřování nosných certifikátů JWT pro požadavky JavaScriptu. V některých případech může mít aplikace více instancí obslužné rutiny ověřování. Například dva cookie obslužné rutiny, kde jeden obsahuje základní identity a jeden se vytvoří, když se aktivuje vícefaktorové ověřování (MFA). Vícefaktorové ověřování se může aktivovat, protože uživatel požádal o operaci, která vyžaduje dodatečné zabezpečení. Další informace o vynucování vícefaktorového ověřování, když uživatel požádá o prostředek, který vyžaduje vícefaktorové ověřování, najdete v části Ochrana problému GitHubu s vícefaktorovým ověřováním.
Schéma ověřování je pojmenováno při konfiguraci ověřovací služby během ověřování. Příklad:
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();
V předchozím kódu byly přidány dva obslužné rutiny ověřování: jeden pro soubory cookie a jeden pro nosný.
Poznámka:
Zadání výchozího schématu HttpContext.User
způsobí, že vlastnost je nastavena na hodnotu identity. Pokud toto chování není žádoucí, zakažte ho vyvoláním bezparametrové AddAuthentication
formy .
Výběr schématu pomocí atributu Authorize
V okamžiku autorizace aplikace označuje obslužnou rutinu, která se má použít. Vyberte obslužnou rutinu, se kterou aplikace autorizuje předáním seznamu schémat ověřování oddělených čárkami .[Authorize]
Atribut [Authorize]
určuje schéma ověřování nebo schémata, která se mají použít bez ohledu na to, jestli je nakonfigurované výchozí nastavení. Příklad:
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());
}
V předchozím příkladu se cookie obslužné rutiny i obslužné rutiny nosné rutiny spouštějí a mají šanci vytvořit aktuálního uživatele a připojit ho identity . Zadáním pouze jednoho schématu se spustí odpovídající obslužná rutina:
[Authorize(AuthenticationSchemes=JwtBearerDefaults.AuthenticationScheme)]
public class Mixed2Controller : Controller
{
public ContentResult Index() => Content(MyWidgets.GetMyContent());
}
V předchozím kódu se spustí pouze obslužná rutina se schématem Bearer. Všechny cookieidentity založené na identitách se ignorují.
Výběr schématu pomocí zásad
Pokud dáváte přednost určení požadovaných schémat v zásadách, můžete kolekci nastavit AuthenticationSchemes při přidávání zásad:
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();
V předchozím příkladu se zásada "Over18" spouští pouze proti identity obslužné rutině "Bearer". Zásadu použijte nastavením vlastnosti atributu [Authorize]
Policy
:
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
namespace AuthScheme.Controllers;
[Authorize(Policy = "Over18")]
public class RegistrationController : Controller
{
// Do Registration
Použití více schémat ověřování
Některé aplikace můžou potřebovat podporu více typů ověřování. Vaše aplikace může například ověřovat uživatele z Azure Active Directory a z databáze uživatelů. Dalším příkladem je aplikace, která ověřuje uživatele z Active Directory Federation Services (AD FS) i Azure Active Directory B2C. V tomto případě by aplikace měla přijmout nosný token JWT od několika vystavitelů.
Přidejte všechna schémata ověřování, která chcete přijmout. Následující kód například přidá dvě schémata ověřování nosných objektů JWT s různými vystavitely:
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();
Poznámka:
Ve výchozím schématu JwtBearerDefaults.AuthenticationScheme
ověřování je registrováno pouze jedno ověřování nosným uživatelem JWT . Další ověřování musí být registrováno pomocí jedinečného schématu ověřování.
Aktualizujte výchozí zásady autorizace tak, aby přijímaly obě schémata ověřování. Příklad:
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();
Vzhledem k tomu, že se přepíše výchozí zásady autorizace, je možné použít [Authorize]
atribut v kontroleru. Kontroler pak přijme požadavky s JWT vydaným prvním nebo druhým vystavitelem.
Podívejte se na tento problém s GitHubem při používání více schémat ověřování.
Následující příklad používá Azure Active Directory B2C a dalšího tenanta Azure Active Directory :
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();
V předchozím kódu se používá k výběru výchozího schématu pro aktuální požadavek, ForwardDefaultSelector aby obslužné rutiny ověřování měly ve výchozím nastavení předávat všechny ověřovací operace. Výchozí logika předávání nejprve zkontroluje nejvýraznější ForwardAuthenticate, ForwardForbidForwardChallenge, , ForwardSignIna ForwardSignOut nastavení, následované kontrolou ForwardDefaultSelector, následované ForwardDefault. První výsledek, který není null, se používá jako cílové schéma pro předávání. Další informace najdete v tématu Schémata zásad v ASP.NET Core.
Úvod do schémat ověřování v ASP.NET Core najdete v tématu Schéma ověřování.
V některých scénářích, jako jsou jednostráňové aplikace (SPA), je běžné používat více metod ověřování. Aplikace může například použít cookieověřování na základě přihlašovacích údajů a ověřování nosných certifikátů JWT pro požadavky JavaScriptu. V některých případech může mít aplikace více instancí obslužné rutiny ověřování. Například dva cookie obslužné rutiny, kde jeden obsahuje základní identity a jeden se vytvoří, když se aktivuje vícefaktorové ověřování (MFA). Vícefaktorové ověřování se může aktivovat, protože uživatel požádal o operaci, která vyžaduje dodatečné zabezpečení. Další informace o vynucování vícefaktorového ověřování, když uživatel požádá o prostředek, který vyžaduje vícefaktorové ověřování, najdete v části Ochrana problému GitHubu s vícefaktorovým ověřováním.
Schéma ověřování je pojmenováno při konfiguraci ověřovací služby během ověřování. Příklad:
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/";
});
V předchozím kódu byly přidány dva obslužné rutiny ověřování: jeden pro soubory cookie a jeden pro nosný.
Poznámka:
Zadání výchozího schématu HttpContext.User
způsobí, že vlastnost je nastavena na hodnotu identity. Pokud toto chování není žádoucí, zakažte ho vyvoláním bezparametrové AddAuthentication
formy .
Výběr schématu pomocí atributu Authorize
V okamžiku autorizace aplikace označuje obslužnou rutinu, která se má použít. Vyberte obslužnou rutinu, se kterou aplikace autorizuje předáním seznamu schémat ověřování oddělených čárkami .[Authorize]
Atribut [Authorize]
určuje schéma ověřování nebo schémata, která se mají použít bez ohledu na to, jestli je nakonfigurované výchozí nastavení. Příklad:
[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;
V předchozím příkladu se cookie obslužné rutiny i obslužné rutiny nosné rutiny spouštějí a mají šanci vytvořit aktuálního uživatele a připojit ho identity . Zadáním pouze jednoho schématu se spustí odpovídající obslužná rutina.
[Authorize(AuthenticationSchemes =
JwtBearerDefaults.AuthenticationScheme)]
public class MixedController : Controller
V předchozím kódu se spustí pouze obslužná rutina se schématem Bearer. Všechny cookieidentity založené na identitách se ignorují.
Výběr schématu pomocí zásad
Pokud dáváte přednost určení požadovaných schémat v zásadách, můžete kolekci nastavit AuthenticationSchemes
při přidávání zásad:
services.AddAuthorization(options =>
{
options.AddPolicy("Over18", policy =>
{
policy.AuthenticationSchemes.Add(JwtBearerDefaults.AuthenticationScheme);
policy.RequireAuthenticatedUser();
policy.Requirements.Add(new MinimumAgeRequirement());
});
});
V předchozím příkladu se zásada "Over18" spouští pouze proti identity obslužné rutině "Bearer". Zásadu použijte nastavením vlastnosti atributu [Authorize]
Policy
:
[Authorize(Policy = "Over18")]
public class RegistrationController : Controller
Použití více schémat ověřování
Některé aplikace můžou potřebovat podporu více typů ověřování. Vaše aplikace může například ověřovat uživatele z Azure Active Directory a z databáze uživatelů. Dalším příkladem je aplikace, která ověřuje uživatele z Active Directory Federation Services (AD FS) i Azure Active Directory B2C. V tomto případě by aplikace měla přijmout nosný token JWT od několika vystavitelů.
Přidejte všechna schémata ověřování, která chcete přijmout. Následující kód například Startup.ConfigureServices
přidá dvě schémata ověřování nosných objektů JWT s různými vystavitely:
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/";
});
}
Poznámka:
Ve výchozím schématu JwtBearerDefaults.AuthenticationScheme
ověřování je registrováno pouze jedno ověřování nosným uživatelem JWT . Další ověřování musí být registrováno pomocí jedinečného schématu ověřování.
Dalším krokem je aktualizace výchozích zásad autorizace tak, aby přijímala obě schémata ověřování. Příklad:
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();
});
}
Vzhledem k tomu, že se přepíše výchozí zásady autorizace, je možné použít [Authorize]
atribut v kontroleru. Kontroler pak přijme požadavky s JWT vydaným prvním nebo druhým vystavitelem.
Podívejte se na tento problém s GitHubem při používání více schémat ověřování.