Identity Server+Azure AD+Blazor声明(Claim)传递异常问题排查
解决Identity Server 4与Azure AD集成后Claim缺失的问题
看起来你遇到的核心问题是IS4没有把从AAD获取的完整声明传递到Blazor应用的id_token里。结合你的配置和日志,我们可以从以下几个方向排查修复:
1. 确保AAD向IS4返回所需的所有声明
首先,你的IS4作为AAD的依赖方,需要正确配置以请求并接收AAD的完整声明。调整AddOpenIdConnect的配置:
services.AddAuthentication() .AddOpenIdConnect("aad", "Sign-in with Azure AD", options => { options.Authority = "https://login.microsoftonline.com/common"; options.ClientId = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxx"; options.SignInScheme = IdentityServerConstants.ExternalCookieAuthenticationScheme; options.SignOutScheme = IdentityServerConstants.SignoutScheme; options.ResponseType = "id_token"; options.CallbackPath = "/signin-aad"; options.SignedOutCallbackPath = "/signout-callback-aad"; options.RemoteSignOutPath = "/signout-aad"; // 新增:请求AAD的profile和email scope,确保获取相关声明 options.Scope.Add("profile"); options.Scope.Add("email"); // 如果需要角色声明,添加roles scope(前提是AAD应用配置了角色) options.Scope.Add("roles"); // 开启从UserInfo端点获取额外声明(AAD有些声明不会默认放在id_token里) options.GetClaimsFromUserInfoEndpoint = true; options.TokenValidationParameters = new TokenValidationParameters { ValidateIssuer = false, NameClaimType = "name", RoleClaimType = "role" }; // 新增:映射AAD的声明到标准Claim类型,避免命名不一致 options.ClaimActions.MapJsonKey(ClaimTypes.Email, "email"); options.ClaimActions.MapJsonKey(ClaimTypes.GivenName, "given_name"); options.ClaimActions.MapJsonKey(ClaimTypes.Surname, "family_name"); options.ClaimActions.MapJsonKey(ClaimTypes.Role, "role"); });
2. 配置IS4的Identity资源,确保声明被允许传递
你的config.cs里需要明确定义包含所需声明的Identity资源,否则IS4不会将这些声明包含在id_token中:
public static IEnumerable<IdentityResource> IdentityResources => new List<IdentityResource> { new IdentityResources.OpenId(), new IdentityResources.Profile(), // 包含name、family_name、given_name等声明 new IdentityResources.Email(), // 包含email、email_verified声明 new IdentityResource( name: "roles", displayName: "User Roles", userClaims: new List<string> { "role" } ) };
同时,确保你的客户端AllowedScopes包含这些资源:
AllowedScopes = { "openid", "profile", "email", "roles", "backend" },
3. 自定义Profile Service,确保外部声明被正确转发
默认的IS4 Profile Service不会自动将所有外部身份源(AAD)的声明传递给客户端。你需要实现IProfileService来手动包含这些声明:
public class CustomProfileService : IProfileService { private readonly IUserClaimsPrincipalFactory<ApplicationUser> _claimsFactory; private readonly UserManager<ApplicationUser> _userManager; public CustomProfileService(UserManager<ApplicationUser> userManager, IUserClaimsPrincipalFactory<ApplicationUser> claimsFactory) { _userManager = userManager; _claimsFactory = claimsFactory; } public async Task GetProfileDataAsync(ProfileDataRequestContext context) { var sub = context.Subject.GetSubjectId(); var user = await _userManager.FindByIdAsync(sub); if (user == null) { throw new ArgumentException("Invalid subject identifier"); } var principal = await _claimsFactory.CreateAsync(user); var claims = principal.Claims.ToList(); // 额外添加从外部身份源(AAD)获取的声明 var externalClaims = context.Subject.FindAll(c => c.Type != ClaimTypes.NameIdentifier).ToList(); claims.AddRange(externalClaims); // 确保只返回请求的声明类型 var requestedClaims = context.RequestedClaimTypes; if (requestedClaims.Any()) { claims = claims.Where(c => requestedClaims.Contains(c.Type)).ToList(); } context.IssuedClaims = claims; } public async Task IsActiveAsync(IsActiveContext context) { var sub = context.Subject.GetSubjectId(); var user = await _userManager.FindByIdAsync(sub); context.IsActive = user != null; } }
然后在Startup.cs中注册这个服务:
services.AddScoped<IProfileService, CustomProfileService>();
4. 检查Azure AD应用注册的令牌配置
登录Azure Portal,找到你的AAD应用注册:
- 进入令牌配置,点击添加声明,确保你需要的声明(比如email、given_name、family_name、role等)被添加并设置为在id_token中返回。
- 如果使用角色,需要在应用角色或企业应用程序中给用户分配角色,确保AAD会将角色声明包含在令牌中。
5. 调试验证声明流转
启用IS4的详细日志,查看从AAD获取的原始声明:
- 在
appsettings.json中设置日志级别:"Logging": { "LogLevel": { "Default": "Debug", "Microsoft": "Warning", "Microsoft.Hosting.Lifetime": "Information", "IdentityServer4": "Debug" } } - 查看日志中外部认证后的ClaimsPrincipal,确认AAD是否返回了所需的声明。如果AAD没返回,就需要调整AAD应用配置;如果AAD返回了但IS4没传递,就需要检查Profile Service和Identity资源配置。
按照这些步骤调整后,应该就能让所有请求的声明出现在id_token中了。
内容的提问来源于stack exchange,提问作者Rihen
相关产品推荐
相关产品推荐

