Sign in users via Facebook and sign up new users automatically part-04
authorKai Moritz <kai@juplo.de>
Mon, 25 Jan 2016 01:18:47 +0000 (02:18 +0100)
committerKai Moritz <kai@juplo.de>
Mon, 1 Feb 2016 06:11:26 +0000 (07:11 +0100)
src/main/java/de/juplo/yourshouter/HomeController.java
src/main/java/de/juplo/yourshouter/SocialConfig.java
src/main/java/de/juplo/yourshouter/UserCookieSignInAdapter.java [new file with mode: 0644]
src/main/java/de/juplo/yourshouter/WebMvcConfig.java
src/main/webapp/thymeleaf/signin.html [new file with mode: 0644]

index bb371f4..c5ece60 100644 (file)
@@ -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();
index 2abcd42..ff69151 100644 (file)
@@ -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 <code>facebook</code>, 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 (file)
index 0000000..ed1a8d5
--- /dev/null
@@ -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 <code>null</code>, 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;
+  }
+}
index e5c6d6f..6676ae6 100644 (file)
@@ -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 (file)
index 0000000..687d7f4
--- /dev/null
@@ -0,0 +1,12 @@
+<!DOCTYPE html>
+<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org">
+  <head>
+    <title>Sign In</title>
+  </head>
+  <body>
+    <form action="#" th:action="@{/signin/facebook}" method="POST">
+      <input type="hidden" name="scope" value="public_profile,manage_pages" />
+      <button type="submit">Sign in with Facebook</button>
+    </form>
+  </body>
+</html>