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

Develop a Facebook-App with Spring-Social – Part IV: Signing In Users

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 tried to teach Spring Social how to remember our signed in users and learned, that we have to sign in a user first.

In this part, I will show you, how you sign (and automatically sign up) users, that are authenticated via the Graph-API.

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-04 to get the source for this part of the series.

In Or Up? Up And In!

In the last part of our series we ran in the problem, that we wanted to connect several (new) users to our application.
We tried to achieve that, by extending our initial configuration.
But the mistake was, that we tried to connect new users.
In the world of Spring Social we can only connect a known user to a new social service.

To know a user, Spring Social requires us to sign in that user.
But again, if you try to sign in a new user, Spring Social requires us to sign up that user first.
Because of that, we had already implemented a ConnectionSignUp and configured Spring Social to call it, whenever it does not know a user, that was authenticated by Facebook.
If you forget that (or if you remove the according configuration, that tells Spring Social to use our ConnectionSignUp), Spring Social will redirect you to the URL /signup — a Sign-Up page you have to implement — after a successfull authentication of a user, that Spring Social does not know yet.

The confusion — or, to be honest, my confusion — about sign in and sign up arises from the fact, that we are developing a Facebook-Application.
We do not care about signing up users.
Each user, that is known to Facebook — that is, who has signed up to Facebook — should be able to use our application.
An explicit sign-up to our application is not needed and not wanted.
So, in our use-case, we have to implement the automatically sign-up of new users.
But Spring Social is designed for a much wider range of use cases.
Hence, it has to distinguish between sign-in and sign-up.

Implementation Of The Sign-In

Spring Social provides the interface SignInAdapter, that it calls every time, it has authenticated a user against a social service.
This enables us, to be aware of that event and remember the user for subsequent calls.
Our implementation stores the user in our SecurityContext to sign him in and creates a cookie to remember him for subsequent calls:

public class UserCookieSignInAdapter implements SignInAdapter
{
  private final static Logger LOG =
      LoggerFactory.getLogger(UserCookieSignInAdapter.class);


  @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(usSigning In Userser, request.getNativeResponse(HttpServletResponse.class));

    return null;
  }
}

It returns null, to indicate, that the user should be redirected to the default-URL after an successful sign-in.
This URL can be configured in the ProviderSignInController and defaults to /, which matches our use-case.
If you return a string here, for example /welcome.html, the controller would ignore the configured URL and redirect to that URL after a successful sign-in.

Configuration Of The Sign-In

To enable the Sign-In, we have to plug our SignInAdapter into the ProviderSignInController:

@Bean
public ProviderSignInController signInController(
    ConnectionFactoryLocator factoryLocator,
    UsersConnectionRepository repository
    )
{
  ProviderSignInController controller = new ProviderSignInController(
      factoryLocator,
      repository,
      new UserCookieSignInAdapter()
      );
  return controller;
}

Since we are using Spring Boot, an alternative configuration would have been to just create a bean-instance of our implementation named signInAdapter.
Then, the auto-configuration of Spring Boot would discover that bean, create an instance of ProviderSignInController and plug in our implementation for us.
If you want to learn, how that works, take a look at the implementation of the auto-configuration in the class SocialWebAutoConfiguration, lines 112ff.

Run it!

If you run our refined example and visit it after impersonating different facebook-users, you will see that everything works as expected now.
If you visit the app for the first time (after a restart) with a new user, the user is signed up and in automatically and a cookie is generated, that stores the Facebook-ID of the user in the browser.
On subsequent calls, his ID is read from this cookie and the corresponding connection is restored from the persistent store by Spring Social.

Coming Next…

In the next part of this little series, we will move the redirect-if-unknown logic from our HomeController into our UserCookieInterceptor, so that the behavior of our so-called “security”-concept more closely resembles the behavior of Spring Security.
That will ease the migration to that solution in a later step.

Perhaps you want to skip that, rather short and boring step and jump to the part after the next, that explains, how to sign in users by the signed_request, that Facebook sends, if you integrate your app as a canvas-page.

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

Develop a Facebook-App with Spring-Social – Part III: Implementing a UserIdSource

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, I explained, why the nice little example from the Getting-Started-Guide “Accessing Facebook Data” cannot function as a real facebook-app.

