如何在使用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映射到用户身份,可直接获取访问令牌并解析其中的所有内容:
- 先确保已注册
IHttpContextAccessor(参考方法一中的builder.Services.AddHttpContextAccessor();) - 在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
相关产品推荐
相关产品推荐

