From a1ad44fc308e479f9a005aa2d87cb604d6eb0e7d Mon Sep 17 00:00:00 2001 From: Kai Moritz Date: Mon, 25 Jan 2016 02:18:47 +0100 Subject: [PATCH] Sign in users via Facebook and sign up new users automatically --- .../de/juplo/yourshouter/HomeController.java | 4 +- .../de/juplo/yourshouter/SocialConfig.java | 25 +++++++ .../yourshouter/UserCookieSignInAdapter.java | 66 +++++++++++++++++++ .../de/juplo/yourshouter/WebMvcConfig.java | 11 ++++ src/main/webapp/thymeleaf/signin.html | 12 ++++ 5 files changed, 116 insertions(+), 2 deletions(-) create mode 100644 src/main/java/de/juplo/yourshouter/UserCookieSignInAdapter.java create mode 100644 src/main/webapp/thymeleaf/signin.html diff --git a/src/main/java/de/juplo/yourshouter/HomeController.java b/src/main/java/de/juplo/yourshouter/HomeController.java index bb371f4..c5ece60 100644 --- a/src/main/java/de/juplo/yourshouter/HomeController.java +++ b/src/main/java/de/juplo/yourshouter/HomeController.java @@ -49,8 +49,8 @@ public class HomeController } if (!authorized) { - LOG.info("no authorized user, redirecting to /connect/facebook"); - return "redirect:/connect/facebook"; + LOG.info("no authorized user, redirecting to /signin.html"); + return "redirect:/signin.html"; } User user = facebook.userOperations().getUserProfile(); diff --git a/src/main/java/de/juplo/yourshouter/SocialConfig.java b/src/main/java/de/juplo/yourshouter/SocialConfig.java index 2abcd42..ff69151 100644 --- a/src/main/java/de/juplo/yourshouter/SocialConfig.java +++ b/src/main/java/de/juplo/yourshouter/SocialConfig.java @@ -17,6 +17,8 @@ import org.springframework.social.connect.ConnectionRepository; import org.springframework.social.connect.UsersConnectionRepository; import org.springframework.social.connect.mem.InMemoryUsersConnectionRepository; import org.springframework.social.connect.web.ConnectController; +import org.springframework.social.connect.web.ProviderSignInController; +import org.springframework.social.connect.web.SignInAdapter; import org.springframework.social.facebook.api.Facebook; import org.springframework.social.facebook.connect.FacebookConnectionFactory; @@ -116,6 +118,29 @@ public class SocialConfig extends SocialConfigurerAdapter return controller; } + /** + * Configure the {@link ProviderSignInController} to use our implementation + * of {@link SignInAdapter} to sign in the user by storing the ID in the + * {@link SecurityContext} and the user-cookie. + * + * @param factoryLocator The {@link ConnectionFactoryLocator} will be injected by Spring. + * @param repository The {@link UserConnectionRepository} will be injected by Spring. + * @return The configured {@link ProviderSignInController} + */ + @Bean + public ProviderSignInController signInController( + ConnectionFactoryLocator factoryLocator, + UsersConnectionRepository repository + ) + { + ProviderSignInController controller = new ProviderSignInController( + factoryLocator, + repository, + new UserCookieSignInAdapter() + ); + return controller; + } + /** * Configure a scoped bean named facebook, that enables * access to the Graph-API in the name of the current user. diff --git a/src/main/java/de/juplo/yourshouter/UserCookieSignInAdapter.java b/src/main/java/de/juplo/yourshouter/UserCookieSignInAdapter.java new file mode 100644 index 0000000..ed1a8d5 --- /dev/null +++ b/src/main/java/de/juplo/yourshouter/UserCookieSignInAdapter.java @@ -0,0 +1,66 @@ +package de.juplo.yourshouter; + +import javax.servlet.http.HttpServletResponse; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.social.connect.Connection; +import org.springframework.social.connect.web.SignInAdapter; +import org.springframework.web.context.request.NativeWebRequest; + + +/** + * Simple implementation of {@link SignInAdapter}. + * + * We configured Spring-Social to call this implementation, to sign in the + * user, after he was authenticated by Facebook. + * + * @author Kai Moritz + */ +public class UserCookieSignInAdapter implements SignInAdapter +{ + private final static Logger LOG = + LoggerFactory.getLogger(UserCookieSignInAdapter.class); + + + /** + * Stores the user in the security-context to sign him in. + * Also remembers the user for subsequent calls by storing the ID in the + * cookie. + * + * @param user + * The user-ID. We configured Spring-Social to call + * {@link UserCookieSignInAdapter} to extract a user-ID from the + * connection. + * @param connection + * The connection. In our case a connection to Facebook. + * @param request + * The actual request. We need it, to store the cookie. + * @return + * We return null, to indicate, that the user should be + * redirected to the default-post-sign-in-URL (configured in + * {@link ProviderSinInController}) after a successfull authentication. + * + * @see {@link UserCookieSignInAdapter} + * @see {@link ProviderSignInController#postSignInUrl} + */ + @Override + public String signIn( + String user, + Connection connection, + NativeWebRequest request + ) + { + LOG.info( + "signing in user {} (connected via {})", + user, + connection.getKey().getProviderId() + ); + SecurityContext.setCurrentUser(user); + UserCookieGenerator + .INSTANCE + .addCookie(user, request.getNativeResponse(HttpServletResponse.class)); + + // We return null to trigger a redirect to "/". + return null; + } +} diff --git a/src/main/java/de/juplo/yourshouter/WebMvcConfig.java b/src/main/java/de/juplo/yourshouter/WebMvcConfig.java index e5c6d6f..6676ae6 100644 --- a/src/main/java/de/juplo/yourshouter/WebMvcConfig.java +++ b/src/main/java/de/juplo/yourshouter/WebMvcConfig.java @@ -8,6 +8,7 @@ import org.springframework.context.annotation.Configuration; import org.springframework.social.connect.UsersConnectionRepository; import org.springframework.web.servlet.config.annotation.EnableWebMvc; import org.springframework.web.servlet.config.annotation.InterceptorRegistry; +import org.springframework.web.servlet.config.annotation.ViewControllerRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; @@ -37,4 +38,14 @@ public class WebMvcConfig extends WebMvcConfigurerAdapter { registry.addInterceptor(new UserCookieInterceptor(usersConnectionRepository)); } + + /** + * {@inheritDoc} + */ + @Override + public void addViewControllers(ViewControllerRegistry registry) + { + // Configure the view /thymeleaf/signin.html for the path /signin.html + registry.addViewController("/signin.html"); + } } diff --git a/src/main/webapp/thymeleaf/signin.html b/src/main/webapp/thymeleaf/signin.html new file mode 100644 index 0000000..687d7f4 --- /dev/null +++ b/src/main/webapp/thymeleaf/signin.html @@ -0,0 +1,12 @@ + + + + Sign In + + +
+ + +
+ + -- 2.20.1