Lots of webmasters love to give their users the option to login with either Facebook or Twitter. Fortunately, you can add social media login support to your Spring Boot app.
Why, yes. Yes we did. But those solutions didn’t integrate with Spring Security. They used external libraries and are suitable options if, for whatever reason, you don’t want to use Spring Security.
In this article, we’ll go over how to enable your users to login with either Facebook or Twitter. If you want to see the complete code for this project, have a look on GitHub.
Create the Apps
Before you can offer your users a Facebook/Twitter login solution, you need to create an application for both platforms.
Set the Properties
Once you’ve created your social media applications, you need to give your Spring Boot app permission to communicate with them. You’ll do that by adding properties in the application.properties file.
Obviously, you’ll want to update the code above with your own credentials.
Add the Necessary Dependencies
You’re going to need quite a few dependencies for this one. Expect your JAR file footprint to be large.
For starters, you’ll need the Spring Social dependencies for both Facebook and Twitter. In addition to that, you’ll need related Spring Security dependencies as well.
Here’s what the list of dependencies should look like your POM file.
Create the User Class
Next, create a User class to represent the user that logs in via Facebook or Twitter.
Keep it simple for now by just including a single field that stores the user’s display name. Later on, you can add other fields (such as address, phone number, etc.).
Here’s the very simple User class:
Configure the MVC Views
Next, it’s time to configure a few views. For the purposes of this demo, you’ll just need 3 of them: a home page, a login page, and a successful login page.
The home page is the “front end” of your website. That’s where you market your brand, so you’ll let visitors view the home page even if they’re not logged in.
The login page allows the user to login with either Facebook or Twitter.
The successful login page is a simple “Welcome!” page that confirms to the user that the login attempt was successful.
Here’s what the code looks like for configuring the views.
Fasten your seat belts. Things are about to get quite a bit more complicated.
The next step is to configure web security. You’ll do that in a class that extends WebSecurityConfigurerAdapter.
First, override the configure() method to define site-wide security. That code looks like this.
As you can see, right out of the gate the code is disabling cross-site forgery requests with the csrf().disable() code. Yes, that opens up some security issues, but it’s necessary when you need to use a third-party API.
The formLogin() block is fairly self-explanatory. It establishes the URL for the form login and allows all visitors to access it.
Finally, logout() is also universally allowed.
In addition to specifying HTTP security, you also need to use Spring Social’s ProviderSignInController to enable social logins. Here’s what that code looks like:
First of all notice, that the method is annotated with @Bean. That’s because the object returned by the method is a bean managed by the Spring container.
That first line of code in the method references a couple of autowired objects. In a nutshell, that line of code specifies the object that will handle user signups. That’s where you’ll instantiate the User object once the user logs in.
The next line instantiates the ProviderSignInController itself with the constructor that takes 3 parameters.
The first parameter is an autowired ConnectionFactoryLocator object. That code determines what type of ConnectionFactory (i.e., Facebook or Twitter) should be used when the user logs in.
The second parameter, a type of UserConnectionFactory, is also autowired. That object is used to manage user connections to service providers.
The third parameter is a class that you’ll have to write. It’s the bridge between this controller and the code that handles application-specific login.
Keep in mind that ProviderSignInController lives up to its name. It’s really a controller class.
Before coding the adapter and signup object, create a couple of utility classes that will make your life easier.
First, create ConnectionHelper. That class will expose one method used to determine whether the user is logging in with Facebook or Twitter.
Here’s what that code looks like:
Note that the method returns ConnectionType. That’s a simple enum that identifies the connection type as either a Facebook connection or a Twitter connection.
To determine the connection type, the code grabs the API object from the Connection. Then, it just evaluates the interface and returns the appropriate value.
The next utility class you should create is UserHelper. That will populate the User object based on information gleaned from the connection.
Here’s what that code looks like:
The getUser() method accepts a Connection object. It uses that object to determine the connection type and then populates the User object accordingly.
Note that there are two methods for populating the User object: one for Facebook and one for Twitter. They look strikingly similar, so you might think that they can be combined.
However, the object models are different for each API. It’s best to leave them separate if you plan on getting API-specific info for your users.
Next, create the adapter class that handles social media logins. Here’s what that code should look like:
The signIn() method is where everything happens. That’s the implemented method from the interface.
First, the method constructs an Authentication object. We’ll look at that code in a bit.
Next, the code adds the Authentication object to the security context. That’s where the user officially becomes part of the family.
Finally, the method returns “/socialloginsuccess.” That’s the URL path for a successful login.
The getAuthentication() method constructs an Authentication object. In this case, it’s an instance of UserNamePasswordAuthenticationToken.
First, the code gets a List of roles for the user. Here, that List only contains one item. Feel free to expand that list based on your own requirements, though.
The next line of code sets the password to null. A password isn’t needed here because the user logged in via social media.
Finally, the code instantiates the Authentication object with the user’s ID, null password, and List of roles.
The last method in the code block above determines how the user logged in (with Facebook or Twitter) and then sets the role accordingly.
The ConnectionSignUp Class
When a user logs in via Facebook or Twitter, you’re almost certainly going to want to do something with that user information. You’ll probably want to persist it.
It’s beyond the scope of this tutorial to get into persistence, but you’ll see enough here to at least get the ball rolling.
Take a look at the SocialConnectionSignup class.