Skip to content

Instantly share code, notes, and snippets.

@ruddell
Last active January 13, 2018 04:12
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ruddell/4d003c7d8035268d34b8e842a338c979 to your computer and use it in GitHub Desktop.
Save ruddell/4d003c7d8035268d34b8e842a338c979 to your computer and use it in GitHub Desktop.
WIP Ignite JHipster Social Login Support
package com.mycompany.myapp.web.rest;
import com.mycompany.myapp.config.Constants;
import com.mycompany.myapp.service.SocialService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.ResponseEntity;
import org.springframework.social.connect.Connection;
import org.springframework.social.connect.ConnectionFactoryLocator;
import org.springframework.social.connect.UserProfile;
import org.springframework.social.connect.web.ProviderSignInUtils;
import org.springframework.social.facebook.api.Facebook;
import org.springframework.social.facebook.connect.FacebookConnectionFactory;
import org.springframework.social.google.api.Google;
import org.springframework.social.google.connect.GoogleConnectionFactory;
import org.springframework.social.oauth1.OAuthToken;
import org.springframework.social.oauth2.AccessGrant;
import org.springframework.social.support.URIBuilder;
import org.springframework.social.twitter.api.Twitter;
import org.springframework.social.twitter.connect.TwitterConnectionFactory;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.context.request.WebRequest;
import org.springframework.web.servlet.view.RedirectView;
@RestController
@RequestMapping("/social")
public class SocialController {
private final Logger log = LoggerFactory.getLogger(SocialController.class);
private final SocialService socialService;
private final ProviderSignInUtils providerSignInUtils;
private final ConnectionFactoryLocator connectionFactoryLocator;
public SocialController(SocialService socialService, ProviderSignInUtils providerSignInUtils, ConnectionFactoryLocator connectionFactoryLocator) {
this.socialService = socialService;
this.providerSignInUtils = providerSignInUtils;
this.connectionFactoryLocator = connectionFactoryLocator;
}
@GetMapping("/signup")
public RedirectView signUp(WebRequest webRequest, @CookieValue(name = "NG_TRANSLATE_LANG_KEY", required = false, defaultValue = Constants.DEFAULT_LANGUAGE) String langKey) {
try {
Connection<?> connection = providerSignInUtils.getConnectionFromSession(webRequest);
socialService.createSocialUser(connection, langKey.replace("\"", ""));
return new RedirectView(URIBuilder.fromUri("/#/social-register/" + connection.getKey().getProviderId())
.queryParam("success", "true")
.build().toString(), true);
} catch (Exception e) {
log.error("Exception creating social user: ", e);
return new RedirectView(URIBuilder.fromUri("/#/social-register/no-provider")
.queryParam("success", "false")
.build().toString(), true);
}
}
@PostMapping(value = "/token")
public ResponseEntity loadConnectionFromToken(@RequestParam String token, @RequestParam String secret, @RequestParam String provider) {
log.info("Provider: {}", provider);
log.info("Token: {}", token);
log.info("Secret: {}", secret);
UserProfile userProfile = null;
if ("facebook".equals(provider)) {
AccessGrant accessGrant = new AccessGrant(token);
Connection<Facebook> connection = ((FacebookConnectionFactory)connectionFactoryLocator.getConnectionFactory(provider)).createConnection(accessGrant);
userProfile = connection.fetchUserProfile();
log.info(String.valueOf(userProfile));
} else if ("twitter".equals(provider)) {
OAuthToken oAuthToken = new OAuthToken(token, secret);
Connection<Twitter> connection = ((TwitterConnectionFactory)connectionFactoryLocator.getConnectionFactory("twitter")).createConnection(oAuthToken);
userProfile = connection.fetchUserProfile();
log.info(String.valueOf(userProfile));
} else if ("google".equals(provider)) {
AccessGrant accessGrant = new AccessGrant(token);
Connection<Google> connection = ((GoogleConnectionFactory)connectionFactoryLocator.getConnectionFactory(provider)).createConnection(accessGrant);
userProfile = connection.fetchUserProfile();
log.info(String.valueOf(userProfile));
}
// TODO SAVE THE CONNECTION
return ResponseEntity.ok().body(userProfile);
}
}
@rakeshkalra1983
Copy link

rakeshkalra1983 commented Dec 4, 2017

Hi @ruddell, was wondering that if RequestParam secret, which is passed to /token api on line 60 can be stored in Jhipster server application.yml only instead of passing it over network?
Was worried about security and exposing the client secret to anyone.

What are your thoughts?

@ruddell
Copy link
Author

ruddell commented Dec 5, 2017

If the secret was stored in application.yml, the client would still need to request it at some point. My thoughts are the same as this comment from a discussion in react-native-oauth

Although the consumer secret is technically a password, it doesn't provide access to anything valuable enough to make decompiling worthwhile. You can't post tweets or access private data, and you can't use it to obtain user tokens due to the fixed callback URL.

The other option is somehow configuring Spring Social to use our existing social keys, I'm not sure how to do this. I plan on investigating this route

@ruddell
Copy link
Author

ruddell commented Jan 13, 2018

Looked into it a little tonight, I think react-native-simple-auth is the library to use. It functions the same as react-native-oauth but doesn't require Google or Facebook secrets, Twitter's secret is still needed (OAuth v1)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment