Spring Boot Social Login and Google Calendar API

Deadly 提交于 2020-07-23 07:14:39

问题


Problem

Reuse End-User Google Authentication via Spring Security OAuth2 to access Google Calendar API in Web Application

Description

I was able to create a small Spring Boot Web application with Login through Spring Security

application.yaml

spring:
  security:
    oauth2:
      client:
        registration:
          google:
            client-id: <id>
            client-secret: <secret>
            scope:
              - email
              - profile
              - https://www.googleapis.com/auth/calendar.readonly

When application starts I can access http://localhost:8080/user and user is asked for google login. After successful login profile json is shown in a browser as the response from:

SecurityController

@RestController
class SecurityController {
    @RequestMapping("/user")
    fun user(principal: Principal): Principal {
        return principal
    }
}

SecurityConfiguration.kt

@Configuration
class SecurityConfiguration : WebSecurityConfigurerAdapter() {
    @Throws(Exception::class)
    override fun configure(http: HttpSecurity) {
        http.authorizeRequests()
                .anyRequest().authenticated()
                .and()
                .oauth2Login()
    }
}

Question

I want to reuse this authentication to retrieve all user's Calendar Events. The following code is taken from google's tutorial on accessing calendar API but it creates a completely independent authorization flow and asks user to log in.

    @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")
    }

How can I reuse already done authentication to access end user's calendar events on Google account?


回答1:


If I understand correctly, what you mean be reusing the authentication is that you want to use the access and refresh tokens Spring retrieved for you in order to use them for requests against Google API.

The user authentication details can be injected into an endpoint method like this:

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
    }

}

With the details in OAuth2AuthorizedClient you should be able to do anything you need with the google API.

If you need to access the API without a user making a request to your service, you can inject OAuth2AuthorizedClientService into a managed component, and use it like this:

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
    }

}


来源:https://stackoverflow.com/questions/61316560/spring-boot-social-login-and-google-calendar-api

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!