Skip to content

Commit

Permalink
Bugfix: Implement workaround for http issue with google auth
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
timeu committed Oct 25, 2021
1 parent 4ce386e commit 1c7204a
Show file tree
Hide file tree
Showing 3 changed files with 113 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -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<Google> {

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();
}
}
Original file line number Diff line number Diff line change
@@ -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<String, String> additionalParameters) {
return oauth2Template.exchangeForAccess(authorizationCode, redirectUri, additionalParameters);
}
@Override
public AccessGrant exchangeCredentialsForAccess(String username, String password,
MultiValueMap<String, String> additionalParameters) {
return oauth2Template.exchangeCredentialsForAccess(username, password, additionalParameters);
}
@Override
public AccessGrant refreshAccess(String refreshToken, String scope,
MultiValueMap<String, String> additionalParameters) {
return oauth2Template.refreshAccess(refreshToken, scope, additionalParameters);
}
@Override
public AccessGrant refreshAccess(String refreshToken, MultiValueMap<String, String> additionalParameters) {
return oauth2Template.refreshAccess(refreshToken, additionalParameters);
}
@Override
public AccessGrant authenticateClient() {
return oauth2Template.authenticateClient();
}
@Override
public AccessGrant authenticateClient(String scope) {
return oauth2Template.authenticateClient(scope);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,13 @@
<constructor-arg value="${google.clientId}"/>
<constructor-arg value="${google.clientSecret}"/>
<property name="defaultScope" value="email"/>
<property name="connectionFactory">
<bean id = "customGoogleConnectionFactory"
class="com.gmi.nordborglab.browser.server.security.GoogleConnectionFactory">
<constructor-arg value="${google.clientId}"/>
<constructor-arg value="${google.clientSecret}"/>
</bean>
</property>
</bean>
<bean class="org.springframework.social.github.security.GitHubAuthenticationService">
<constructor-arg value="${github.clientId}"/>
Expand Down

0 comments on commit 1c7204a

Please sign in to comment.