Multiple login pages with Spring Security

In real projects, you may encounter some cases where the application needs to use two different login methods depending on the user’s role, for example, there are applications that will need normal users to login using tokens or QR code, and admin login using username and password. How to implement multiple login pages using Spring Security? I will guide you in this tutorial.

Example application

First, I will create a new Spring Boot project with Spring Security Starter, Spring Web Starter, Thymeleaf Starter:

Multiple login page with Spring Security

and WebJars with Bootstrap dependency for example as follows:

Result:

Multiple login page with Spring Security

To demonstrate the need we are trying to solve, I will create a controller to expose 2 pages, one only for the user with the USER role and the other only for the user with the ADMIN role. As follows:

The Thymeleaf template for these pages is as follows:

admin.html:

user.html:

Now, if you run the application and request to these two pages, the default login page of Spring Security will always be displayed.

I will use Spring Security’s default login page for user “admin” with username and password, and for normal user “user”, I will use a custom login page with username and password, similar to what I did in Custom login page using Bootstrap and Thymeleaf in Spring Security.

The login-user.html page code for normal users to log in is as follows:

Expose this login page in the ApplicationController class as follows:

Now I will configure Spring Security for requests to these 2 sites.

Spring Security Configuration

First, I will configure information about the user who will log in to the example application.

As I said above, we will have 2 users, “user” and “admin” with roles “USER” and “admin” respectively ADMIN”. Both of these users will use the same source for authentication, which means they are stored in the same place, in this tutorial, we will use the source as in memory.

I will create a bean for the UserDetailsService object containing the information of these two users as follows:

Next, we will configure Spring Security.

Here, because we need to handle the request for the user with the role “USER”, we will display the custom login page and the user with the “ADMIN” role will display the default login page of Spring Security, so I will define multiple class extends abstract class WebSecurityConfigurerAdapter with the following order:

Here, I am declaring to handle the request of a normal user using the UserSpringSecurityConfiguration class and the admin user does the rest. I just declare the @Order annotation for the UserSpringSecurityConfiguration class so that it is called first to handle any request, if the antMatcher() condition is not met for it to handle that request, the AdminSpringSecurityConfiguration class will handle the request.

As you can see, for requests that start with “/user”, if the user does not have the “USER” role, I configure our example application to redirect to the “/user-login” page so that the user can log in, now the AdminSpringSecurityConfiguration class will handle this “/user-login” request. In the AdminSpringSecurityConfiguration class, I have configured for the request that starts with “/user-login”, we will permitAll(). The “/user-login” page will now be displayed. If the login is successful and the user has the “USER” role, our application will automatically redirect to the page starting with “/user” that we requested.

Run the application and request to http://localhost:8080/user/view, you will see the custom login page displayed as follows:

Multiple login page with Spring Security

Log in with user “user” and password as “user”, you will see the following results:

Multiple login page with Spring Security

And if you request to http://localhost:8080/admin/view, you will see Spring Security’s default login page displayed. Login with user “admin” and password “admin”, you will see the following results:

Multiple login page with Spring Security

In the AdminSpringSecurityConfiguration class, I have configured for the remaining requests, except for the “/user/**” request, the user must have the role of “ADMIN”.

Remember that, to configure for a specific request URL, we will use the antMatcher() method of the HttpSecurity object with the value starting with the request URL we need. For the remaining requests, do not declare the @Order annotation with the configuration class, so that it is always in the highest order.

Add Comment