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

请求OAuth2访问令牌时能否添加自定义Claims?

问题

在请求OAuth2 Access Token时,是否可以为其添加自定义Claims?默认情况下授权服务器会添加自身的Claims,但我希望在请求令牌时额外指定自定义Claims。这是否可行?

我正尝试使用nimbusds库实现此功能,以下是我的代码:

/**
    * Obtains an OAuth2 access token using the client credentials grant.
    *
    * @param clientId the client ID to authenticate with the token endpoint
    * @param clientSecret the client secret to authenticate with the token endpoint
    * @return the access token value as a string
    */
public String getToken(String clientId, String clientSecret) throws URISyntaxException, ParseException, IOException {
    // Construct the client credentials grant
    AuthorizationGrant clientGrant = new ClientCredentialsGrant();

    // The credentials to authenticate the client at the token endpoint
    ClientID clientID = new ClientID(clientId);
    Secret clientSECRET= new Secret(clientSecret);
    ClientAuthentication clientAuth = new ClientSecretBasic(clientID, clientSECRET);

    // The request scope for the token (may be optional)
    // Scope scope = new Scope("core");

    // The token endpoint
    URI tokenEndpoint = new URI("http://localhost:5444/oauth2/token");
    // URI tokenEndpoint = new URI("http://localhost:8081/realms/master/protocol/openid-connect/token");

    // Make the token request
    TokenRequest request = new TokenRequest(tokenEndpoint, clientAuth, clientGrant, null, null, Map.of("custom", List.of("custom")));

    TokenResponse response = TokenResponse.parse(request.toHTTPRequest().send());

    if (! response.indicatesSuccess()) {
        // We got an error response...
        TokenErrorResponse errorResponse = response.toErrorResponse();
        log.info("errorResponse: {}", errorResponse.toString());
    }

    AccessTokenResponse successResponse = response.toSuccessResponse();

    // Get the access token
    AccessToken accessToken = successResponse.getTokens().getAccessToken();
    log.info("accessToken: {}", accessToken.toJSONString());

    return accessToken.getValue();

}

我在这行代码中尝试添加自定义值,但获取到的令牌中并未包含请求的自定义Claims:

TokenRequest request = new TokenRequest(tokenEndpoint, clientAuth, clientGrant, null, null, Map.of("custom", List.of("custom")));

解决思路

核心结论:自定义Claims的添加必须得到授权服务器的支持,客户端仅发送参数无法直接生效,需要从请求方式、服务器配置两方面调整:

1. 修正TokenRequest的参数传递方式

OAuth2规范中,客户端传递自定义Claims通常需要通过claims参数(JSON格式)指定,而非直接传入自定义键值对。修改代码示例:

// 构造指定access_token自定义Claims的JSON结构
String claimsJson = "{\"access_token\":{\"custom\":\"custom_value\"}}";
// 将claims作为请求参数传入TokenRequest
TokenRequest request = new TokenRequest(
    tokenEndpoint, 
    clientAuth, 
    clientGrant, 
    null, 
    null, 
    Map.of("claims", List.of(claimsJson))
);

2. 配置授权服务器接收并处理自定义Claims

不同授权服务器的配置逻辑不同,举几个常见场景:

  • Spring Authorization Server:自定义OAuth2TokenCustomizer,从token请求的参数中提取自定义值,添加到生成的令牌Claims集合中
  • Keycloak:创建自定义Protocol Mapper,或者在客户端配置中启用允许传递自定义Claims,并将目标Claims添加到客户端作用域
  • 自定义授权服务器:在令牌生成逻辑中,显式读取请求中的自定义参数,写入JWT的Claims

3. 验证请求参数的实际发送状态

用抓包工具(如Charles、Wireshark)检查发送到令牌端点的POST请求,确认自定义参数是否被正确包含在表单数据中。如果参数未发送成功,需排查NimbusDS库是否正确将扩展参数转换为表单字段。

4. 正确解析令牌中的自定义Claims

确保解析access token时直接读取目标Claims,例如:

// 从AccessToken中直接提取自定义Claim
String customValue = accessToken.getClaim("custom").toString();

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 15:35:24