我正在尝试使用google作为OAuth服务器来实现一个简单的Spring OAuth2资源服务器。
基本上,我一直在遵循像这样的指南spring-oauth2-with-google
application.yml:
spring:
security:
oauth2:
client:
registration:
google:
client-id: *******.apps.googleusercontent.com
client-secret:********_
scope:
- email
- profile
- openid
resourceserver:
jwt:
issuer-uri: https://accounts.google.com
jwk-set-uri: https://www.googleapis.com/oauth2/v3/certs
SecurityConfig.java:
@Configuration
public class SecurityConfig {
@Bean
protected SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.httpBasic().disable()
.formLogin(AbstractHttpConfigurer::disable)
.csrf(AbstractHttpConfigurer::disable)
.authorizeRequests(authorize -> authorize
.anyRequest().authenticated()
)
.oauth2ResourceServer(OAuth2ResourceServerConfigurer::jwt)
.sessionManagement(sessionManagement ->
sessionManagement.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
;
return http.build();
}
}
UserController.java
@RestController
@RequestMapping("/user")
@RequiredArgsConstructor
public class UserController {
@GetMapping("/{id}")
public void getUser(@PathVariable String id) {
System.out.println("Id: " + id);
}
}
我能够通过postman获得google JWT,如指南中所述,但无论我如何努力,当我试图通过postman使用我的端点时,响应总是401。我已经尝试在Bearer关键字和token_id之间设置一个空格。
Postman 出错:
Bearer error="invalid_token", error_description="Invalid token", error_uri="https://tools.ietf.org/html/rfc6750#section-3.1"
但是如果我查看google token info中的令牌,结果似乎还可以:
"issued_to": "263667859573-jve8vplquh7qn4ft7aaj1t1m9boaq5d6.apps.googleusercontent.com",
"audience": "263667859573-jve8vplquh7qn4ft7aaj1t1m9boaq5d6.apps.googleusercontent.com",
"user_id": "112897290372529438679",
"scope": "openid https://www.googleapis.com/auth/userinfo.profile https://www.googleapis.com/auth/userinfo.email",
"expires_in": 3296,
"email": "javier@email.com",
"verified_email": true,
"access_type": "online"
1条答案
按热度按时间hujrc8aj1#
也许,您从Google获得的访问令牌不是一个JWT,而是一个不透明的令牌,在这种情况下,使用JWT解码器配置资源服务器将不起作用。请尝试在https://jwt.io之类的工具中“打开”一个访问令牌,以确保安全。
我找不到这种Google不透明令牌的标准内省端点,只有https://www.googleapis.com/oauth2/v3/tokeninfo,您可以将
access_token
作为请求参数提交到https://www.googleapis.com/oauth2/v3/tokeninfo。(而不是JWT解码器),提供您自己的标记内部检查器来调用tokeninfo端点,检查响应并抛出异常或返回您选择的Authentication
。但这是相当多的工作,而且内省的效率远远低于解码JWT(首先需要为资源服务器上的每个传入请求向Google提交令牌,而对所有请求只获取一次公钥就足以满足第二次请求)。
很可能Google只是不想让我们使用他们的授权服务器作为我们自己的资源服务器,除了少数有限的情况(我不确定是哪些)。
另一种选择是使用另一个能够联合“社交”身份的授权服务器(当然是Google,还有Facebook、Github等)。Keycloak是一个著名的内部部署解决方案,但是如果你不想自己维护授权服务器,你可以看看像Auth0这样的SaaS(它有一个免费的层)。这两个只是我目前在一系列解决方案中的首选,只需搜索“OIDC授权服务器”,然后选择你自己的。