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

使用Nimbus OAuth2 SDK 10.13时TokenRequest无法获取ClientID等信息

问题

我正在使用nimbus-oauth2-sdk 10.13搭建OAuth提供商与OAuth客户端。

客户端代码

该客户端通过授权码发送Token请求,对接谷歌、脸书等第三方提供商可返回正确响应:

// Initialize client information
ClientID clientId = new ClientID("12345");
Secret secret = new Secret("abcdef");
URI redirectURL = URI.create("http://localhost:8080/tokenResponse");
AuthorizationCode authCode = new AuthorizationCode("aaa");

// Create TokenRequest
TokenRequest tokenRequest = new TokenRequest(
                    redirectURL,
                    new ClientSecretPost(clientId, secret),
                    new AuthorizationCodeGrant(authCode, redirectURL)
            );

// Send HTTP request
HTTPResponse httpResponse = tokenRequest.toHTTPRequest().send();
String responseBody = httpResponse.getContent();

// Parse and handle the token response
net.minidev.json.JSONObject tokenJson = OAuthUtil.parseJSONresponse(responseBody);
TokenResponse response = TokenResponse.parse(tokenJson);

if (response instanceof AccessTokenResponse) {
    System.out.println(new JSONObject(responseBody).toString());

} else {
    try {
        throw new OAuthException("Error in receiving token: " + tokenJson.getAsString("error"), 3);
    } catch (OAuthException e) {
        throw new RuntimeException(e);
    }
}

服务端代码

try {
    LOGGER.log(Level.INFO,request.getParameter("client_id"));
    LOGGER.log(Level.INFO,request.getParameter("authorization_details"));

    TokenRequest tokenRequest = TokenRequest.parse(ServletUtils.createHTTPRequest(request));

    if (tokenRequest.getClientID() != null) {
        LOGGER.log(Level.INFO, "Client ID: " + tokenRequest.getClientID().getValue());
    } else {
        LOGGER.log(Level.WARNING, "Client ID is null");
    }
} catch (ParseException e) {
    LOGGER.log(Level.WARNING, "Error parsing token request: " + e.getMessage());
}

Tokens tokens = new Tokens(new BearerAccessToken(), new RefreshToken());
AccessTokenResponse accessTokenResponse = new AccessTokenResponse(tokens);
response.getWriter().write(accessTokenResponse.toJSONObject().toJSONString());

在服务端中,通过request.getParameter("client_id")可以获取到Client ID,但tokenRequest.getClientID()返回null,请问这是什么原因?


原因分析与解决办法

这是因为你使用的ClientSecretPost客户端认证方式,会把客户端凭证(client_id和client_secret)放在请求体中,而Nimbus SDK的TokenRequest.parse()方法默认只会从请求的Authorization头或者请求参数的client_id字段提取客户端ID,但不会自动解析请求体里的client_id——因为ClientSecretPost的凭证属于客户端认证信息,并非TokenRequest本身client_id属性的来源。

解决步骤

  1. 提取客户端凭证:解析TokenRequest后,通过getClientAuthentication()获取ClientSecretPost实例,从中提取client_id和client_secret:
ClientAuthentication clientAuth = tokenRequest.getClientAuthentication();
if (clientAuth instanceof ClientSecretPost) {
    ClientSecretPost secretPost = (ClientSecretPost) clientAuth;
    LOGGER.log(Level.INFO, "Client ID: " + secretPost.getClientID().getValue());
    LOGGER.log(Level.INFO, "Client Secret: " + secretPost.getClientSecret().getValue());
}
  1. 提取授权码:通过getAuthorizationGrant()获取AuthorizationCodeGrant实例,提取授权码:
AuthorizationGrant grant = tokenRequest.getAuthorizationGrant();
if (grant instanceof AuthorizationCodeGrant) {
    AuthorizationCodeGrant codeGrant = (AuthorizationCodeGrant) grant;
    LOGGER.log(Level.INFO, "Authorization Code: " + codeGrant.getAuthorizationCode().getValue());
}

本质原因

TokenRequest.getClientID()方法的设计是返回显式在请求参数中传递的client_id(比如隐式授权流的场景),而ClientSecretPost方式的客户端凭证属于OAuth 2.0规范定义的客户端认证信息,需要从客户端认证对象中提取,Nimbus SDK严格遵循了这一规范。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 07:00:55