You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ASP.NET微服务:如何读取共享认证Cookie中的角色与ID等声明信息?

在非ASP.NET Identity的API中读取共享Auth Cookie的完整声明

要解决这个问题,核心是让非Identity的API能正确解密并解析Auth Cookie中的所有声明,以下是具体实现步骤:

1. 统一数据保护与Cookie认证配置

所有微服务(包括非Identity API)必须使用相同的数据保护配置和Cookie参数,才能保证Cookie能被正确解密。在非Identity API的Program.cs中添加如下配置:

// 配置共享数据保护,需和认证微服务使用相同的密钥存储与应用名称
builder.Services.AddDataProtection()
    .PersistKeysToFileSystem(new DirectoryInfo(@"\\your-shared-key-path")) // 示例:共享文件目录,也可使用Redis/密钥库
    .SetApplicationName("YourSharedApplicationName"); // 必须与认证微服务的ApplicationName完全一致

// 配置Cookie认证,匹配认证微服务的Cookie参数
builder.Services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
    .AddCookie(options =>
    {
        options.Cookie.Name = ".AspNetCore.Identity.Application"; // 和认证微服务的Cookie名称一致
        options.Cookie.Domain = ".your-domain.com"; // 跨域共享的主域名
        options.TicketDataFormat = new TicketDataFormat(
            builder.Services.BuildServiceProvider().GetRequiredService<IDataProtector>()
        );
    });

// 启用认证与授权中间件(顺序不能错)
app.UseAuthentication();
app.UseAuthorization();

配置完成后,你可以通过User.Claims直接获取所有声明,比如:

[HttpGet("user-info")]
public IActionResult GetUserInfo()
{
    var userId = User.FindFirstValue(ClaimTypes.NameIdentifier);
    var roles = User.FindAll(ClaimTypes.Role).Select(c => c.Value);
    return Ok(new { UserId = userId, Roles = roles });
}

2. 手动解密Cookie(备选方案)

如果自动解析失效,可以手动解密Cookie并提取声明:

[ApiController]
[Route("api/claims")]
public class ClaimsController : ControllerBase
{
    private readonly IDataProtector _dataProtector;

    public ClaimsController(IDataProtectionProvider dataProtectionProvider)
    {
        // 使用与认证微服务一致的保护器名称
        _dataProtector = dataProtectionProvider.CreateProtector("Microsoft.AspNetCore.Identity.Application");
    }

    [HttpGet]
    public IActionResult GetAllClaims()
    {
        var cookie = Request.Cookies[".AspNetCore.Identity.Application"];
        if (string.IsNullOrEmpty(cookie))
            return Unauthorized();

        try
        {
            var unprotectedData = _dataProtector.Unprotect(cookie);
            var ticket = TicketSerializer.Default.Deserialize(unprotectedData);
            var claims = ticket.Principal.Claims.ToDictionary(c => c.Type, c => c.Value);
            return Ok(claims);
        }
        catch
        {
            return BadRequest("无法解析认证Cookie");
        }
    }
}

3. 检查认证微服务的声明生成逻辑

确保认证微服务在生成Cookie时,已将角色、用户ID等关键声明添加到ClaimsIdentity中:

// 认证微服务的登录逻辑示例
var user = await _userManager.FindByNameAsync(username);
var claims = new List<Claim>
{
    new Claim(ClaimTypes.NameIdentifier, user.Id),
    new Claim(ClaimTypes.Name, user.UserName),
    new Claim(ClaimTypes.Role, "Admin"), // 添加角色声明
    // 按需添加其他自定义声明
};

var identity = new ClaimsIdentity(claims, CookieAuthenticationDefaults.AuthenticationScheme);
await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, new ClaimsPrincipal(identity));

排查要点

  • 确认所有服务的数据保护密钥完全共享,否则无法解密Cookie。
  • 检查Cookie的Name、Domain、Path参数在所有服务中完全一致。
  • 确保非Identity API的中间件顺序正确:UseAuthentication()必须在UseAuthorization()之前。

内容的提问来源于stack exchange,提问作者Andrеw

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 19:50:36