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:
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:
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>
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:
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:
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.
Nam Ha Minh is certified Java programmer (SCJP and SCWCD). He began programming with Java back in the days of Java 1.4 and has been passionate about it ever since. You can connect with him on Facebook and watch his Java videos on YouTube.
Comments