Redirecting users to different pages after login based on their roles or other criteria is a common requirement in many web applications. Spring Security 6.2.x provides flexible mechanisms to achieve this. In this guide, we will explore how to configure Spring Security to redirect users to different pages after login.

As an example, you might want to redirect standard users to a homepage, while admin users are redirected to an admin dashboard. This article will guide you through implementing this functionality using Spring Security 6.2.x.

Prerequisites

Ensure you have the following set up:

  • Java Development Kit (JDK) 11 or higher
  • Maven or Gradle for dependency management
  • Spring Boot 3.2.x

Project Setup

First, ensure you have the necessary dependencies in your pom.xml or build.gradle file as outlined in the previous guide.

Maven Configuration

Add these dependencies to your pom.xml:

XML
<dependencies>
    <!-- Spring Boot Starter Web -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

    <!-- Spring Boot Starter Security -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-security</artifactId>
    </dependency>

    <!-- Thymeleaf for templating (optional) -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-thymeleaf</artifactId>
    </dependency>
</dependencies>

Gradle Configuration

Add these dependencies to your build.gradle:

Groovy
dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-web'
    implementation 'org.springframework.boot:spring-boot-starter-security'
    implementation 'org.springframework.boot:spring-boot-starter-thymeleaf' // optional
}

Configuring Spring Security

To handle redirection after login, we’ll configure a custom authentication success handler.

1. Create Custom Authentication Success Handler

Create a class named CustomAuthenticationSuccessHandler as shown here:

Java
import org.springframework.security.core.Authentication;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.stereotype.Component;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Set;

@Component
public class CustomAuthenticationSuccessHandler implements AuthenticationSuccessHandler {

    @Override
    public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response,
                                        Authentication authentication) throws IOException, ServletException {
        Set<String> roles = AuthorityUtils.authorityListToSet(authentication.getAuthorities());

        if (roles.contains("ROLE_ADMIN")) {
            response.sendRedirect("/admin/dashboard");
        } else if (roles.contains("ROLE_USER")) {
            response.sendRedirect("/user/homepage");
        } else {
            response.sendRedirect("/default");
        }
    }
}

The onAuthenticationSuccess method is the main entry point of the AuthenticationSuccessHandler. It determines the logged in user role and then redirects to the right URL.

  • ADMIN users are redirected to admin/dashboard URL
  • USERs are redirected to user/homepage
  • ALL_OTHER roles users are redirected to the /default url.

2. Create Security Configuration class

Update your SecurityConfig class to use the custom authentication success handler as follows:

Java
import com.example.security.handler.CustomAuthenticationSuccessHandler;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.beans.factory.annotation.Autowired;

@Configuration
@EnableWebSecurity
public class SecurityConfig {

    @Autowired
    private CustomAuthenticationSuccessHandler customAuthenticationSuccessHandler;

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http
            .authorizeHttpRequests((requests) -> requests
                .requestMatchers("/login", "/logout", "/public/**").permitAll()
                .requestMatchers("/admin/**").hasRole("ADMIN")
                .requestMatchers("/user/**").hasRole("USER")
                .anyRequest().authenticated()
            )
            .formLogin((form) -> form
                .loginPage("/login")
                .successHandler(customAuthenticationSuccessHandler)
                .permitAll()
            )
            .logout((logout) -> logout
                .logoutUrl("/logout")
                .logoutSuccessUrl("/login?logout")
                .invalidateHttpSession(true)
                .deleteCookies("JSESSIONID")
            );

        return http.build();
    }
    
    @Bean
    public UserDetailsService userDetailsService() {
        // Create users with different roles
        UserDetails admin = User.withUsername("admin")
                .password("{noop}admin@123")
                .roles("ADMIN")
                .build();

        UserDetails user = User.withUsername("user")
                .password("{noop}user@123")
                .roles("USER")
                .build();

        return new InMemoryUserDetailsManager(admin, user);
    }
}

The SecurityConfig class configures Spring Security for a web application. It sets up URL authorization rules, specifies custom login and logout behavior, and uses a custom success handler to redirect users after login based on their roles. By defining this configuration, you ensure secure and role-based access control in your Spring Boot application.

  • @Configuration: Indicates that this class contains bean definitions.
  • @EnableWebSecurity: Enables Spring Security’s web security configuration.
  • Inject an instance of CustomAuthenticationSuccessHandler into the SecurityConfig class. The handler will be used to manage what happens after a user successfully logs in.

3. Creating Views and Controllers – Test the Configurations

Create the login page and the home pages for different roles.

1. Create the login.html

Place this file in src/main/resources/templates:

HTML
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <title>Login</title>
</head>
<body>
    <h1>Login</h1>
    <form th:action="@{/login}" method="post">
        <div>
            <label>Username:</label>
            <input type="text" name="username"/>
        </div>
        <div>
            <label>Password:</label>
            <input type="password" name="password"/>
        </div>
        <div>
            <button type="submit">Login</button>
        </div>
        <div th:if="${param.error}">
            Invalid username or password.
        </div>
        <div th:if="${param.logout}">
            You have been logged out.
        </div>
    </form>
</body>
</html>

2. Create adminDashboard.html

Place this file in src/main/resources/templates/admin:

HTML
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <title>Admin Dashboard</title>
</head>
<body>
    <h1>Welcome Admin</h1>
    <a th:href="@{/logout}">Logout</a>
</body>
</html>

3. Create userHome.html

Place this file in src/main/resources/templates/user:

HTML
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <title>User Home</title>
</head>
<body>
    <h1>Welcome User</h1>
    <a th:href="@{/logout}">Logout</a>
</body>
</html>

4. Final HTML – default.html

Place this file in src/main/resources/templates:

HTML
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <title>Default Page</title>
</head>
<body>
    <h1>Welcome to the Default Page</h1>
    <a th:href="@{/logout}">Logout</a>
</body>
</html>

5. Create the HomeController

Create a controller to handle the requests:

Java
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;

@Controller
public class HomeController {

    @GetMapping("/login")
    public String login() {
        return "login";
    }

    @GetMapping("/admin/dashboard")
    public String adminHome() {
        return "admin/adminDashboard";
    }

    @GetMapping("/user/home")
    public String userHome() {
        return "user/userHome";
    }

    @GetMapping("/default")
    public String defaultPage() {
        return "default";
    }
}

Testing the Configuration

Run your Spring Boot application and navigate to http://localhost:8080/login. Log in with credentials corresponding to a user with either ROLE_ADMIN or ROLE_USER. You should be redirected to the appropriate home page based on the user’s role.

Conclusion

By implementing a custom authentication success handler, you can easily control the redirection behavior after login based on user roles or other criteria. This guide has shown you how to set up such redirections in a Spring Security 6.2.x application, providing a flexible and robust solution to meet your application’s requirements.

You have learned how to implement role-based redirection after login in a Spring Security 6.2.x application. We’ve covered the necessary configurations and provided a custom AuthenticationSuccessHandler implementation that determines the target URL based on the user’s roles.

By following this guide, you can easily extend your application to handle different types of users and redirect them to the appropriate pages after successful authentication, enhancing the overall user experience and security of your application.

By |Last Updated: May 21st, 2024|Categories: Spring Security|