Spring Boot Social Login with Facebook Example
- Details
- Written by Nam Ha Minh
- Last Updated on 30 November 2022   |   Print Email
Social login is very common for web applications today, as it brings convenience to end users – single sign on across different applications.
In this tutorial, I’d love to share with you guys about implementing social login with Facebook for an existing Spring Boot web application, using Spring OAuth2 Client library – so your users will be able to sign in your application using their own Facebook accounts instead of application-managed credentials.
Suppose that you have an existing Spring Boot project with authentication functionality already implemented using Spring Security and the user information is stored in MySQL database (If not, download the sample project in this tutorial).
Then we will update the login page that lets the users login using their own Facebook accounts like this:
Here, the users can choose to login using email and password (which requires registration before), or login with Facebook (no registration required).
1. Create Facebook App ID
Firstly, you need to create Facebook developer account and create a Facebook App for OAuth authentication. Follow this video: How to create Facebook App ID for Website login.
Then obtain the App ID and App Secret of your new Facebook App, to be used in the project configuration. And note that for testing on localhost you don’t need to specify a redirect URI.
2. Add Spring Boot OAuth2 Client Dependency
To use Spring Boot OAuth2 client library along with Spring Security, you need to add the following dependency (Maven) for the project:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-oauth2-client</artifactId> </dependency>
You will see Spring OAuth2 simplifies Facebook social login integration for Spring Boot application. What you need to do is few configuration and Java classes.
3. Configure Spring OAuth2 Properties for Facebook
Next, in your Spring Boot configuration file (application.yml), declare the following properties for OAuth2 Client registration with provider facebook:
spring: security: oauth2: client: registration: facebook: clientId: YOUR_FACEBOOK_APP_ID clientSecret: YOUR_FACEBOOK_APP_SECRET scope: - email - public_profile
Remember to replace the values for clientId and clientSecret by the App ID and Secret which you got in the previous step (create Facebook App ID).
4. Update User Entity Class and Users table
When a user chooses to use social login using Facebook, the application will store the user’s information (email address and provider named FACEBOOK) in the database – so we need to update the User entity class – adding a new field along with getter and setter as follows:
package net.codejava.user; import javax.persistence.EnumType; import javax.persistence.Enumerated; @Entity @Table(name = "users") public class User { ... @Enumerated(EnumType.STRING) private Provider provider; public Provider getProvider() { return provider; } public void setProvider(Provider provider) { this.provider = provider; } ... }
Provider is an enum type, which is as simple as follows:
package net.codejava.user; public enum Provider { LOCAL, FACEBOOK }
Then in the database, we have a new column provider with datatype is varchar like this:
The possible values for this column are LOCAL and FACEBOOK (enum constants).
5. Update Login Page
In your custom login page, add the following hyperlink:
<a th:href="/@{/oauth2/authorization/facebook}">Login with Facebook</a>
Then the users will see the Login with Facebook option as shown below:
For more details about using custom login page, read this article: Spring Security Custom Login Page with Thymeleaf, HTML 5 and Bootstrap 4.
6. Code Custom OAuth User and OAuth User Service Classes
Next, you need to create a class of type OAuth2User defined by Spring OAuth2, with the following code:
package net.codejava.security.oauth; import java.util.Collection; import java.util.Map; import org.springframework.security.core.GrantedAuthority; import org.springframework.security.oauth2.core.user.OAuth2User; public class CustomOAuth2User implements OAuth2User { private OAuth2User oauth2User; public CustomOAuth2User(OAuth2User oauth2User) { this.oauth2User = oauth2User; } @Override public Map<String, Object> getAttributes() { return oauth2User.getAttributes(); } @Override public Collection<? extends GrantedAuthority> getAuthorities() { return oauth2User.getAuthorities(); } @Override public String getName() { return oauth2User.getAttribute("name"); } public String getEmail() { return oauth2User.<String>getAttribute("email"); } }
You can see this class wraps an instance of OAuth2User, which will be passed by Spring OAuth upon successful OAuth authentication. And note that we override the getName() and code the getEmail() methods to return username and email, respectively.
And create a subclass of DefaultOAuth2UserService as follows:
package net.codejava.security.oauth; import org.springframework.security.oauth2.client.userinfo.DefaultOAuth2UserService; import org.springframework.security.oauth2.client.userinfo.OAuth2UserRequest; import org.springframework.security.oauth2.core.OAuth2AuthenticationException; import org.springframework.security.oauth2.core.user.OAuth2User; import org.springframework.stereotype.Service; @Service public class CustomOAuth2UserService extends DefaultOAuth2UserService { @Override public OAuth2User loadUser(OAuth2UserRequest userRequest) throws OAuth2AuthenticationException { OAuth2User user = super.loadUser(userRequest); return new CustomOAuth2User(user); } }
Here, we override the loadUser() method which will be called by Spring OAuth2 upon successful authentication, and it returns a new CustomOAuth2User object.
7. Configure Spring Security for OAuth2 Authentication
To enable social login with Facebook along with trivial login page, you need to update the Spring Security configuration class as follows:
package net.codejava.security; @Configuration @EnableWebSecurity public class WebSecurityConfig extends WebSecurityConfigurerAdapter { ... @Override protected void configure(HttpSecurity http) throws Exception { http.authorizeRequests() .antMatchers("/", "/login").permitAll() .anyRequest().authenticated() .and() .formLogin().permitAll() .and() .oauth2Login() .loginPage("/login") .userInfoEndpoint() .userService(oauth2UserService); } @Autowired private CustomOAuth2UserService oauth2UserService; }
The important part to configure OAuth2 Login is:
http.oauth2Login() .loginPage("/login") .userInfoEndpoint() .userService(userService)
That’s enough for the basic OAuth2 configuration with Spring Boot. You can now test login using Facebook, but let’s go further – as described in the next section.
8. Implement Authentication Success Handler
Because we need to process some logics after successful login using Facebook, e.g. updating user information in the database – so add the following code to configure an authentication success handler:
http.oauth2Login() .loginPage("/login") .userInfoEndpoint() .userService(oauthUserService) .and() .successHandler(new AuthenticationSuccessHandler() { @Override public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException { CustomOAuth2User oauthUser = (CustomOAuth2User) authentication.getPrincipal(); userService.processOAuthPostLogin(oauthUser.getEmail()); response.sendRedirect("/list"); } })
You know, the onAuthenticationSuccess() method will be called by Spring OAuth2 upon successful login using Facebook, so here we can perform our custom logics – by using the UserService class – which is described in the next section.
9. Register New User Upon Successful Facebook Login
We implement the processOAuthPostLogin() method in the UserService class as follows:
package net.codejava.user; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @Service public class UserService { @Autowired private UserRepository repo; public void processOAuthPostLogin(String username) { User existUser = repo.getUserByUsername(username); if (existUser == null) { User newUser = new User(); newUser.setUsername(username); newUser.setProvider(Provider.FACEBOOK); newUser.setEnabled(true); repo.save(newUser); } } }
Here, we check if no users found in the database with the given email (which is retrieved after successful login with Facebook), then we persist a new User object with the provider name is FACEBOOK. You can also write additional code for updating user’s details in case the user exists in the database.
For your reference, below is code of the UserRepository class:
package net.codejava.user; import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.CrudRepository; import org.springframework.data.repository.query.Param; public interface UserRepository extends CrudRepository<User, Long> { @Query("SELECT u FROM User u WHERE u.username = :username") public User getUserByUsername(@Param("username") String username); }
10. Test Social Login using Facebook
Download the sample project under the Attachments section below. Run the ProductManagerApplication and access the application at http://localhost URL. Click View all products and the login page appears.
Click Login with Facebook, enter email and password of your Facebook account, then you’ll be redirected to the product listing page, as follows:
Note that if you already logged in your Facebook, you will be authenticated automatically without having to sign in your Facebook. Check the users table in database and you will see a new row inserted with provider is FACEBOOK.
Congratulations! You have successfully implemented social login using Facebook in a Spring Boot application with Spring OAuth2 client API.
NOTES:
- Because the Facebook App you created is still in Development mode, you can login using only the Facebook account which you used to create the Facebook App. If you want to login using any Facebook accounts, you must enable Live mode for your Facebook App, which is described in this video.
- Facebook App may require SSL connection, so kindly refer to this video: Configure HTTPS for Spring Boot Application with Self-Signed Certificate on Localhost
- If you encounter a Facebook login error, this article may help.
- Clone sample project from this GitHub repo.
To see the coding steps in action, watch the following companion video:
Related Spring OAuth2 Tutorials:
- Spring Boot OAuth2 Login with Google Example
- Spring Boot OAuth2 Login with GitHub Example
- Spring Boot OAuth2 Social Login with Google and Facebook Examples
Related Spring Security Tutorials:
- Spring Security Forgot Password Tutorial
- Spring Security Limit Login Attempts Example
- Spring Security OTP Email Tutorial
- Spring Security Authentication with JPA, Hibernate and MySQL
- Spring Security Role-based Authorization Tutorial
- Spring Security Customize Login and Logout
- How to Get Logged-in User's Details with Spring Security
- Spring Security: Prevent User from Going Back to Login Page if Already logged in
- Spring Security Authentication Success Handler Examples
- Spring Security Authentication Failure Handler Examples
- Spring Security Logout Success Handler Example
- Spring Security Before Authentication Filter Examples
Other Spring Boot Tutorials:
- How to create a Spring Boot Web Application (Spring MVC with JSP/ThymeLeaf)
- Spring Boot CRUD Example with Spring MVC – Spring Data JPA – ThymeLeaf - Hibernate - MySQL
- Spring Boot Hello World RESTful Web Services Tutorial
- Spring Boot Thymeleaf Form Handling Tutorial
- Spring Data JPA Paging and Sorting Examples
- Spring Boot Error Handling Guide
- Spring Boot Logging Basics
Comments