In this part, we will try to solve that problem, by implementing a UserIdSource, that tells Spring Social, which user it should connect to the API.

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-03 to get the source for this part of the series.

Introducing UserIdSource

The UserIdSource is used by Spring Social to ask us, which user it should connect with the social net.
Clearly, to answer that question, we must remeber, which user we are currently interested in!

Remember Your Visitors

In order to remember the current user, we implement a simple mechanism, that stores the ID of the current user in a cookie and retrieves it from there for subsequent calls.
This concept was borrowed — again — from the official code examples.
You can find it for example in the quickstart-example.

It is crucial to stress, that this concept is inherently insecure and should never be used in a production-environment.
As the ID of the user is stored in a cookie, an attacker could simply take over control by sending the ID of any currently connected user, he is interested in.

The concept is implemented here only for educational purposes.
It will be replaced by Spring Security later on.
But for the beginning, it is easier to understand, how Spring Social works, if we implement a simple version of the mechanism ourself.

Pluging in Our New Memory

The internals of our implementation are not of interest.
You may explore them by yourself.
In short, it stores the ID of each new user in a cookie.
By inspecting that cookie, it can restore the ID of the user on subsequent calls.

What is from interest here is, how we can plug in this simple example-mechanism in Spring Social.

Mainly, there are two hooks to do that, that means: two interfaces, we have to implement:

  1. UserIdSource:
    Spring Social uses an instance of this interface to ask us, which users authorizations it should load from its persistent store of user/connection-mappings.
    We already have seen an implementation of that one in the last part of our series.
  2. ConnectionSignUp:
    Spring Social uses an instance of this interface, to ask us about the name it should use for a new user during sign-up.

Implementation

The implementation of ConnectionSignUp simply uses the ID, that is provided by the social network.
Since we are only signing in users from Facebook, these ID’s are guaranteed to be unique.

public class ProviderUserIdConnectionSignUp implements ConnectionSignUp
{
  @Override
  public String execute(Connection connection)
  {
    return connection.getKey().getProviderUserId();
  }
}

The implementation of UserIdSource retrieves the ID, that was stored in the SecurityContext (our simple implementation — not to be confused with the class from Spring Security).
If no user is stored in the SecurityContext, it falls back to the old behavior and returns the fix id anonymous.

public class SecurityContextUserIdSource implements UserIdSource
{
  private final static Logger LOG =
      LoggerFactory.getLogger(SecurityContextUserIdSource.class);


  @Override
  public String getUserId()
  {
    String user = SecurityContext.getCurrentUser();
    if (user != null)
    {
      LOG.debug("found user \"{}\" in the security-context", user);
    }
    else
    {
      LOG.info("found no user in the security-context, using \"anonymous\"");
      user = "anonymous";
    }
    return user;
  }
}

Actual Plumbing

To replace the AnonymousUserIdSource by our new implementation, we simply instantiate that instead of the old one in our configuration-class SocialConfig:

@Override
public UserIdSource getUserIdSource()
{
  return new SecurityContextUserIdSource();
}

There are several ways to plug in the ConnectionSignUp.
I decided, to plug it into the instance of InMemoryUsersConnectionRepository, that our configuration uses, because this way, the user will be signed up automatically on sign in, if it is not known to the application:

@Override
public UsersConnectionRepository getUsersConnectionRepository(
    ConnectionFactoryLocator connectionFactoryLocator
    )
{
  InMemoryUsersConnectionRepository repository =
      new InMemoryUsersConnectionRepository(connectionFactoryLocator);
  repository.setConnectionSignUp(new ProviderUserIdConnectionSignUp());
  return repository;
}

This makes sense, because our facebook-app uses Facebook, to sign in its users, and, because of that, does not have its own user-model.
It can just reuse the user-data provided by facebook.

The other approach would be, to officially sign up users, that are not known to the app.
This is achieved, by redirecting to a special URL, if a sign-in fails, because the user is unknown.
These URL then presents a formular for sign-up, which can be prepopulated with the user-data provided by the social network.
You can read more about this approach in the official documentation.

Run It!

So, let us see, if our refinement works. Run the following command and log into your app with at least two different users:

