Так что я понял, как добиться в основном того, чего хотел !!
Мне действительно не нужно было специально добавлять «уникальное_имя» к токену, а просто добавить больше утверждений, чем то, что стандартная среда Identity добавляет для вас.
Вот как я это сделал:
Создание пользовательского SignInManager:
public class OpenIdictSignInManager<TUser> : SignInManager<TUser> where TUser : IdentityUser
{
public OpenIdictSignInManager(
UserManager<TUser> userManager,
IHttpContextAccessor contextAccessor,
IUserClaimsPrincipalFactory<TUser> claimsFactory,
IOptions<IdentityOptions> optionsAccessor,
ILogger<SignInManager<TUser>> logger,
IAuthenticationSchemeProvider schemes) : base(userManager,
contextAccessor,
claimsFactory,
optionsAccessor,
logger,
schemes)
{
}
public override async Task<ClaimsPrincipal> CreateUserPrincipalAsync(TUser user)
{
var principal = await base.CreateUserPrincipalAsync(user);
var identity = (ClaimsIdentity)principal.Identity;
identity.AddClaim(new Claim(OpenIdConnectConstants.Claims.EmailVerified, user.EmailConfirmed.ToString().ToLower()));
return principal;
}
}
Затем применил новый SignInManager к конфигурации startup.cs:
// Register the Identity services.
services.AddIdentity<ApplicationUser, IdentityRole>()
.AddEntityFrameworkStores<ApplicationDbContext>()
.AddDefaultTokenProviders()
.AddSignInManager<OpenIdictSignInManager<ApplicationUser>>();
Затем добавлен пункт назначения заявки при создании заявки в AuthorizationController:
// Note: by default, claims are NOT automatically included in the access and identity tokens.
// To allow OpenIddict to serialize them, you must attach them a destination, that specifies
// whether they should be included in access tokens, in identity tokens or in both.
foreach (var claim in ticket.Principal.Claims)
{
// Never include the security stamp in the access and identity tokens, as it's a secret value.
if (claim.Type == _identityOptions.Value.ClaimsIdentity.SecurityStampClaimType)
{
continue;
}
var destinations = new List<string>();
// Identity Token destinations only
if (new List<string>
{
OpenIdConnectConstants.Claims.EmailVerified
}.Contains(claim.Type))
{
destinations.Add(OpenIdConnectConstants.Destinations.IdentityToken);
claim.SetDestinations(destinations);
continue;
}
destinations.Add(OpenIdConnectConstants.Destinations.AccessToken);
// Only add the iterated claim to the id_token if the corresponding scope was granted to the client application.
// The other claims will only be added to the access_token, which is encrypted when using the default format.
if ((claim.Type == OpenIdConnectConstants.Claims.Name && ticket.HasScope(OpenIdConnectConstants.Scopes.Profile)) ||
(claim.Type == OpenIdConnectConstants.Claims.Email && ticket.HasScope(OpenIdConnectConstants.Scopes.Email)) ||
(claim.Type == OpenIdConnectConstants.Claims.Role && ticket.HasScope(OpenIddictConstants.Claims.Roles)))
{
destinations.Add(OpenIdConnectConstants.Destinations.IdentityToken);
}
claim.SetDestinations(destinations);
}
Мне понадобилось несколько дней, чтобы покопаться в коде и поискать в Google, чтобы придумать этот подход, поэтому я подумал, что поделюсь им и надеюсь, что это поможет кому-то еще:)