使用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属性的来源。
解决步骤
- 提取客户端凭证:解析
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()); }
- 提取授权码:通过
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
相关产品推荐
相关产品推荐

