如何通过 Spring Boot 访问需要 OAuth2 的外部 URL?
How to access external URL which requires OAuth2 via Spring Boot?
目前,我们用于对需要 OAuth2 的服务器进行身份验证的机制是编写一个包含 main() 方法的 Java 程序,该方法 运行 是一个 HttpClient 来生成一个使用此调用的 OAuth2 访问令牌:
https://api.externalsite.com/v1/oauth/token?clientId=iLHuXeULFBdW4B1dmRY0MhFILRQnlfeK&clientSecret=RG3JanXEq2R1GhRvIQ2d2AKRx0SORvb3&grant_type=client_credentials
此 returns 以下 JSON 负载:
{
"access_token": "eyJhbGciOi786I1NiJ9.eyJ1c2VybmFtZSI6bnVsbCwiZGV2aWNlSWQiOm51bGwsImNsaWVudElkIjoiaUxIdVhlVUxGQmRXNEIxZG1SWTBNaFJPTVJRbmxmZUsiLCJhZElkIjpudWxsLCJleHAiOjE1MjU0MjY4LMYsImlhdCI6MTUyNTQyMzE0Nn0.Zz_uhXqOF2ykC24mNBWHnQ_Vmx-jfQs3X4qcmmN0-Sk",
"token_type": "Bearer",
"expires_in": 3600,
"refresh_token": null,
"scope": null
}
获得访问令牌后,我们可以使用 JSON 对授权网站/服务进行 运行 查询。
问题:
在 Spring 引导微服务 (2.0.1.RELEASE) 中,如何使用 Spring 安全性或仅使用 HttpClient 来使用 clientId、clientSecret 和 grant_type 以在来自 REST 控制器层的每个 REST 调用(可能是 HTTP Post)中自动提供全局访问令牌?
谁能展示一个代码示例,说明如何使用 Spring 安全性或其他库来仅发送 clientId、clientSecret 和 grant_type 来获取 OAuth2 访问令牌?
如果 OAuth2 令牌过期怎么办(使用问题 # 2 中的库)?
1) 您不需要 spring 安全性。只需使用 'io.jsonwebtoken.Jwts'。
您可以使用任意数量的参数来生成 JWT 令牌。
您可以在 Spring 启动应用程序中使用一个组件来生成 JWT 令牌。
然后创建将使用此 bean 的令牌服务并执行:生成访问令牌、验证访问令牌并刷新令牌。
2)
样本 :
@零件
public String createJwtToken(User user, TokenType type, ClientKey clientKey) 抛出 InvalidKeyException, NoSuchAlgorithmException, NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException {
String userName = user.getUsername();
Date currentTime = new Date();
String token = Jwts.builder()
.setSubject(userName)
.claim(Constants.NAME_KEY, Constants.NAME_VALUE)
.claim(Constants.USER_TOKEN_KEY, clientKey.getKey())
.claim(Constants.SCOPE_KEY, Constants.SCOPE_VALUE)
.claim(Constants.TOKEN_TYPE, type.name())
.setIssuer(tokenIssuer)
.setHeaderParam(Constants.TOKEN_TYP, Constants.TOKEN_JWT)
.setHeaderParam(Constants.TOKEN_TYPE, type.name())
.setIssuedAt(currentTime)
.setExpiration(timeout(type))
.signWith(SignatureAlgorithm.HS256, key)
.compact();
return encrypt(token);
}
3) 每当您第一次生成令牌时,您都会生成 2 个令牌:accessToken 和 Refresh Token。
AccessToken 是短暂的,很快就会过期。 - 比如说 5 分钟。
刷新令牌的有效期更长:例如:20 分钟。
刷新令牌的用途是您可以使用刷新令牌生成新的访问令牌。
因此,当您的访问令牌过期时,只需通过传递您的刷新令牌来调用刷新令牌方法。此方法应该 return 来自具有新访问令牌的 redis 用户。
此致,
R 莱
找到IBM开源提供的OAuth2Client:
https://www.ibm.com/developerworks/library/se-oauthjavapt1/index.html#download
此外,刚刚使用了 RestTemplate:
String accessToken = OAuth2Client.generateAccessToken();
RestTemplate restTemplate = new RestTemplate();
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
headers.set("Authorization", "Bearer "+accessToken);
HttpEntity<String> entity = new HttpEntity<String>(request,headers);
String response = restTemplate.postForObject(url, entity, String.class);
非常简单!
目前,我们用于对需要 OAuth2 的服务器进行身份验证的机制是编写一个包含 main() 方法的 Java 程序,该方法 运行 是一个 HttpClient 来生成一个使用此调用的 OAuth2 访问令牌:
https://api.externalsite.com/v1/oauth/token?clientId=iLHuXeULFBdW4B1dmRY0MhFILRQnlfeK&clientSecret=RG3JanXEq2R1GhRvIQ2d2AKRx0SORvb3&grant_type=client_credentials
此 returns 以下 JSON 负载:
{
"access_token": "eyJhbGciOi786I1NiJ9.eyJ1c2VybmFtZSI6bnVsbCwiZGV2aWNlSWQiOm51bGwsImNsaWVudElkIjoiaUxIdVhlVUxGQmRXNEIxZG1SWTBNaFJPTVJRbmxmZUsiLCJhZElkIjpudWxsLCJleHAiOjE1MjU0MjY4LMYsImlhdCI6MTUyNTQyMzE0Nn0.Zz_uhXqOF2ykC24mNBWHnQ_Vmx-jfQs3X4qcmmN0-Sk",
"token_type": "Bearer",
"expires_in": 3600,
"refresh_token": null,
"scope": null
}
获得访问令牌后,我们可以使用 JSON 对授权网站/服务进行 运行 查询。
问题:
在 Spring 引导微服务 (2.0.1.RELEASE) 中,如何使用 Spring 安全性或仅使用 HttpClient 来使用 clientId、clientSecret 和 grant_type 以在来自 REST 控制器层的每个 REST 调用(可能是 HTTP Post)中自动提供全局访问令牌?
谁能展示一个代码示例,说明如何使用 Spring 安全性或其他库来仅发送 clientId、clientSecret 和 grant_type 来获取 OAuth2 访问令牌?
如果 OAuth2 令牌过期怎么办(使用问题 # 2 中的库)?
1) 您不需要 spring 安全性。只需使用 'io.jsonwebtoken.Jwts'。 您可以使用任意数量的参数来生成 JWT 令牌。 您可以在 Spring 启动应用程序中使用一个组件来生成 JWT 令牌。
然后创建将使用此 bean 的令牌服务并执行:生成访问令牌、验证访问令牌并刷新令牌。
2) 样本 : @零件 public String createJwtToken(User user, TokenType type, ClientKey clientKey) 抛出 InvalidKeyException, NoSuchAlgorithmException, NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException {
String userName = user.getUsername();
Date currentTime = new Date();
String token = Jwts.builder()
.setSubject(userName)
.claim(Constants.NAME_KEY, Constants.NAME_VALUE)
.claim(Constants.USER_TOKEN_KEY, clientKey.getKey())
.claim(Constants.SCOPE_KEY, Constants.SCOPE_VALUE)
.claim(Constants.TOKEN_TYPE, type.name())
.setIssuer(tokenIssuer)
.setHeaderParam(Constants.TOKEN_TYP, Constants.TOKEN_JWT)
.setHeaderParam(Constants.TOKEN_TYPE, type.name())
.setIssuedAt(currentTime)
.setExpiration(timeout(type))
.signWith(SignatureAlgorithm.HS256, key)
.compact();
return encrypt(token);
}
3) 每当您第一次生成令牌时,您都会生成 2 个令牌:accessToken 和 Refresh Token。 AccessToken 是短暂的,很快就会过期。 - 比如说 5 分钟。 刷新令牌的有效期更长:例如:20 分钟。
刷新令牌的用途是您可以使用刷新令牌生成新的访问令牌。 因此,当您的访问令牌过期时,只需通过传递您的刷新令牌来调用刷新令牌方法。此方法应该 return 来自具有新访问令牌的 redis 用户。
此致,
R 莱
找到IBM开源提供的OAuth2Client:
https://www.ibm.com/developerworks/library/se-oauthjavapt1/index.html#download
此外,刚刚使用了 RestTemplate:
String accessToken = OAuth2Client.generateAccessToken();
RestTemplate restTemplate = new RestTemplate();
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
headers.set("Authorization", "Bearer "+accessToken);
HttpEntity<String> entity = new HttpEntity<String>(request,headers);
String response = restTemplate.postForObject(url, entity, String.class);
非常简单!