Сопоставление, настройка и преобразование утверждений в ASP.NET Core
Утверждения можно создавать из любых данных пользователя или данных удостоверения личности, которые могут быть созданы с помощью доверенного поставщика удостоверений или удостоверений ASP.NET Core. Утверждение — это пара "имя-значение", которая представляет собой предмет, а не то, что он может делать. В этой статье рассматриваются следующие области:
- Настройка и сопоставление утверждений с помощью клиента OpenID Connect
- Задание утверждения имени и роли
- Сброс пространств имен утверждений
- Настройка, расширение утверждений с помощью TransformAsync
Сопоставление утверждений с помощью проверки подлинности OpenID Connect
Утверждения профиля можно вернуть в id_token
объекте , который возвращается после успешной проверки подлинности. Клиентское приложение ASP.NET Core требует только области профиля. При использовании утверждений не требуется дополнительное id_token
сопоставление утверждений.
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Authentication.OpenIdConnect;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.AddAuthentication(options =>
{
options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
})
.AddCookie()
.AddOpenIdConnect(options =>
{
options.SignInScheme = "Cookies";
options.Authority = "-your-identity-provider-";
options.RequireHttpsMetadata = true;
options.ClientId = "-your-clientid-";
options.ClientSecret = "-your-client-secret-from-user-secrets-or-keyvault";
options.ResponseType = "code";
options.UsePkce = true;
options.Scope.Add("profile");
options.SaveTokens = true;
});
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseAuthentication();
app.UseAuthorization();
app.MapRazorPages();
app.Run();
Для предыдущего кода требуется пакет NuGet Microsoft.AspNetCore.Authentication.OpenIdConnect .
Другим способом получения утверждений пользователя является использование API сведений о пользователе OpenID Connect. Клиентское приложение ASP.NET Core использует GetClaimsFromUserInfoEndpoint
свойство для настройки этого свойства. Одним из важных отличий от первых параметров является то, что необходимо указать утверждения, которые требуется использовать MapUniqueJsonKey
метод, в противном случае в клиентском приложении будут доступны только name
given_name
email
стандартные утверждения. Утверждения, включенные в список id_token
, сопоставляются по умолчанию. Это основное отличие от первого варианта. Необходимо явно определить некоторые необходимые утверждения.
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Authentication.OpenIdConnect;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.AddAuthentication(options =>
{
options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
})
.AddCookie()
.AddOpenIdConnect(options =>
{
options.SignInScheme = "Cookies";
options.Authority = "-your-identity-provider-";
options.RequireHttpsMetadata = true;
options.ClientId = "-your-clientid-";
options.ClientSecret = "-client-secret-from-user-secrets-or-keyvault";
options.ResponseType = "code";
options.UsePkce = true;
options.Scope.Add("profile");
options.SaveTokens = true;
options.GetClaimsFromUserInfoEndpoint = true;
options.ClaimActions.MapUniqueJsonKey("preferred_username",
"preferred_username");
options.ClaimActions.MapUniqueJsonKey("gender", "gender");
});
var app = builder.Build();
// Code removed for brevity.
Примечание.
По умолчанию обработчик Open ID Connect использует запросы авторизации по протоколу PAR, если документ обнаружения поставщика удостоверений заявляет о поддержке PAR. Документ обнаружения поставщика удостоверений обычно находится в .well-known/openid-configuration
. Если невозможно использовать PAR в конфигурации клиента у поставщика удостоверений, можно отключить PAR, используя параметр PushedAuthorizationBehavior.
builder.Services
.AddAuthentication(options =>
{
options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
})
.AddCookie()
.AddOpenIdConnect("oidc", oidcOptions =>
{
// Other provider-specific configuration goes here.
// The default value is PushedAuthorizationBehavior.UseIfAvailable.
// 'OpenIdConnectOptions' does not contain a definition for 'PushedAuthorizationBehavior'
// and no accessible extension method 'PushedAuthorizationBehavior' accepting a first argument
// of type 'OpenIdConnectOptions' could be found
oidcOptions.PushedAuthorizationBehavior = PushedAuthorizationBehavior.Disable;
});
Чтобы убедиться, что проверка подлинности выполняется только при использовании PAR, используйте pushedAuthorizationBehavior.Require . Это изменение также представляет новое событие OnPushAuthorization для OpenIdConnectEvents , которое можно использовать для настройки запроса принудительной авторизации или обработки его вручную. Дополнительные сведения см. в предложении API.
Сопоставление утверждений имен и ролей
Утверждение Name и утверждение роли сопоставляются со свойствами по умолчанию в контексте HTTP ASP.NET Core. Иногда требуется использовать различные утверждения для свойств по умолчанию или утверждение имени, а утверждение роли не совпадает со значениями по умолчанию. Утверждения можно сопоставить с помощью свойства TokenValidationParameters и задать любое утверждение по мере необходимости. Значения из утверждений можно использовать непосредственно в httpContext User.Identity. Свойство name и роли.
User.Identity.Name
Если отсутствуют значения или роли отсутствуют, проверьте значения в возвращенных утверждениях и задайте NameClaimType
значения и RoleClaimType
значения. Возвращенные утверждения из проверки подлинности клиента можно просмотреть в контексте HTTP.
builder.Services.AddAuthentication(options =>
{
options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
})
.AddCookie()
.AddOpenIdConnect(options =>
{
// Other options...
options.TokenValidationParameters = new TokenValidationParameters
{
NameClaimType = "email"
//, RoleClaimType = "role"
};
});
Пространства имен утверждений, пространства имен по умолчанию
ASP.NET Core добавляет пространства имен по умолчанию в некоторые известные утверждения, которые могут не потребоваться в приложении. При необходимости отключите эти добавленные пространства имен и используйте точные утверждения, созданные сервером OpenID Connect.
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
JsonWebTokenHandler.DefaultInboundClaimTypeMap.Clear();
builder.Services.AddAuthentication(options =>
{
options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
})
.AddCookie()
.AddOpenIdConnect(options =>
{
options.SignInScheme = "Cookies";
options.Authority = "-your-identity-provider-";
options.RequireHttpsMetadata = true;
options.ClientId = "-your-clientid-";
options.ClientSecret = "-your-client-secret-from-user-secrets-or-keyvault";
options.ResponseType = "code";
options.UsePkce = true;
options.Scope.Add("profile");
options.SaveTokens = true;
});
var app = builder.Build();
// Code removed for brevity.
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();
builder.Services.AddAuthentication(options =>
{
options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
})
.AddCookie()
.AddOpenIdConnect(options =>
{
options.SignInScheme = "Cookies";
options.Authority = "-your-identity-provider-";
options.RequireHttpsMetadata = true;
options.ClientId = "-your-clientid-";
options.ClientSecret = "-your-client-secret-from-user-secrets-or-keyvault";
options.ResponseType = "code";
options.UsePkce = true;
options.Scope.Add("profile");
options.SaveTokens = true;
});
var app = builder.Build();
// Code removed for brevity.
Если необходимо отключить пространства имен для каждой схемы, а не глобально, можно использовать параметр MapInboundClaims = false .
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.AddAuthentication(options =>
{
options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
})
.AddCookie()
.AddOpenIdConnect(options =>
{
options.SignInScheme = "Cookies";
options.Authority = "-your-identity-provider-";
options.RequireHttpsMetadata = true;
options.ClientId = "-your-clientid-";
options.ClientSecret = "-your-client-secret-from-user-secrets-or-keyvault";
options.ResponseType = "code";
options.UsePkce = true;
options.MapInboundClaims = false;
options.Scope.Add("profile");
options.SaveTokens = true;
});
var app = builder.Build();
// Code removed for brevity.
Расширение или добавление настраиваемых утверждений с помощью IClaimsTransformation
Интерфейс IClaimsTransformation можно использовать для добавления дополнительных утверждений в ClaimsPrincipal класс. Для интерфейса требуется один метод TransformAsync. Этот метод может вызываться несколько раз. Добавьте новое утверждение только в том случае, если оно еще не существует в .ClaimsPrincipal
Создается ClaimsIdentity
для добавления новых утверждений и его можно добавить в .ClaimsPrincipal
using Microsoft.AspNetCore.Authentication;
using System.Security.Claims;
public class MyClaimsTransformation : IClaimsTransformation
{
public Task<ClaimsPrincipal> TransformAsync(ClaimsPrincipal principal)
{
ClaimsIdentity claimsIdentity = new ClaimsIdentity();
var claimType = "myNewClaim";
if (!principal.HasClaim(claim => claim.Type == claimType))
{
claimsIdentity.AddClaim(new Claim(claimType, "myClaimValue"));
}
principal.AddIdentity(claimsIdentity);
return Task.FromResult(principal);
}
}
Интерфейс IClaimsTransformation и MyClaimsTransformation
класс можно зарегистрировать как службу:
builder.Services.AddTransient<IClaimsTransformation, MyClaimsTransformation>();
Сопоставление утверждений от внешних поставщиков удостоверений
См. следующий документ:
Сохранение дополнительных утверждений и маркеров от внешних поставщиков в ASP.NET Core
Утверждения можно создавать из любых данных пользователя или удостоверений, которые могут быть выданы доверенным поставщиком удостоверений или средствами ASP.NET Core Identity. Утверждение — это пара "имя-значение", которая представляет собой предмет, а не то, что он может делать. В этой статье рассматриваются следующие области:
- Настройка и сопоставление утверждений с помощью клиента OpenID Connect
- Задание утверждения имени и роли
- Сброс пространств имен утверждений
- Настройка, расширение утверждений с помощью TransformAsync
Сопоставление утверждений с помощью проверки подлинности OpenID Connect
Утверждения профиля можно вернуть в id_token
объекте , который возвращается после успешной проверки подлинности. Клиентское приложение ASP.NET Core требует только области профиля. При использовании утверждений не требуется дополнительное id_token
сопоставление утверждений.
public void ConfigureServices(IServiceCollection services)
{
services.AddAuthentication(options =>
{
options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
})
.AddCookie()
.AddOpenIdConnect(options =>
{
options.SignInScheme = "Cookies";
options.Authority = "-your-identity-provider-";
options.RequireHttpsMetadata = true;
options.ClientId = "-your-clientid-";
options.ClientSecret = "-your-client-secret-from-user-secrets-or-keyvault";
options.ResponseType = "code";
options.UsePkce = true;
options.Scope.Add("profile");
options.SaveTokens = true;
});
Другим способом получения утверждений пользователя является использование API сведений о пользователе OpenID Connect. Клиентское приложение ASP.NET Core использует GetClaimsFromUserInfoEndpoint
свойство для настройки этого свойства. Одним из важных отличий от первых параметров является то, что необходимо указать утверждения, которые требуется использовать MapUniqueJsonKey
метод, в противном случае в клиентском приложении будут доступны только name
given_name
email
стандартные утверждения. Утверждения, включенные в список id_token
, сопоставляются по умолчанию. Это основное отличие от первого варианта. Необходимо явно определить некоторые необходимые утверждения.
public void ConfigureServices(IServiceCollection services)
{
services.AddAuthentication(options =>
{
options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
})
.AddCookie()
.AddOpenIdConnect(options =>
{
options.SignInScheme = "Cookies";
options.Authority = "-your-identity-provider-";
options.RequireHttpsMetadata = true;
options.ClientId = "-your-clientid-";
options.ClientSecret = "-your-client-secret-from-user-secrets-or-keyvault";
options.ResponseType = "code";
options.UsePkce = true;
options.Scope.Add("profile");
options.SaveTokens = true;
options.GetClaimsFromUserInfoEndpoint = true;
options.ClaimActions.MapUniqueJsonKey("preferred_username", "preferred_username");
options.ClaimActions.MapUniqueJsonKey("gender", "gender");
});
Сопоставление утверждений имен и ролей
Утверждение Name и утверждение роли сопоставляются со свойствами по умолчанию в контексте HTTP ASP.NET Core. Иногда требуется использовать различные утверждения для свойств по умолчанию или утверждение имени, а утверждение роли не совпадает со значениями по умолчанию. Утверждения можно сопоставить с помощью свойства TokenValidationParameters и задать любое утверждение по мере необходимости. Значения из утверждений можно использовать непосредственно в httpContext User.Identity. Свойство name и роли.
User.Identity.Name
Если отсутствуют значения или роли отсутствуют, проверьте значения в возвращенных утверждениях и задайте NameClaimType
значения и RoleClaimType
значения. Возвращенные утверждения из проверки подлинности клиента можно просмотреть в контексте HTTP.
public void ConfigureServices(IServiceCollection services)
{
services.AddAuthentication(options =>
{
options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
})
.AddCookie()
.AddOpenIdConnect(options =>
{
// other options...
options.TokenValidationParameters = new TokenValidationParameters
{
NameClaimType = "email",
// RoleClaimType = "role"
};
});
Пространства имен утверждений, пространства имен по умолчанию
ASP.NET Core добавляет пространства имен по умолчанию в некоторые известные утверждения, которые могут не потребоваться в приложении. При необходимости отключите эти добавленные пространства имен и используйте точные утверждения, созданные сервером OpenID Connect.
public void Configure(IApplicationBuilder app)
{
JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();
Расширение или добавление настраиваемых утверждений с помощью IClaimsTransformation
Интерфейс IClaimsTransformation
можно использовать для добавления дополнительных утверждений в ClaimsPrincipal
класс. Для интерфейса требуется один метод TransformAsync
. Этот метод может вызываться несколько раз. Добавьте новое утверждение только в том случае, если оно еще не существует в .ClaimsPrincipal
Создается ClaimsIdentity
для добавления новых утверждений и его можно добавить в .ClaimsPrincipal
public class MyClaimsTransformation : IClaimsTransformation
{
public Task<ClaimsPrincipal> TransformAsync(ClaimsPrincipal principal)
{
ClaimsIdentity claimsIdentity = new ClaimsIdentity();
var claimType = "myNewClaim";
if (!principal.HasClaim(claim => claim.Type == claimType))
{
claimsIdentity.AddClaim(new Claim(claimType, "myClaimValue"));
}
principal.AddIdentity(claimsIdentity);
return Task.FromResult(principal);
}
}
Интерфейс IClaimsTransformation
и MyClaimsTransformation
класс можно добавить в метод ConfigureServices в качестве службы.
public void ConfigureServices(IServiceCollection services)
{
services.AddTransient<IClaimsTransformation, MyClaimsTransformation>();
Расширение или добавление пользовательских утверждений в ASP.NET Core Identity
См. следующий документ:
Добавление утверждений в Identity использование IUserClaimsPrincipalFactory
Сопоставление утверждений от внешних поставщиков удостоверений
См. следующий документ:
Сохранение дополнительных утверждений и маркеров от внешних поставщиков в ASP.NET Core
ASP.NET Core