Course – LSS – NPI (cat=Spring Security)
announcement - icon

If you're working on a Spring Security (and especially an OAuth) implementation, definitely have a look at the Learn Spring Security course:


1. Overview

In this tutorial, we’ll focus on adding a new Facebook login to an existing form-login app.

We will use the Spring Social support to interact with Facebook and keep things clean and simple.

Note: The Spring Social library is now deprecated; we can take a look at Spring Security 5 – OAuth2 Login which provides social login feature built over OAuth2.

2. Maven Configuration

First, we will need to add spring-social-facebook dependency to our pom.xml:


3. Security Config – Just Form Login

Let’s first start from the simple security configuration where we just have form-based authentication:

@ComponentScan(basePackages = { "" })
public class SecurityConfig {
    private UserDetailsService userDetailsService;

    public AuthenticationManager authManager(HttpSecurity http) throws Exception {
        return http.getSharedObject(AuthenticationManagerBuilder.class)

    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
            .antMatchers("/login*", "/signin/**", "/signup/**")

We’re not going to spend a lot of time on this config – if you want to understand it better, have a look at the form login article.

4. The Facebook Properties

Next, let’s configure Facebook properties in our

Note that:

  • We need to create a Facebook application to obtain appId and appSecret
  • From Facebook application Settings, make sure to Add Platform “Website” and http://localhost:8080/ as the “Site URL”

5. Security Config – Adding Facebook

Now, let’s add a new way to authenticate into the system – driven by Facebook:

public class SecurityConfig {

    private FacebookConnectionSignup facebookConnectionSignup;

    String appSecret;
    String appId;
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {

    public ProviderSignInController providerSignInController() {
        ConnectionFactoryLocator connectionFactoryLocator = 
        UsersConnectionRepository usersConnectionRepository = 
        ((InMemoryUsersConnectionRepository) usersConnectionRepository)
        return new ProviderSignInController(connectionFactoryLocator, 
            usersConnectionRepository, new FacebookSignInAdapter());
    private ConnectionFactoryLocator connectionFactoryLocator() {
        ConnectionFactoryRegistry registry = new ConnectionFactoryRegistry();
        registry.addConnectionFactory(new FacebookConnectionFactory(appId, appSecret));
        return registry;
    private UsersConnectionRepository getUsersConnectionRepository(ConnectionFactoryLocator 
        connectionFactoryLocator) {
        return new InMemoryUsersConnectionRepository(connectionFactoryLocator);

Let’s carefully look at the new config:

  • we’re using a ProviderSignInController to enable the Facebook authentication, which needs two things:
    first, a ConnectionFactoryLocator registered as a FacebookConnectionFactory with the Facebook properties we defined earlier.
    second, an InMemoryUsersConnectionRepository.
  • by sending a POST to “/signin/facebook” – this controller will initiate a user sign-in using the Facebook service provider
  • we’re setting up a SignInAdapter to handle the login logic in our application
  • and we also setting up a ConnectionSignUp to handle signing up users implicitly when they first authenticate with Facebook

6. The Sign-In Adapter

Simply put, this adapter is a bridge between the controller above – driving the Facebook user sign-in flow – and our specific local application:

public class FacebookSignInAdapter implements SignInAdapter {
    public String signIn(
      String localUserId, 
      Connection<?> connection, 
      NativeWebRequest request) {
          new UsernamePasswordAuthenticationToken(
          connection.getDisplayName(), null, 
          Arrays.asList(new SimpleGrantedAuthority("FACEBOOK_USER"))));
        return null;

Note that users logged in using Facebook will have the role FACEBOOK_USER, while users logged in using the form will have the role USER.

7. Connection Sign Up

When a user authenticates with Facebook for the first time, they have no existing account in our application.

This is the point where we need to create that account automatically for them; we’re going to be using a ConnectionSignUp to drive that user creation logic:

public class FacebookConnectionSignup implements ConnectionSignUp {

    private UserRepository userRepository;

    public String execute(Connection<?> connection) {
        User user = new User();
        return user.getUsername();

As you can see, we created an account for the new user – using their DisplayName as username.

8. The Front End

Finally, let’s take a look at our front end.

We’re going to now have support for these two authentication flows – form login and Facebook – on our login page:

<div th:if="${param.logout}">You have been logged out</div>
<div th:if="${param.error}">There was an error, please try again</div>

<form th:action="@{/login}" method="POST" >
    <input type="text" name="username" />
    <input type="password" name="password" />
    <input type="submit" value="Login" />
<form action="/signin/facebook" method="POST">
    <input type="hidden" name="scope" value="public_profile" />
    <input type="submit" value="Login using Facebook"/>

Finally – here’s the index.html:

    <p sec:authentication="name">Username</p>      
    <a th:href="@{/logout}">Logout</a>                     

<h1>Welcome, <span sec:authentication="name">Username</span></h1>
<p sec:authentication="authorities">User authorities</p>

Note how this index page displays usernames and authorities.

And that’s it – we now have two ways to authenticate into the application.

9. Conclusion

In this quick article, we learned how to use spring-social-facebook to implement a secondary authentication flow for our application.

And, of course, as always, the source code is fully available over on GitHub.

Course – LSS (cat=Security/Spring Security)

I just announced the new Learn Spring Security course, including the full material focused on the new OAuth2 stack in Spring Security:

res – Security (video) (cat=Security/Spring Security)
Comments are open for 30 days after publishing a post. For any issues past this date, use the Contact form on the site.