WSO2 IS 5.10.0中自定义声明未写入JWT问题排查及示例需求
问题排查与解决方案
可能的问题点
1. Access Token声明返回配置未开启
WSO2 IS 默认不会将所有用户声明自动包含在Access Token中,哪怕你在ClaimHandler中完成了映射。需手动开启相关配置:
- 打开
<IS_HOME>/repository/conf/identity/identity.xml,找到<OAuth>节点,添加或修改:<AlwaysSendClaimsInToken>true</AlwaysSendClaimsInToken> - 或者在对应OAuth客户端的配置中,添加自定义属性
oauth.include.user.claims,值设为true(路径:IS管理控制台 → 服务提供者 → 对应客户端 → OAuth/OpenID Connect Configuration → 编辑 → 添加自定义属性)。
2. OpenID范围仅作用于ID Token
你提到将声明添加到openid范围,但openid范围主要控制ID Token的声明返回,而当前请求用的是response_type=token,获取的是Access Token。需确保这些声明也关联到OAuth2的default范围,或自定义范围并关联声明,同时在授权请求中包含该范围。
3. ClaimHandler未正确传递声明到Token生成上下文
重写handleLocalClaims和handleExternalClaims时,需确保处理后的声明被正确返回,否则后续流程无法获取。示例逻辑:
@Override public Map<String, String> handleLocalClaims(Map<String, String> localClaims, User user, ClaimMapping[] requestedClaimMappings, String issuer, Map<String, Object> properties) throws ClaimHandlerException { // 从User对象取出自定义声明并添加到返回集合 localClaims.put("custom_claim1", user.getClaimValue("http://wso2.org/claims/customclaim1")); localClaims.put("custom_claim2", user.getClaimValue("http://wso2.org/claims/customclaim2")); // 必须返回处理后的集合,不可遗漏 return super.handleLocalClaims(localClaims, user, requestedClaimMappings, issuer, properties); }
4. 自定义认证器未将声明存入User对象
在CustomLocalAuthenticator的认证逻辑中,需把从外部API获取的字段正确设置到AuthenticatedUser的Claims中:
@Override protected void processAuthenticationResponse(HttpServletRequest request, HttpServletResponse response, AuthenticationContext context) throws AuthenticationFailedException { // 调用外部API获取用户声明 String claim1 = externalApiResponse.getString("claim1"); String claim2 = externalApiResponse.getString("claim2"); // 构建认证用户对象并设置声明 AuthenticatedUser authUser = AuthenticatedUser.createAuthenticatedUserFromSubjectIdentifier(username); authUser.setClaimValue("http://wso2.org/claims/customclaim1", claim1); authUser.setClaimValue("http://wso2.org/claims/customclaim2", claim2); // 绑定到认证上下文 context.setSubject(authUser); }
5. 声明映射配置错误
检查IS管理控制台的声明配置:
- 本地声明的
Claim URI需与代码中使用的完全一致(如http://wso2.org/claims/customclaim1) - 外部声明的
Mapped Local Claim需对应正确的本地声明 - 在
Scopes→ 目标范围(如openid或default)中,确认已添加这些本地声明,并勾选对应Token的包含选项
实用示例
1. 自定义ClaimHandler核心代码
public class CustomClaimHandler extends DefaultClaimHandler { @Override public Map<String, String> handleLocalClaims(Map<String, String> localClaims, User user, ClaimMapping[] requestedClaimMappings, String issuer, Map<String, Object> properties) throws ClaimHandlerException { // 从User对象提取自定义声明 String[] claimUris = { "http://wso2.org/claims/customclaim1", "http://wso2.org/claims/customclaim2", "http://wso2.org/claims/customclaim3", "http://wso2.org/claims/customclaim4" }; String[] tokenClaimNames = { "custom_claim1", "custom_claim2", "custom_claim3", "custom_claim4" }; // 映射声明到Token字段 for (int i = 0; i < claimUris.length; i++) { String claimValue = user.getClaimValue(claimUris[i]); if (claimValue != null) { localClaims.put(tokenClaimNames[i], claimValue); } } // 调用父类处理默认声明逻辑 return super.handleLocalClaims(localClaims, user, requestedClaimMappings, issuer, properties); } }
2. 注册自定义ClaimHandler
在<IS_HOME>/repository/conf/identity/identity.xml中替换默认ClaimHandler:
<ClaimHandler>org.wso2.custom.auth.handler.CustomClaimHandler</ClaimHandler>
3. 授权请求调整
确保请求包含关联声明的范围,比如添加default范围:
https://localhost:9443/oauth2/authorize?scope=openid default&response_type=token&redirect_uri=https://localhost/callback&client_id=9_rLhEkjM66KfJNc5xWaJjECvuEa
内容的提问来源于stack exchange,提问作者Marco Picariello
相关产品推荐
相关产品推荐

