Use access token from Keycloak social login to consume Google API in Java
I have 2 pieces of code I want to integrate.
- I have a working Google API (Youtube) integration that gets some user related information using the correct scopes while asking for authentication.
public YouTube getService() throws GeneralSecurityException, IOException {
final NetHttpTransport httpTransport = GoogleNetHttpTransport.newTrustedTransport();
return new YouTube.Builder(httpTransport, JSON_FACTORY, getCredent开发者_StackOverflowials())
.setApplicationName(APPLICATION_NAME)
.build();
}
private Credential getCredentials() throws IOException {
// With the GoogleAuthorizationCodeFlow you can create a Credential
Credential credential = authorizationCodeFlow.loadCredential(userService.getUserWithAuthorities().get().getId().toString());
if (credential == null) {
GoogleAuthorizationCodeRequestUrl authorizationUrl = authorizationCodeFlow.newAuthorizationUrl();
Map<String, String> state = Map.of("userId", userService.getUserWithAuthorities().get().getId().toString());
authorizationUrl.setState(new ObjectMapper().writeValueAsString(state));
authorizationUrl.setRedirectUri(CALLBACK_URL);
System.out.println("REDIRECTURL: " + authorizationUrl); //ToDo: remove
throw new YtUnauthorizedException(authorizationUrl.toString());
}
return credential;
}
- I have a spring security / keycloack integration with social login using jhipster generated code.
Now I want to use the Google API code with the access token from Spring Security / Keycloak but none of the options I tried worked.
Following this article I tried this code:
GoogleCredential credential = new GoogleCredential().setAccessToken(getAccessToken());
private String getAccessToken(){
Authentication authentication =
SecurityContextHolder
.getContext()
.getAuthentication();
OAuth2AuthenticationToken oauthToken =
(OAuth2AuthenticationToken) authentication;
OAuth2AuthorizedClient client =
clientService.loadAuthorizedClient(
oauthToken.getAuthorizedClientRegistrationId(),
oauthToken.getName());
return client.getAccessToken().getTokenValue();
}
But it doesn't work. I suspect I'm getting the access token of Keycloak but not Google. Any idea how I can use Google API with this setup?
Google does not know about your Keycloak instance and won't accept the access-tokens it emitted.
When you "login with Google" against a Keycloak instance, it checks an ID token emitted by Google and creates its own set of tokens (access, refresh and ID). Just open one of this tokens in https://jwt.io (or introspect it if it is opaque) and check the iss
and aud
claim values. This new tokens are to be used on your own applications (ID & refresh on clients, access on resource-servers), not on Google API.
To query Google API, two cases:
- the request is not done on behalf of a specific user (you registered a Google client app that sends requests in its own name) => configure the REST client in your back-end with client-credentials so that it gets a fresh access-token before emitting requests to Google
- the request is made on behalf of the end-user => you need an access-token for that user => request it from your client app (this could even be silent as your user already identified against Google) and send the request from the client directly or send Google access-token in a request body to your resource-server so that it can set its own request to with this "Google" token as authorization header
精彩评论