使用Active Directory时如何添加自定义声明并使其持久化?
问题分析与解决方案
你的代码仅在当前请求的内存中临时添加了身份信息,请求结束后就会丢失——因为没有将自定义声明写入到持久化的认证票据(如Cookie或Token)中,后续请求无法读取到这些信息。以下是两种可行的解决方式:
1. 将自定义声明整合到认证体系(推荐)
这种方式把自定义数据作为身份认证的一部分,适合需要在授权逻辑中使用的场景(比如基于该声明限制接口访问)。
方式1:动态添加声明(每次请求自动注入)
实现IClaimsTransformation接口,在每次请求时为用户添加自定义声明:
public class CustomClaimsTransformation : IClaimsTransformation { public Task<ClaimsPrincipal> TransformAsync(ClaimsPrincipal principal) { // 避免重复添加声明 if (!principal.HasClaim(c => c.Type == "IsAdminMode")) { var identity = principal.Identity as ClaimsIdentity; identity?.AddClaim(new Claim("IsAdminMode", "true")); } return Task.FromResult(principal); } }
在Program.cs中注册这个服务:
builder.Services.AddScoped<IClaimsTransformation, CustomClaimsTransformation>();
方式2:手动更新并持久化认证票据
如果需要手动触发(比如用户主动切换Admin模式),则需要重新生成认证Cookie并写入客户端:
var httpContext = _httpContextAccessor.HttpContext; var identity = httpContext.User.Identity as ClaimsIdentity; // 移除旧声明(如果存在) var existingClaim = identity?.FindFirst("IsAdminMode"); if (existingClaim != null) { identity.RemoveClaim(existingClaim); } // 添加新声明 identity?.AddClaim(new Claim("IsAdminMode", "true")); // 重新生成并持久化认证Cookie var authProps = new AuthenticationProperties { IsPersistent = true, // 关闭浏览器后仍保留 ExpiresUtc = DateTimeOffset.UtcNow.AddDays(7) }; await httpContext.SignInAsync( CookieAuthenticationDefaults.AuthenticationScheme, new ClaimsPrincipal(identity), authProps);
2. 使用Session存储临时会话变量
如果只是存储临时会话数据,不需要参与授权逻辑,可直接用ASP.NET Core的Session:
首先在Program.cs启用Session:
builder.Services.AddSession(options => { options.IdleTimeout = TimeSpan.FromHours(2); options.Cookie.HttpOnly = true; options.Cookie.IsEssential = true; }); // 注意中间件顺序:在UseRouting之后、UseAuthorization之前添加 app.UseSession();
然后进行读写操作:
// 设置变量 _httpContextAccessor.HttpContext.Session.SetString("IsAdminMode", "true"); // 读取变量 var isAdmin = _httpContextAccessor.HttpContext.Session.GetString("IsAdminMode");
内容的提问来源于stack exchange,提问作者Tom Crosman
相关产品推荐
相关产品推荐

