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

如何在使用OIDC的Blazor Server应用中获取访问令牌全部Claims?

在Blazor Server(OIDC)中获取访问令牌的完整Claims

默认情况下,通过AuthenticationStateProvider获取的用户Claims仅包含OIDC提供商返回的部分信息,若要访问访问令牌中的scope、client_id、aud等全部Claims,可通过以下两种方式实现:

方法一:配置OIDC认证选项,自动映射令牌Claims到用户身份

在项目的Program.cs中配置OIDC认证服务时,添加Claim映射规则,确保令牌中的目标Claims被同步到用户身份对象中:

using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Authentication.OpenIdConnect;

var builder = WebApplication.CreateBuilder(args);

// 添加HttpContextAccessor(可选,用于后续直接获取令牌)
builder.Services.AddHttpContextAccessor();

// 配置认证服务
builder.Services.AddAuthentication(options =>
{
    options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
    options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
})
.AddCookie()
.AddOpenIdConnect(options =>
{
    options.Authority = "你的OIDC提供商地址"; // 例如:https://your-oidc-provider.com
    options.ClientId = "你的客户端ID";
    options.ClientSecret = "你的客户端密钥";
    options.ResponseType = "code";
    options.Scope.Add("openid");
    options.Scope.Add("profile"); // 根据需求添加其他Scope

    // 映射令牌中的特定Claims到用户身份
    options.ClaimActions.MapJsonKey("scope", "scope");
    options.ClaimActions.MapJsonKey("client_id", "client_id");
    options.ClaimActions.MapJsonKey("aud", "aud");
    // 若需要保留所有Claims,可使用:options.ClaimActions.MapAll();

    // 从UserInfo端点获取Claims(可选,根据OIDC提供商配置)
    options.GetClaimsFromUserInfoEndpoint = true;
    // 保存令牌到Cookie,方便后续获取
    options.SaveTokens = true;
});

// 其他服务配置...

var app = builder.Build();

// 中间件配置...
app.UseAuthentication();
app.UseAuthorization();

app.Run();

配置完成后,即可在Blazor组件中直接从AuthenticationState获取这些Claims:

@inject AuthenticationStateProvider AuthStateProvider

@code {
    protected override async Task OnInitializedAsync()
    {
        var authState = await AuthStateProvider.GetAuthenticationStateAsync();
        var user = authState.User;

        // 获取目标Claims
        var scope = user.FindFirst("scope")?.Value;
        var clientId = user.FindFirst("client_id")?.Value;
        var audience = user.FindFirst("aud")?.Value;
    }
}

方法二:直接获取访问令牌并手动解析Claims

如果不需要将Claims映射到用户身份,可直接获取访问令牌并解析其中的所有内容:

  1. 先确保已注册IHttpContextAccessor(参考方法一中的builder.Services.AddHttpContextAccessor();)
  2. 在Blazor组件中注入IHttpContextAccessor,并解析令牌:
@inject IHttpContextAccessor HttpContextAccessor
@using System.IdentityModel.Tokens.Jwt

@code {
    protected override async Task OnInitializedAsync()
    {
        // 从HttpContext获取访问令牌
        var accessToken = await HttpContextAccessor.HttpContext.GetTokenAsync("access_token");
        
        if (!string.IsNullOrEmpty(accessToken))
        {
            var tokenHandler = new JwtSecurityTokenHandler();
            // 解析JWT令牌
            var jwtToken = tokenHandler.ReadJwtToken(accessToken);
            
            // 获取令牌中的所有Claims
            var allTokenClaims = jwtToken.Claims;
            // 提取特定Claims
            var scope = allTokenClaims.FirstOrDefault(c => c.Type == "scope")?.Value;
            var clientId = allTokenClaims.FirstOrDefault(c => c.Type == "client_id")?.Value;
            var audience = allTokenClaims.FirstOrDefault(c => c.Type == "aud")?.Value;
        }
    }
}

注意事项

  • 必须设置options.SaveTokens = true,否则无法通过GetTokenAsync获取访问令牌。
  • 解析JWT需要依赖System.IdentityModel.Tokens.Jwt包,可通过NuGet安装该包。
  • 使用MapAll()会映射所有令牌Claims,但可能引入冗余数据,建议按需使用MapJsonKey映射特定Claims。

内容的提问来源于stack exchange,提问作者M. Akar

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.25 11:54:06