ASP.NET Core 7中自定义Claim重定向后消失问题求助
解决方案
问题原因
你当前的代码只是在当前请求上下文中临时添加了ClaimsIdentity,并没有将其持久化到认证Cookie中。重定向后新请求会重新从Cookie加载用户身份,自然无法获取到临时添加的Claim。
实现持久化的步骤
要让自定义Claim持久化,需要修改用户的认证票据并重新登录,将新的身份信息写入Cookie。
方法一:使用SignInManager重新登录
首先在控制器中注入SignInManager<ClaimsPrincipal>和IHttpContextAccessor:
private readonly IHttpContextAccessor _httpContextAccessor; private readonly SignInManager<ClaimsPrincipal> _signInManager; public YourController(IHttpContextAccessor httpContextAccessor, SignInManager<ClaimsPrincipal> signInManager) { _httpContextAccessor = httpContextAccessor; _signInManager = signInManager; }
然后修改业务逻辑代码:
var userID = await GetId(User.Identity?.Name.ToString()); if (userID != 0) { // 获取当前用户的身份主体 var currentPrincipal = _httpContextAccessor.HttpContext.User; // 创建包含原有所有Claim的新身份,再添加自定义Claim var newIdentity = new ClaimsIdentity(currentPrincipal.Identity); newIdentity.AddClaim(new Claim("MyClaim", userID.ToString())); // 构建新的身份主体 var newPrincipal = new ClaimsPrincipal(newIdentity); // 重新登录,将新身份持久化到认证Cookie await _signInManager.SignInAsync(newPrincipal, isPersistent: true); return RedirectToAction(nameof(Index)); }
方法二:直接操作AuthenticationTicket
如果不想依赖SignInManager,也可以直接通过HttpContext更新认证票据:
var userID = await GetId(User.Identity?.Name.ToString()); if (userID != 0) { // 读取当前的认证票据 var authResult = await HttpContext.AuthenticateAsync(CookieAuthenticationDefaults.AuthenticationScheme); if (authResult.Succeeded) { // 复制原有Claim并添加新Claim var updatedClaims = authResult.Principal.Claims.ToList(); updatedClaims.Add(new Claim("MyClaim", userID.ToString())); // 创建新的身份和主体 var newIdentity = new ClaimsIdentity(updatedClaims, authResult.Principal.Identity.AuthenticationType); var newPrincipal = new ClaimsPrincipal(newIdentity); // 重新写入认证Cookie await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, newPrincipal, authResult.Properties); } return RedirectToAction(nameof(Index)); }
获取持久化的Claim
在任何控制器或视图中,都可以直接从User对象中读取自定义Claim:
控制器中获取
// 直接查找Claim var myClaimValue = User.Claims.FirstOrDefault(c => c.Type == "MyClaim")?.Value; // 封装成扩展方法更方便 public static class ClaimsPrincipalExtensions { public static string GetMyClaimValue(this ClaimsPrincipal principal) { return principal.Claims.FirstOrDefault(c => c.Type == "MyClaim")?.Value; } } // 使用扩展方法 var value = User.GetMyClaimValue();
视图中获取
@using System.Security.Claims @{ var myClaimValue = User.Claims.FirstOrDefault(c => c.Type == "MyClaim")?.Value; } <p>自定义Claim值:@myClaimValue</p>
注意事项
- 确保项目中已正确配置Cookie认证(Azure AD认证会自动配置此部分)
- 如果用户的
userID后续发生变化,需要重复上述流程重新更新Claim并持久化 - 自定义Claim会存储在认证Cookie中,避免添加过大的数据,影响Cookie性能
内容的提问来源于stack exchange,提问作者Diomedes
相关产品推荐
相关产品推荐