git clone http://juplo.de/git/examples/facebook-app/
cd facebook-app
checkout part-00
mvn spring-boot:run \
    -Dfacebook.app.id=YOUR_ID \
    -Dfacebook.app.secret=YOUR_SECRET \
    -Dlogging.level.de.juplo.yourshouter=debug

(The last part of the command turns on the DEBUG logging-level, to see in detail, what is going on.

But What The *#! Is Going On There?!?

Unfortunately, our application shows exactly the same behavior as, before our last refinement.
Why that?

If you run the application in a debugger and put a breakpoint in our implementation of ConnectionSignUp, you will see, that this code is never called.
But it is plugged in in the right place and should be called, if a new user signs in!

The solution is, that we are using the wrong mechanism.
We are still using the ConnectController which was configured in the simple example, we extended.
But this controller is meant to connect a known user to one or more new social services.
This controller assumes, that the user is already signed in to the application and can be retrieved via the configured UserIdSource.


To sign in a user to our application, we have to use the ProviderSignInController instead!

Coming next…

In the next part of this series, I will show you, how to change the configuration, so that the ProviderSignInController is used to sign in (and automatically sign up) users, that were authenticated through the Graph-API from 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

Develop a Facebook-App with Spring-Social – Part II: How Spring Social Works

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 took control of the autoconfiguration, that Spring Boot had put in place for us.
But there is still a lot of magic in our little example, that was borrowed from the offical “Getting Started”-guides or at least, it looks so.

First Time In The Electric-Wonder-Land

When I first run the example, I wondered like “Wow, how does this little piece of code figures out which data to fetch? How is Spring Social told, which data to fetch? That must be stored in the session, or so! But where is that configured?” and so on and so on.

When we connect to Facebook, Facebook tells Spring Social, which user is logged in and if this user authorizes the requested access.
We get an access-token from facebook, that can be used to retrieve user-related data from the Graph-API.
Our application has to manage this data.

Spring Social assists us on that task.
But in the end, we have to make the decisions, how to deal with it.

Whom Are You Intrested In?

Spring Social provides the concept of a ConnectionRepository, which is used to persist the connections of specific user.
Spring Social also provides the concept of a UsersConnectionRepository, which stores, whether a user is connected to a specific social service or not.
As described in the official documentation, Spring Social uses the UsersConnectionRepository to create a request-scoped ConnectionRepository bean (the bean named facebook in our little example), that is used by us to access the Graph-API.

But to be able to do so, it must know which user we are interested in!

Hence, Spring Social requires us to configure a UserIdSource.
Every time, when it prepares a request for us, Spring Social will ask this source, which user we are interested in.

Attentive readers might have noticed, that we have configured such a source, when we were explicitly rebuilding the automatic default-configuration of Spring Boot:

public class AnonymousUserIdSource implements UserIdSource
{
  @Override
  public String getUserId()
  {
    return "anonymous";
  }
}

No One Special…

But what is that?!?
All the time we are only interested in one and the same user, whose connections should be stored under the key anonymous?

And what will happen, if a second user connects to our app?

Let’s Test That!

To see what happens, if more than one user connects to your app, you have to create a test user.
This is very simple.
Just go to the dashboard of your app, select the menu-item “Roles” and click on the tab “Test Users”.
Select a test user (or create a new one) and click on the “Edit”-button.
There you can select “Log in as this test user”.

If you first connect to the app as yourself and afterwards as test user, you will see, that your data is presented to the test user.

That is, because we are telling Spring Social that every user is called anonymous.
Hence, every user is the same for Spring Social!
When the test user fetches the page, after you have connected to Facebook as yourself, Spring-Social is thinking, that the same user is returning and serves your data.

Coming next…

In the next part of this series, we will try to teach Spring Social to distinguish between several users.

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

Develop a Facebook-App with Spring-Social – Part I: Behind the Scenes

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 and first part of this series, I prepared you for our little course.

In this part we will take a look behind the scenes and learn more about the autoconfiguration performed by Spring-Boot, which made our first small example so automagically.

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-01 to get the source for this part of the series.

Our Silent Servant Behind the Scenes: Spring-Boot

While looking at our simple example from the last part of this series, you may have wondered, how all this is wired up.
You can log in a user from facebook, access his public profile and all this without one line of configuration.


This is achieved via Spring-Boot autoconfiguration.

What comes in very handy in the beginning, sometimes get’s in your way, when your project grows.
This may happen, because these parts of the code are not under your control and you do not know what the autoconfiguration is doing on your behalf.
Because of that, in this part of our series, we will rebuild the most relevant parts of the configuration by hand.
As you will see later, this is not only an exercise, but will lead us to the first improvement of our little example.

What Is Going On Here?

In our case, two Spring-Boot configuration-classes are defining the configuration.
These two classes are SocialWebAutoConfiguration and FacebookAutoConfiguration.
Both classes are located in the package spring-boot-autoconfigure.

The first one configures the ConnectController, sets up an instance of InMemoryUsersConnectionRepository as persitent store for user/connection-mappings and sets up a UserIdService on our behalf, that always returns the user-id anonymous.

The second one adds an instance of FacebookConnectionFactory to the list of available connection-factories, if the required properties (spring.social.facebook.appId and spring.social.facebook.appSecret) are available.
It also configures, that a request-scoped bean of the type Connection<Facebook> is created for each request, that has a known user, who is connected to the Graph-API.

Rebuild This Configuration By Hand

The following class rebuilds the same configuration explicitly:

@Configuration
@EnableSocial
public class SocialConfig extends SocialConfigurerAdapter
{
  /**
   * Add a {@link FacebookConnectionFactory} to the configuration.
   * The factory is configured through the keys <code>facebook.app.id</code>
   * and <,code>facebook.app.secret</code>.
   *
   * @param config
   * @param env 
   */
  @Override
  public void addConnectionFactories(
      ConnectionFactoryConfigurer config,
      Environment env
      )
  {
    config.addConnectionFactory(
        new FacebookConnectionFactory(
            env.getProperty("facebook.app.id"),
            env.getProperty("facebook.app.secret")
            )
        );
  }

  /**
   * Configure an instance of {@link InMemoryUsersConnection} as persistent
   * store of user/connection-mappings.
   *
   * At the moment, no special configuration is needed.
   *
   * @param connectionFactoryLocator
   *     The {@link ConnectionFactoryLocator} will be injected by Spring.
   * @return
   *     The configured {@link UsersConnectionRepository}.
   */
  @Override
  public UsersConnectionRepository getUsersConnectionRepository(
      ConnectionFactoryLocator connectionFactoryLocator
      )
  {
    InMemoryUsersConnectionRepository repository =
        new InMemoryUsersConnectionRepository(connectionFactoryLocator);
    return repository;
  }

  /**
   * Configure a {@link UserIdSource}, that is equivalent to the one, that is
   * created by Spring-Boot.
   *
   * @return
   *     An instance of {@link AnonymousUserIdSource}.
   *
   * @see {@link AnonymousUserIdSource}
   */
  @Override
  public UserIdSource getUserIdSource()
  {
    return new AnonymousUserIdSource();
  }


  /**
   * Configuration of the controller, that handles the authorization against
   * the Facebook-API, to connect a user to Facebook.
   *
   * At the moment, no special configuration is needed.
   *
   * @param factoryLocator
   *     The {@link ConnectionFactoryLocator} will be injected by Spring.
   * @param repository
   *     The {@link ConnectionRepository} will be injected by Spring.
   * @return
   *     The configured controller.
   */
  @Bean
  public ConnectController connectController(
      ConnectionFactoryLocator factoryLocator,
      ConnectionRepository repository
      )
  {
    ConnectController controller =
        new ConnectController(factoryLocator, repository);
    return controller;
  }

  /**
   * Configure a scoped bean named <code>facebook</code>, that enables
   * access to the Graph-API in the name of the current user.
   *
   * @param repository
   *     The {@link ConnectionRepository} will be injected by Spring.
   * @return
   *     A {@Connection}, that represents the authorization of the
   *     current user against the Graph-API, or null, if the
   *     current user is not connected to the API.
   */
  @Bean
  @Scope(value = "request", proxyMode = ScopedProxyMode.INTERFACES)
  public Facebook facebook(ConnectionRepository repository)
  {
    Connection connection =
        repository.findPrimaryConnection(Facebook.class);
    return connection != null ? connection.getApi() : null;
  }
}

If you run this refined version of our app, you will see, that it behaves in exact the same way, as the initial version.

Coming next

You may ask, why we should rebuild the configuration by hand, if it does the same thing.
This is, because the example, so far, would not work as a real app.
The first step, to refine it, is to take control of the configuration.

In the next part of this series, I will show you, why this is necessary.
But, first, we have to take a short look into Spring Social.

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

Develop a Facebook-App with Spring-Social – Part 0: Prepare

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

The goal of this series is not, to show how simple it is to set up your first social app with Spring Social.
Even though the usual getting-started guides, like the one this series is based on, are really simple at first glance, they IMHO tend to be confusing, if you try to move on.
I started with the example from the original Getting-Started guide “Accessing Facebook Data” and planed to extend it to handle a sign-in via the canvas-page of facebook, like in the Spring Social Canvas-Example.
But I was not able to achieve that simple refinement and ran into multiple obstacles.

Because of that, I wanted to show the refinement-process from a simple example up to a full-fledged facebook-app.
My goal is, that you should be able to reuse the final result of the last part of this series as blueprint and starting-point for your own project.
At the same time, you should be able to jump back to earlier posts and read all about the design-decisions, that lead up to that result.

This part of my series will handle the preconditions of our first real development-steps.

The Source is With You

The source-code can be found on http://juplo.de/git/examples/facebook-app/
and browsed via gitweb.
For every part I will add a corresponding tag, that denotes the differences between the earlier and the later development steps.

Keep it Simple

We will start with the most simple app possible, that just displays the public profile data of the logged in user.
This app is based on the code of the original Getting-Started guide “Accessing Facebook Data” from Spring-Social.

But it is simplified and cleand a little.
And I fixed some small bugs: the original code from
https://github.com/spring-guides/gs-accessing-facebook.git
produces a
NullPointerException and won’t work with the current version 2.0.3.RELEASE of spring-social-facebook, because it uses the depreceated scope read_stream.

The code for this.logging.level.de.juplo.yourshouter= part is tagged with part-00.
Appart from the HTML-templates, the attic for spring-boot and the build-definitions in the pom.xml it mainly consists of one file:

@Controller
@RequestMapping("/")
public class HomeController
{
  private final static Logger LOG = LoggerFactory.getLogger(HomeController.class);


  private final Facebook facebook;


  @Inject.logging.level.de.juplo.yourshouter=
  public HomeController(Facebook facebook)
  {
    this.facebook = facebook;
  }


  @RequestMapping(method = RequestMethod.GET)
  public String helloFacebook(Model model)
  {
    boolean authorized = true;
    try
    {
      authorized = facebook.isAuthorized();
    }
    catch (NullPointerException e)
    {
      LOG.debug("NPE while acessing Facebook: {}", e);
      authorized = false;
    }
    if (!authorized)
    {
      LOG.info("no authorized user, redirecting to /connect/facebook");
      return "redirect:/connect/facebook";
    }

    User user = facebook.userOperations().getUserProfile();
    LOG.info("authorized user {}, id: {}", user.getName(), user.getId());
    model.addAttribute("user", user);
    return "home";
  }
}

I removed every unnecessary bit, to clear the view for the relevant part.
You can add your styling and stuff by yourself later…

Automagic

The magic of Spring-Social is hidden in the autoconfiguration of Spring-Boot, which will be revealed and refined/replaced in the next parts of this series.

Run it!

You can clone the repository, checkout the right version and run it with the following commands:

git clone http://juplo.de/git/examples/facebook-app/
cd facebook-app
checkout part-00
mvn spring-boot:run \
    -Dfacebook.app.id=YOUR_ID \
    -Dfacebook.app.secret=YOUR_SECRET

Of course, you have to replace YOUR_ID and YOUR_SECRET with the ID and secret of your Facebook-App.
What you have to do to register as a facebook-developer and start your first facebook-app is described in this “Getting Started”-guide from Spring-Social.

In addition to what is described there, you have to configure the URL of your website.
To do so, you have to navigate to the Settings-panel of your newly registered facebook-app.
Click on Add Platform and choose Website.
Then, enter http://localhost:8080/ as the URL of your website.

After maven has downloaded all dependencies and started the Spring-Boot application in the embedded tomcat, you can point your browser to http://localhost:8080, connect, go back to the welcome-page and view the public data of the account you connected with your app.

Coming next…

Now, you are prepared to learn Spring-Social and develop your first app step by step.
I will guide you through the process in the upcoming parts of this series.

In the next part of this series I will explain, why this example from the “Getting Started”-guide would not work as a real application and what has to be done, to fix that.

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

How To Keep The Time-Zone When Deserializing A ZonedDateTime With Jackson

The Problem: Jackson Loses The Time-Zone During Dezerialization Of A ZonedDateTime

In its default configuration Jackson adjusts the time-zone of a ZonedDateTime to the time-zone of the local context.
As, by default, the time-zone of the local context is not set and has to be configured manually, Jackson adjusts the time-zone to GMT.

This behavior is very unintuitive and not well documented.
It looks like Jackson just loses the time-zone during deserialization and, if you serialize and deserialize a ZonedDateTime, the result will not equal the original instance, because it has a different time-zone.

The Solution: Tell Jackson, Not To Adjust the Time-Zone

Fortunately, there is a quick and simple fix for this odd default-behavior: you just have to tell Jackson, not to adjust the time-zone.
Tis can be done with this line of code:

mapper.disable(DeserializationFeature.ADJUST_DATES_TO_CONTEXT_TIME_ZONE);

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

Fix Hot Reload of Thymeleaf-Templates In spring-boot:run

The Problem: Hot-Reload Of Thymeleaf-Templates Does Not Work, When The Application Is Run With spring-boot:run

A lot of people seem to have problems with hot reloading of static HTML-ressources when developing a Spring-Boot application that uses Thymeleaf as templateing engine with spring-boot:run.
There are a lot of tips out there, how to fix that problem:

  • The official Hot-Swapping-Guide says, that you just have to add spring.thymeleaf.cache=false in your application-configuration in src/main/resources/application.properties.
  • Some say, that you have to disable caching by setting spring.template.cache=false and spring.thymeleaf.cache=false and/or run the application in debugging mode.
  • Others say, that you have to add a dependency to org.springframework:springloaded to the configuration of the spring-boot-maven-plugin.
  • There is even a bug-report on GitHub, that says, that you have to run the application from your favored IDE.

But none of that fixes worked for me.
Some may work, if I would switch my IDE (I am using Netbeans), but I have not tested that, because I am not willing to switch my beloved IDE because of that issue.

The Solution: Move Your Thymeleaf-Templates Back To src/main/webapp

Fortunatly, I found a simple solution, to fix the issue without all the above stuff.
You simply have to move your Thymeleaf-Templates back to where they belong (IMHO): src/main/webapp and turn of the caching.
It is not necessary to run the application in debugging mode and/or from your IDE, nor is it necessary to add the dependency to springloaded or more configuration-switches.

To move the templates and disable caching, just add the following to your application configuration in src/main/application.properties:

spring.thymeleaf.prefix=/thymeleaf/
spring.thymeleaf.cache=false

Of course, you also have to move your Thymeaf-Templates from src/main/resources/templates/ to src/main/webapp/thymeleaf/.
In my opinion, the templates belong there anyway, in order to have them accessible as normal static HTML(5)-files.
If they are locked away in the classpath you cannot access them, which foils the approach of Thymeleaf, that you can view your templates in a browser as thy are.

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

java.lang.Exception: Method XZY should have no parameters

Did you ever stumbled across the following error during developing test-cases with JUnit and JMockit?

java.lang.Exception: Method XZY should have no parameters

Here is the quick and easy fix for it:
Fix the ordering of the dependencies in your pom.xml.
The dependency for JMockit has to come first!

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

Integrating A Maven-Backend- With A Nodjs/Grunt-Fronted-Project

Frontend-Development With Nodjs and Grunt

As I already wrote in a previous article, frontend-development is mostly done with Nodjs and Grunt nowadays.
As I am planing to base the frontend of my next Spring-Application on Bootstrap, I was looking for a way to integrate my backend, which is build using Spring and Thymeleaf and managed with Maven, with a frontend, which is based on Bootstrap and, hence, build with Nodjs and Grunt.

Integrate The Frontend-Build Into The Maven-Build-Process

As I found out, one can integrate a npm-based build into a maven project with the help of the frontend-maven-plugin.
This plugin automates the managment of Nodjs and its libraries and ensures that the version of Node and NPM being run is the same in every build environment.
As a backend-developer, you do not have to install any of the frontend-tools manualy.
Because of that, this plugin is ideal to integrate a separately developed frontend into a maven-build, without bothering the backend-developers with details of the frontend-build-process.

Seperate The Frontend-Project From The Maven-Based Backend-Project

The drawback with this approach is, that the backend- and the frontend-project are tightly coupled.
You can configure the frontend-maven-plugin to use a separate subdirectory as working-directory (for example src/main/frontend) and utilize this to separate the frontend-project in its own repository (for example by using the submodule-functions of git).
But the grunt-tasks, that you call in the frontend-project through the frontend-maven-plugin, must be defined in that project.

Since I am planing to integrate a ‐ slightly modified ‐ version of Bootstrap as frontend into my project, that would mean that I have to mess around with the configuration of the Bootstrap-project a lot.
But that is not a very good idea, because it hinders upgrades of the Bootstrap-base, because merge-conflicts became more and more likely.

So, I decided to program a special Gruntfile.js, that resides in the base-folder of my Maven-project and lets me redefine and call tasks of a separated frontend-project in a subdirectory.

Redefine And Call Tasks Of An Included Gruntfile From A Sub-Project

As it turned out, there are several npm-plugins for managing and building sub-projects (like grunt-subgrunt or grunt-recurse) or including existing Gruntfiles from sub-projects (like grunt-load-gruntfile), but none of them lets you redefine tasks of the subproject before calling them.

I programmed a simple Gruntfile, that lets you do exactly this:


module.exports = function(grunt) {

  grunt.loadNpmTasks('grunt-newer');

  grunt.registerTask('frontend','Build HTML & CSS for Frontend', function() {
    var
    done = this.async(),
    path = './src/main/frontend';

    grunt.util.spawn({
      cmd: 'npm',
      args: ['install'],
      opts: { cwd: path, stdio: 'inherit' }
    }, function (err, result, code) {
      if (err || code > 0) {
        grunt.fail.warn('Failed installing node modules in "' + path + '".');
      }
      else {
        grunt.log.ok('Installed node modules in "' + path + '".');
      }

      process.chdir(path);
      require(path + '/Gruntfile.js')(grunt);
      grunt.task.run('newer:copy');
      grunt.task.run('newer:less');
      grunt.task.run('newer:svgstore');

      done();
    });
  });


  grunt.registerTask('default', [ 'frontend' ]);

};

This Gruntfile loads the npm-taks grunt-newer.
Then, it registers a grunt-task called frontend, that loads the dependencies of the specified sub-project, read in its Gruntfile and runs redefined versions of the tasks copy, less and svgstore, which are defined in the sub-project.
The sub-project itself does not register grunt-newer itself.
This is done in this parent-project, to demonstrate how to register additional grunt-plugins and redefine tasks of the sub-project without touching it at all.

The separated frontend-project can be used by the frontend-team to develop the temlates, needed by the backend-developers, without any knowledge of the maven-project.
The frontend-project is then included into the backend, which is managed by maven, and can be used by the backend-developers without the need to know anything about the techniques that were used to develop the templates.

The whole example can be browsed at juplo.de/gitweb or cloned with:


git clone http://juplo.de/git/examples/maven-grunt-integration

Be sure to checkout the tag 2.0.0 for the corresponding version after the cloning, in case i add more commits to demonstrate other stuff.
Also, you have to init and clone the submodule after checkout:


git submodule init
git submodule update

If you run mvn jetty:run, you will notice, that the frontend-maven-plugin will automatically download Nodejs into a the folder node of the parent-project.
Afterwards, the dependencies of the parent-project are downloaded in the folder node_modules of the parent-project and the dpendencies of the sub-project are downloaded in the folder src/main/frontend/node_modules and the sub-project is build automatically in the folder src/main/frontend/dist, which is included into the directory-tree that is served by the jetty-maven-plugin.

The sub-project is fully usable standalone to drive the development of the frontend separately.
You can read more about it in this previous article.

Conclusion

In this article, I showed how to integrate a separately developed frontend-project into a backend-project managed by Maven.
This enables you to separate the development of the layout and the logic of a classic ROCA-project nearly totally.