#asp.net #.net #asp.net-core #.net-core #asp.net-core-webapi
#asp.net #.net #asp.net-core #.net-core #asp.net-core-webapi
Вопрос:
Я разрабатываю ASP.NET Ядро 3.1 Веб-API с конечной точкой для добавления нового утверждения к существующему идентификатору пользователя. Утверждение успешно добавляется к идентификатору, однако при последующих запросах добавленное утверждение отсутствует в коллекции утверждений, поэтому недоступно. Я также попытался добавить новое удостоверение, присвоив ему утверждение, аналогично при последующих запросах добавленное удостоверение отсутствует в коллекции удостоверений. Есть идеи?
var claims = new List<Claim>()
{
new Claim("token","value")
}
var identity = httpContextAccessor.HttpContext.User.Identities.FirstOrDefault();
identity.AddClaims(claims);
Комментарии:
1. HttpContext уникален для отдельного запроса. Добавление утверждения к идентификатору запроса (a) ничего не сделает для последующего запроса (b).
Ответ №1:
Чтобы сохранить вновь добавленные утверждения для существующего пользователя HttpContext, вы могли бы реализовать пользовательский CustomClaimsPrincipalFactory. Выполните следующие действия:
public class AppUser : IdentityUser
{
public string CompanyName { get; set; }
public string DisplayName { get; set; }
}
public static class IdentityExtensions
{
public static string FullName(this IIdentity identity) //@User.Identity.FullName()
{
var claim = ((ClaimsIdentity)identity).FindFirst("DisplayName");
// Test for null to avoid issues during local testing
return (claim != null) ? claim.Value : string.Empty;
}
public static string GetCompanyName(this IIdentity identity)
{
if (identity == null)
throw new ArgumentNullException(nameof(identity));
var claim = ((ClaimsIdentity)identity).FindFirst("CompanyName");
// Test for null to avoid issues during local testing
return (claim != null) ? claim.Value : string.Empty;
}
}
public class CustomClaimsPrincipalFactory : UserClaimsPrincipalFactory<AppUser, IdentityRole>
{
public CustomClaimsPrincipalFactory(UserManager<AppUser> userManager, RoleManager<IdentityRole> roleManager,
IOptions<IdentityOptions> optionsAccessor)
: base(userManager, roleManager, optionsAccessor)
{
}
public override async Task<ClaimsPrincipal> CreateAsync(AppUser user)
{
if (user == null)
throw new ArgumentNullException(nameof(user));
var principal = await base.CreateAsync(user);
// Add your claims here
((ClaimsIdentity)principal.Identity).AddClaim(new Claim("CompanyName", user.CompanyName));
((ClaimsIdentity)principal.Identity).AddClaim(new Claim("DisplayName", user.DisplayName));
return principal;
}
}
Зарегистрировать CustomClaimsPrincipalFactory
public void Configure(IServiceCollection services)
{
...
services.AddScoped<IUserClaimsPrincipalFactory<AppUser>, CustomClaimsPrincipalFactory>();
});
}
Ответ №2:
Вам нужно позвонить _signInManager.Context.SignInAsync
с обновленным ClaimsIdentity
.
Вот рабочая демонстрация:
1. Расширение для входа с новым ClaimsIdentity
:
public class CustomClaimsCookieSignInHelper<TIdentityUser> where TIdentityUser : IdentityUser
{
private readonly SignInManager<TIdentityUser> _signInManager;
public CustomClaimsCookieSignInHelper(SignInManager<TIdentityUser> signInManager)
{
_signInManager = signInManager;
}
public async Task SignInUserAsync(ClaimsIdentity claimsIdentity)
{
await _signInManager.Context.SignInAsync(IdentityConstants.ApplicationScheme, new ClaimsPrincipal(claimsIdentity));
}
}
2. Зарегистрируйтесь CustomClaimsCookieSignInHelper<TIdentityUser>
:
services.AddTransient<CustomClaimsCookieSignInHelper<IdentityUser>>();
3. Обновите утверждения пользователя:
public class IndexModel : PageModel
{
private readonly CustomClaimsCookieSignInHelper<IdentityUser> _signInHelper;
public IndexModel(CustomClaimsCookieSignInHelper<IdentityUser> signInHelper)
{
_signInHelper = signInHelper;
}
public async Task<IActionResult> OnGetAsync()
{
var claims = new List<Claim>()
{
new Claim("token","value")
};
var identity = HttpContext.User.Identities.FirstOrDefault();
identity.AddClaims(claims);
await _signInHelper.SignInUserAsync(identity);
return Page();
}
}
Кстати, если вы используете jwt authentication
, когда серверная сторона получает вызов API с токеном, AddJwtBearer
токен декодирует токен, проверяет токен и аутентифицирует пользователя, вы можете добавлять новые утверждения либо в OnTokenValidated
пользовательское промежуточное программное обеспечение, либо в пользовательское промежуточное программное обеспечение. Но утверждения не будут сохраняться при следующих вызовах api.Поэтому, если вы хотите получить обновленное утверждение в другом запросе, должен быть выдан новый токен.