我正在尝试为我的宠物项目实现“使用谷歌登录”授权。我决定首先练习一个小项目,因此我创建了一个仅包含一个控制器的简单 REST 应用程序。我设法完成了在谷歌控制台中创建项目的所有步骤,在那里创建了所有必要的密钥,并成功地将谷歌令牌放入邮递员标头中。看起来像这样
ya29.A0AVA9y1v0OZNHTtELFgP-OGQdT_GY_V9mJ3FKXB2ZcOYjS7_AWx2nX1IzP8Sfnr9uxosNZNyNZK2h_q4zF1Qvhhu2bptv-tL-kSn3qVjHwfDdjqIydn3bKBkqVhIHKhmCE3PLrXuSuDJ2sML-66uFFwR28IpyaCgYKATASATASFQE65dr8xXC0Q6jWHExbZ0yL0utlKw0163
所以我开始实现spring boot应用程序并遇到了一些问题。我按照网络上的教程配置了 spring security,将所有客户端 ID 和所有这些内容放入 application.properties 中并运行我的应用程序。令人惊讶的是,没有任何作用。我开始挖掘并发现 JwtAuthenticationProvider 抱怨他“
Failed to authenticate since the JWT was invalid
”。经过一番谷歌搜索后,我发现谷歌所谓的“access_token”并不是真正的 JWT 令牌,但我不知道如何处理这些信息。我一定错过了一些重要的东西,但我不知道是什么。
我的 SpringSecurityConfig:
@Configuration
@EnableWebSecurity(debug = true)
@EnableGlobalMethodSecurity(prePostEnabled = true)
class SpringSecurityConfig {
@Bean
fun filterChain(http: HttpSecurity): SecurityFilterChain {
http
.authorizeRequests()
.antMatchers("/**").fullyAuthenticated()
.and()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.oauth2ResourceServer().jwt()
.and()
.and()
.cors().and().csrf().disable()
return http.build()
}
}
我的财产:
spring.security.oauth2.client.registration.google.client-id=<MY_CLIENT_ACTUAL_VALUE>
spring.security.oauth2.client.registration.google.client-secret=<MY_SECRET_ACTUAL_VALUE>
spring.security.oauth2.client.registration.google.scope=openid,profile,email
spring.security.oauth2.resourceserver.jwt.issuer-uri=https://accounts.google.com
spring.security.oauth2.resourceserver.jwt.jwk-set-uri=https://www.googleapis.com/oauth2/v3/certs
我的控制器:
@RestController
@RequestMapping("/api")
class TestController {
@GetMapping(path = ["/alive"])
private fun alive() = "OK"
}
在我尝试使用令牌标头与邮递员连接后,我得到以下信息:
************************************************************
Request received for GET '/api/alive':
org.apache.catalina.connector.RequestFacade@51219c91
servletPath:/api/alive
pathInfo:null
headers:
authorization: Bearer ya29.A0AVA9y1v0OZNHTtELFgP-OGQdT_GY_V9mJ3FKXB2ZcOYjS7_AWx2nX1IzP8Sfnr9uxosNZNyNZK2h_q4zF1Qvhhu2bptv-tL-kSn3qVjHwfDdjqIydn3bKBkqVhIHKhmCE3PLrXuSuDJ2sML-66uFFwR28IpyaCgYKATASATASFQE65dr8xXC0Q6jWHExbZ0yL0utlKw0163
user-agent: PostmanRuntime/7.29.2
accept: */*
postman-token: b6dd2ef8-a4e5-46bf-8d62-141831146efb
host: localhost:8080
accept-encoding: gzip, deflate, br
connection: keep-alive
cookie: JSESSIONID=715201B0645DD1329566CD5AB8509BE6
Security filter chain: [
DisableEncodeUrlFilter
WebAsyncManagerIntegrationFilter
SecurityContextPersistenceFilter
HeaderWriterFilter
CorsFilter
LogoutFilter
BearerTokenAuthenticationFilter
RequestCacheAwareFilter
SecurityContextHolderAwareRequestFilter
AnonymousAuthenticationFilter
SessionManagementFilter
ExceptionTranslationFilter
FilterSecurityInterceptor
]
************************************************************
2022-08-19 17:07:29,005 DEBUG [http-nio-8080-exec-1] org.springframework.security.web.FilterChainProxy: Securing GET /api/alive
2022-08-19 17:07:29,009 DEBUG [http-nio-8080-exec-1] org.springframework.security.web.context.SecurityContextPersistenceFilter: Set SecurityContextHolder to empty SecurityContext
2022-08-19 17:07:29,031 DEBUG [http-nio-8080-exec-1] org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationProvider: Failed to authenticate since the JWT was invalid
2022-08-19 17:07:29,033 DEBUG [http-nio-8080-exec-1] org.springframework.security.web.context.SecurityContextPersistenceFilter: Cleared SecurityContextHolder to complete request
您应该将 id_token 发送到服务器(这是一个有效的 JWT),而不是 access_token (这不是)。