问题
通过 Spring Security OAuth2 重用最终用户 Google 身份验证以在 Web 应用程序中访问 Google Calendar API
描述
我能够通过 Spring Security 创建一个带有登录的小型 Spring Boot Web 应用程序
应用程序.yaml
spring:
security:
oauth2:
client:
registration:
google:
client-id: <id>
client-secret: <secret>
scope:
- email
- profile
- https://www.googleapis.com/auth/calendar.readonly
当应用程序启动时,我可以访问 http://localhost:8080/user并要求用户进行谷歌登录。成功登录后,配置文件 json 显示在浏览器中作为来自以下内容的响应:
安全 Controller
@RestController
class SecurityController {
@RequestMapping("/user")
fun user(principal: Principal): Principal {
return principal
}
}
安全配置.kt
@Configuration
class SecurityConfiguration : WebSecurityConfigurerAdapter() {
@Throws(Exception::class)
override fun configure(http: HttpSecurity) {
http.authorizeRequests()
.anyRequest().authenticated()
.and()
.oauth2Login()
}
}
问题
我想重新使用此身份验证来检索所有用户的日历事件。以下代码取自谷歌关于访问日历 API 的教程,但它创建了一个完全独立的授权流程并要求用户登录。
@Throws(IOException::class)
private fun getCredentials(httpTransport: NetHttpTransport): Credential {
val clientSecrets = loadClientSecrets()
return triggerUserAuthorization(httpTransport, clientSecrets)
}
private fun loadClientSecrets(): GoogleClientSecrets {
val `in` = CalendarQuickstart::class.java.getResourceAsStream(CREDENTIALS_FILE_PATH)
?: throw FileNotFoundException("Resource not found: $CREDENTIALS_FILE_PATH")
return GoogleClientSecrets.load(JSON_FACTORY, InputStreamReader(`in`))
}
private fun triggerUserAuthorization(httpTransport: NetHttpTransport, clientSecrets: GoogleClientSecrets): Credential {
val flow = GoogleAuthorizationCodeFlow.Builder(
httpTransport, JSON_FACTORY, clientSecrets, SCOPES)
.setDataStoreFactory(FileDataStoreFactory(File(TOKENS_DIRECTORY_PATH)))
.setAccessType("offline")
.build()
val receiver = LocalServerReceiver.Builder().setPort(8880).build()
return AuthorizationCodeInstalledApp(flow, receiver).authorize("user")
}
如何重复使用已完成的身份验证来访问最终用户在 Google 帐户上的日历事件?
最佳答案
如果我理解正确,你的意思是重用身份验证是你想使用 Spring 为你检索的访问和刷新 token ,以便将它们用于针对 Google API 的请求。
用户身份验证详细信息可以像这样注入(inject)到端点方法中:
import org.springframework.security.oauth2.client.OAuth2AuthorizedClient
import org.springframework.security.oauth2.client.annotation.RegisteredOAuth2AuthorizedClient
import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.bind.annotation.RestController
@RestController
class FooController(val historyService: HistoryService) {
@GetMapping("/foo")
fun foo(@RegisteredOAuth2AuthorizedClient("google") user: OAuth2AuthorizedClient) {
user.accessToken
}
}
有了 OAuth2AuthorizedClient
中的详细信息,您应该能够使用 google API 做任何您需要的事情。
如果您需要在没有用户向您的服务发出请求的情况下访问 API,您可以将 OAuth2AuthorizedClientService
注入(inject)托管组件,并像这样使用它:
import org.springframework.security.oauth2.client.OAuth2AuthorizedClient
import org.springframework.security.oauth2.client.OAuth2AuthorizedClientService
import org.springframework.stereotype.Service
@Service
class FooService(val clientService: OAuth2AuthorizedClientService) {
fun foo() {
val user = clientService.loadAuthorizedClient<OAuth2AuthorizedClient>("google", "principal-name")
user.accessToken
}
}
关于spring-boot - Spring Boot 社交登录和 Google Calendar API,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61316560/