Spring Security Spring OAuth2资源服务器与Google授权服务器

py49o6xq  于 2022-11-24  发布在  Spring
关注(0)|答案(1)|浏览(241)

我正在尝试使用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"
hujrc8aj

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

http.oauth2ResourceServer().opaqueToken().introspector(...);

但这是相当多的工作,而且内省的效率远远低于解码JWT(首先需要为资源服务器上的每个传入请求向Google提交令牌,而对所有请求只获取一次公钥就足以满足第二次请求)。
很可能Google只是不想让我们使用他们的授权服务器作为我们自己的资源服务器,除了少数有限的情况(我不确定是哪些)。
另一种选择是使用另一个能够联合“社交”身份的授权服务器(当然是Google,还有Facebook、Github等)。Keycloak是一个著名的内部部署解决方案,但是如果你不想自己维护授权服务器,你可以看看像Auth0这样的SaaS(它有一个免费的层)。这两个只是我目前在一系列解决方案中的首选,只需搜索“OIDC授权服务器”,然后选择你自己的。

相关问题