Develop a Facebook-App with Spring-Social – Part V: Refactor The Redirect-Logic

In this series of Mini-How-Tow’s I will describe how to develop a facebook app with the help of Spring-Social

In the last part of this series, we reconfigured our app, so that users are signed in after an authentication against Facebook and new users are signed up automatically on the first visit.

In this part, we will refactor our redirect-logic for unauthenticated users, so that it more closely resembles the behavior of Spring Social, hence, easing the planed switch to that technology in a feature step.

The Source is With You

You can find the source-code on http://juplo.de/git/examples/facebook-app/ and browse it via gitweb. Check out part-05 to get the source for this part of the series.

Mimic Spring Security

To stress that again: our simple authentication-concept is only meant for educational purposes. It is inherently insecure! We are not refining it here, to make it better or more secure. We are refining it, so that it can be replaced with Spring Security later on, without a hassle!

In our current implementation, a user, who is not yet authenticated, would be redirected to our sign-in-page only, if he visits the root of our webapp (/). To move all redirect-logic out of HomeController and redirect unauthenicated users from all pages to our sign-in-page, we can simply modify our interceptor UserCookieInterceptor, which already intercepts each and every request.

We refine the method preHandle, so that it redirects every request to our sign-in-page, that is not authenticated:

@Override
public boolean preHandle(
    HttpServletRequest request,
    HttpServletResponse response,
    Object handler
    )
    throws
      Exception
{
  if (request.getServletPath().startsWith("/signin"))
    return true;

  String user = UserCookieGenerator.INSTANCE.readCookieValue(request);
  if (user != null)
  {
    if (!repository
        .findUserIdsConnectedTo("facebook", Collections.singleton(user))
        .isEmpty()
        )
    {
      LOG.info("loading user {} from cookie", user);
      SecurityContext.setCurrentUser(user);
      return true;
    }
    else
    {
      LOG.warn("user {} is not known!", user);
      UserCookieGenerator.INSTANCE.removeCookie(response);
    }
  }

  response.sendRedirect("/signin.html");
  return false;
}

If the user, that is identified by the cookie, is not known to Spring Security, we send a redirect to our sign-in-page and flag the request as already handled, by returning false. To prevent an endless loop of redirections, we must not redirect request, that were already redirected to our sign-in-page. Since these requests hit our webapp as a new request for the different location, we can filter out and wave through at the beginning of this method.

Run It!

That is all there is to do. Run the app and call the page http://localhost:8080/profile.html as first request. You will see, that you will be redirected to our sigin-in-page.

Cleaning Up Behind Us…

As it is now not possible, to call any page except the sigin-up-page, without beeing redirected to our sign-in-page, if you are not authenticated, it is impossible to call any page without being authenticated. Hence, we can (and should!) refine our UserIdSource, to throw an exception, if that happens anyway, because it has to be a sign for a bug:

public class SecurityContextUserIdSource implements UserIdSource
{

  @Override
  public String getUserId()
  {
    Assert.state(SecurityContext.userSignedIn(), "No user signed in!");
    return SecurityContext.getCurrentUser();
  }
}

Coming Next…

In the next part of this series, we will enable users to sign in through the canvas-page of our app. The canvas-page is the page that Facebook embeds into its webpage, if we render our app inside of Facebook.

Funded by the Europian Union

This article was published in the course of a resarch-project, that is funded by the European Union and the federal state Northrhine-Wetphalia.

Europäische Union: Investitionen in unsere Zukunft - Europäischer Fonds für regionale Entwicklung EFRE.NRW 2014-2020: Invesitionen in Wachstum und Beschäftigung

Leave a Reply

Your email address will not be published. Required fields are marked *