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

ASP.NET Core 6中如何通过OpenIdConnect将Access Token声明添加到ClaimsPrincipal

解决ASP.NET Core 6中OpenIdConnect无法获取Access Token声明的问题

默认情况下,Microsoft.AspNetCore.Authentication.OpenIdConnect中间件仅从id_token提取声明构建ClaimsPrincipal,不会自动包含access_token中的内容。要将access_token的声明添加到主体中,可按以下步骤操作:

1. 基础配置确保获取Access Token

先在认证服务配置中开启SaveTokens以保存access_token到认证票据,同时配置正确的授权码流参数:

builder.Services.AddAuthentication(options =>
{
    options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
    options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
})
.AddCookie()
.AddOpenIdConnect(options =>
{
    options.Authority = "https://your-keycloak-domain/auth/realms/your-realm";
    options.ClientId = "your-client-id";
    options.ClientSecret = "your-client-secret";
    options.ResponseType = OpenIdConnectResponseType.Code;
    options.SaveTokens = true; // 必须开启,才能后续读取access_token
    options.GetClaimsFromUserInfoEndpoint = true; // 可选,若需从UserInfo端点拉取额外信息
});

2. 在令牌验证事件中解析并添加声明

通过OnTokenValidated事件,在令牌验证完成后解析access_token,将其声明添加到ClaimsPrincipal:

options.Events = new OpenIdConnectEvents
{
    OnTokenValidated = context =>
    {
        // 从认证属性中读取access_token
        if (context.Properties.TryGetTokenValue("access_token", out var accessToken))
        {
            var tokenHandler = new JwtSecurityTokenHandler();
            if (tokenHandler.CanReadToken(accessToken))
            {
                var jwtToken = tokenHandler.ReadJwtToken(accessToken);
                
                // 遍历access_token的声明,添加到主体中
                foreach (var claim in jwtToken.Claims)
                {
                    // 可选:跳过已存在的声明,避免重复
                    if (!context.Principal.HasClaim(c => c.Type == claim.Type && c.Value == claim.Value))
                    {
                        context.Principal.AddClaim(claim);
                    }
                }
            }
        }

        return Task.CompletedTask;
    }
};

注:context.Properties.TryGetTokenValue是.NET 6+的扩展方法,比直接读取字典更简洁可靠。

3. 额外注意事项

  • 确认Keycloak客户端配置中,access_token已包含你需要的自定义声明:可在Keycloak的客户端范围或用户属性映射中配置。
  • 若Keycloak签发的access_token是加密的,需额外配置解密密钥(默认情况下Keycloak签发的是未加密JWT,无需此操作)。
  • 如果不需要保留重复声明,可根据声明类型或值进行过滤,避免ClaimsPrincipal中出现重复项。

内容的提问来源于stack exchange,提问作者Inx51

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 03:05:21