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

WSO2 APIM 4.2.0自定义JWT生成器:authorization_code授权时获取用户信息失败

WSO2 APIM 4.2.0 自定义后端JWT生成器在authorization_code授权模式下报错解决

问题场景

在WSO2 API Manager 4.2.0一体化部署环境中,使用自定义后端JWT生成器传递自定义声明customerId:

  • 终端用户采用client-credentials授权类型时功能正常
  • 采用authorization_code授权类型时,后端JWT生成失败,抛出**"User does not exist in the UserStore"**错误

调试确认:APIUtil.getClaims()执行失败的核心原因是jwtInfoDto.getEndUser()在authorization_code模式下返回用户的UUID(userId),而非用户名,导致无法在用户存储中匹配到目标用户。

根因分析

  • client-credentials授权:网关获取的endUser是客户端应用的标识(以用户名形式存储在用户库),因此APIUtil.getClaims()可正常查询声明
  • authorization_code授权:默认情况下,网关从OAuth2令牌中获取的endUser是用户的UUID(userId),但APIUtil.getClaims()仅支持通过用户名查询用户存储,因此出现匹配失败

解决方案

修改自定义JWT生成器代码,先将userId转换为对应用户名,再调用APIUtil.getClaims()查询用户声明。修改后的完整代码如下:

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.osgi.service.component.annotations.Component;
import org.wso2.carbon.apimgt.api.APIManagementException;
import org.wso2.carbon.apimgt.common.gateway.dto.JWTInfoDto;
import org.wso2.carbon.apimgt.common.gateway.jwtgenerator.APIMgtGatewayJWTGeneratorImpl;
import org.wso2.carbon.apimgt.common.gateway.jwtgenerator.AbstractAPIMgtGatewayJWTGenerator;
import org.wso2.carbon.apimgt.impl.utils.APIUtil;
import org.wso2.carbon.user.api.UserStoreManager;
import org.wso2.carbon.user.api.UserStoreException;

import java.util.Map;
import java.util.SortedMap;

@Component(
        enabled = true,
        service = AbstractAPIMgtGatewayJWTGenerator.class,
        name = "CustomGatewayJWTGenerator"
)

/**
 * Extend default JWT generator to add Customer ID as additional claim
 */
public class CustomGatewayJWTGenerator extends APIMgtGatewayJWTGeneratorImpl {

    private static final Log LOG = LogFactory.getLog(CustomGatewayJWTGenerator.class);

    @Override
    public Map<String, Object> populateCustomClaims(JWTInfoDto jwtInfoDto) {

        Map<String, Object> claims = super.populateCustomClaims(jwtInfoDto);
        SortedMap<String, String> userClaims;
        String customerIdClaimURI = "http://wso2.org/claims/customerId";
        String endUser = jwtInfoDto.getEndUser();
        int tenantId = jwtInfoDto.getEndUserTenantId();

        try {
            // Convert userId to username for authorization_code flow
            UserStoreManager userStoreManager = APIUtil.getUserStoreManager(tenantId);
            String username = userStoreManager.getUserNameFromUserId(endUser);
            
            // Query claims with username
            userClaims = APIUtil.getClaims(username, tenantId, getDialectURI());
            if (userClaims.containsKey(customerIdClaimURI)) {
                claims.put(customerIdClaimURI, userClaims.get(customerIdClaimURI));
            }
        } catch (APIManagementException | UserStoreException e) {
            LOG.error("Error occurred when populating custom claims", e);
        } 
        return claims;
    }
}

可选配置优化

若希望网关直接返回用户名而非userId,可修改APIM的deployment.toml配置文件,添加以下内容:

[apim.oauth_config]
enable_user_id_in_access_token = false

该配置会让OAuth2令牌存储用户名而非userId,jwtInfoDto.getEndUser()将直接返回用户名,无需代码转换。注意:该配置会影响所有依赖userId的功能,需根据业务场景评估后启用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 05:53:16