From 1c7204ab3dd581b0809cf436120adcb975b96cf2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=9Cmit=20Seren?= Date: Mon, 25 Oct 2021 20:39:46 +0200 Subject: [PATCH] Bugfix: Implement workaround for http issue with google auth Inject a custom GoogleOauth2Template that replaces http with https. This is required due to recent change in Google OAUTH2 which requires https for non localhost redirect urls. Spring security social > 2.x would make this workaround obsolete as it detects that the app is running behind a proxy that does TLS termination. --- .../security/GoogleConnectionFactory.java | 38 +++++++++++ .../security/GoogleOAuth2TemplateWrapper.java | 68 +++++++++++++++++++ .../main/resources/META-INF/spring-social.xml | 7 ++ 3 files changed, 113 insertions(+) create mode 100644 src/genophenbrowser-server/src/main/java/com/gmi/nordborglab/browser/server/security/GoogleConnectionFactory.java create mode 100644 src/genophenbrowser-server/src/main/java/com/gmi/nordborglab/browser/server/security/GoogleOAuth2TemplateWrapper.java diff --git a/src/genophenbrowser-server/src/main/java/com/gmi/nordborglab/browser/server/security/GoogleConnectionFactory.java b/src/genophenbrowser-server/src/main/java/com/gmi/nordborglab/browser/server/security/GoogleConnectionFactory.java new file mode 100644 index 00000000..c5e8021b --- /dev/null +++ b/src/genophenbrowser-server/src/main/java/com/gmi/nordborglab/browser/server/security/GoogleConnectionFactory.java @@ -0,0 +1,38 @@ +package com.gmi.nordborglab.browser.server.security; + +import org.springframework.social.connect.UserProfile; +import org.springframework.social.connect.support.OAuth2ConnectionFactory; +import org.springframework.social.google.api.Google; +import org.springframework.social.google.connect.GoogleAdapter; +import org.springframework.social.google.connect.GoogleOAuth2Template; +import org.springframework.social.google.connect.GoogleServiceProvider; +import org.springframework.social.oauth2.AccessGrant; +import org.springframework.social.oauth2.OAuth2Operations; + +/** + * Custom Google ConnectionFactory implementation to workround https://jira.spring.io/browse/SOCIAL-447. + * + * + * @author Uemit Seren + */ +public class GoogleConnectionFactory extends OAuth2ConnectionFactory { + + private final GoogleOAuth2TemplateWrapper oauth2Template; + + public GoogleConnectionFactory(final String clientId, final String clientSecret) { + super("google", new GoogleServiceProvider(clientId, clientSecret), + new GoogleAdapter()); + oauth2Template = new GoogleOAuth2TemplateWrapper(new GoogleOAuth2Template(clientId, clientSecret)); + } + + public OAuth2Operations getOAuthOperations() { + return oauth2Template; + } + + @Override + protected String extractProviderUserId(final AccessGrant accessGrant) { + final Google api = ((GoogleServiceProvider) getServiceProvider()).getApi(accessGrant.getAccessToken()); + final UserProfile userProfile = getApiAdapter().fetchUserProfile(api); + return userProfile.getUsername(); + } +} \ No newline at end of file diff --git a/src/genophenbrowser-server/src/main/java/com/gmi/nordborglab/browser/server/security/GoogleOAuth2TemplateWrapper.java b/src/genophenbrowser-server/src/main/java/com/gmi/nordborglab/browser/server/security/GoogleOAuth2TemplateWrapper.java new file mode 100644 index 00000000..9f6fc6ba --- /dev/null +++ b/src/genophenbrowser-server/src/main/java/com/gmi/nordborglab/browser/server/security/GoogleOAuth2TemplateWrapper.java @@ -0,0 +1,68 @@ +package com.gmi.nordborglab.browser.server.security; + +import org.springframework.social.oauth2.AccessGrant; +import org.springframework.social.oauth2.GrantType; +import org.springframework.social.oauth2.OAuth2Operations; +import org.springframework.social.oauth2.OAuth2Parameters; +import org.springframework.util.MultiValueMap; + +public class GoogleOAuth2TemplateWrapper implements OAuth2Operations{ + + private final OAuth2Operations oauth2Template; + + public GoogleOAuth2TemplateWrapper(OAuth2Operations oauth2Template) { + this.oauth2Template = oauth2Template; + } + private OAuth2Parameters fixRedirectUrl(OAuth2Parameters parameters) { + String redirectUrl = parameters.getRedirectUri(); + if (redirectUrl.contains("http") && !redirectUrl.contains("localhost")) { + redirectUrl = redirectUrl.replace("http", "https"); + } + parameters.setRedirectUri(redirectUrl); + return parameters; + } + + @Override + public String buildAuthorizeUrl(OAuth2Parameters parameters) { + return oauth2Template.buildAuthorizeUrl(fixRedirectUrl(parameters)); + } + @Override + public String buildAuthorizeUrl(GrantType grantType, OAuth2Parameters parameters) { + return oauth2Template.buildAuthorizeUrl(grantType, fixRedirectUrl(parameters)); + } + @Override + public String buildAuthenticateUrl(OAuth2Parameters parameters) { + return oauth2Template.buildAuthenticateUrl(fixRedirectUrl(parameters)); + } + @Override + public String buildAuthenticateUrl(GrantType grantType, OAuth2Parameters parameters) { + return oauth2Template.buildAuthenticateUrl(grantType, fixRedirectUrl(parameters)); + } + @Override + public AccessGrant exchangeForAccess(String authorizationCode, String redirectUri, + MultiValueMap additionalParameters) { + return oauth2Template.exchangeForAccess(authorizationCode, redirectUri, additionalParameters); + } + @Override + public AccessGrant exchangeCredentialsForAccess(String username, String password, + MultiValueMap additionalParameters) { + return oauth2Template.exchangeCredentialsForAccess(username, password, additionalParameters); + } + @Override + public AccessGrant refreshAccess(String refreshToken, String scope, + MultiValueMap additionalParameters) { + return oauth2Template.refreshAccess(refreshToken, scope, additionalParameters); + } + @Override + public AccessGrant refreshAccess(String refreshToken, MultiValueMap additionalParameters) { + return oauth2Template.refreshAccess(refreshToken, additionalParameters); + } + @Override + public AccessGrant authenticateClient() { + return oauth2Template.authenticateClient(); + } + @Override + public AccessGrant authenticateClient(String scope) { + return oauth2Template.authenticateClient(scope); + } +} \ No newline at end of file diff --git a/src/genophenbrowser-server/src/main/resources/META-INF/spring-social.xml b/src/genophenbrowser-server/src/main/resources/META-INF/spring-social.xml index d1fbeeb2..23b9807a 100644 --- a/src/genophenbrowser-server/src/main/resources/META-INF/spring-social.xml +++ b/src/genophenbrowser-server/src/main/resources/META-INF/spring-social.xml @@ -74,6 +74,13 @@ + + + + + +