Вход в социальную сеть Spring Boot и API Календаря Google - PullRequest
1 голос
/ 20 апреля 2020

Проблема

Повторное использование аутентификации Google для конечного пользователя через Spring Security OAuth2 для доступа к API Календаря Google в веб-приложении

Описание

Мне удалось создать небольшую загрузку Spring Веб-приложение с входом через 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

При запуске приложения я могу получить доступ к http://localhost: 8080 / user , и у пользователя запрашивается Google авторизоваться. После успешного входа в систему профиль json отображается в браузере как ответ от:

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()
    }
}

Вопрос

Я хочу использовать эту аутентификацию для получения всех событий календаря пользователя. Следующий код взят из руководства Google по доступу к календарному 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")
    }

Как повторно использовать уже выполненную аутентификацию для доступа к событиям календаря конечного пользователя в Гугл аккаунт?

1 Ответ

2 голосов
/ 22 апреля 2020

Если я правильно понимаю, вы имеете в виду повторное использование аутентификации: вы хотите использовать права доступа и повторно получить sh токены, полученные Spring для вас, чтобы использовать их для запросов к Google API.

Данные аутентификации пользователя могут быть введены в метод конечной точки следующим образом:

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 вы сможете делать все, что вам нужно, с помощью API Google.

Если вам нужно получить доступ к API без запроса пользователем вашего сервиса, вы можете добавить OAuth2AuthorizedClientService в управляемый компонент и использовать его следующим образом:

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
    }

}
...