Spring Security Role-Based Authorization in Spring Boot

In this example, we will learn how to use Spring Security Role-Based Authorization access in Spring Boot. We will create a step-by-step Spring Boot application with Spring Security role-based access authorization. In this example manage three roles of users(ADMIN, MANAGER and EMPLOYEE) to authorize and access based on the role.

Table of content

1. Keep Eclipse IDE ready(STS integrated)
2. Create a Spring Boot Starter Project 
3. Maven Dependency
4. Create a view page
5. Create a Controller class
6. Create a Spring Security Config class
7. Run the Application
8. Conclusion

1. Keep Eclipse IDE ready(STS integrated)

Refer to this article How to Create Spring Project in IDE to create Spring Boot Project in Eclipse IDE.

2. Create a Spring Boot Starter Project 

Add the following dependencies: 
• Spring Web 
• Spring Security
• Thymeleaf

Project Structure of Role-Based Authorization Spring Security

spring_security_role-based_authorization_in_spring_boot

3. Maven Dependency

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.7.11</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.springjava</groupId>
    <artifactId>Spring_Security_Role_Based_Authorization_Example</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>war</packaging>
    <name>Spring_Security_Role_Based_Authorization_Example</name>
    <description>Demo project for Spring Boot</description>
    <properties>
        <java.version>16</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-tomcat</artifactId>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>

4. Create a view page

Create a view page under src/main/resources/templates.

index.html

<html lang="en"
      xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Spring Security</title>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css"
          rel="stylesheet">
</head>
<body>
<nav class="navbar navbar-expand-lg navbar-dark bg-dark">
    <div class="container-fluid">
        <a class="navbar-brand">Spring Security Role Based Authorization Example</a>
        <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
            <span class="navbar-toggler-icon"></span>
        </button>
        <div class="collapse navbar-collapse" id="navbarSupportedContent">
            <ul class="navbar-nav me-auto mb-2 mb-lg-0">
                <li class="nav-item">
                    <a class="nav-link active" aria-current="page" th:href="@{/login}">Login</a>
                </li>
            </ul>
        </div>
    </div>
</nav>
<br /><br />
<body>
<div class="container">
    <div class="row">
        <h1> Welcome to Spring Security</h1>
    </div>
</div>
</body>
</html>

login.html

<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Login</title>
<link
    href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css"
    rel="stylesheet">
</head>
<body>
    <nav class="navbar navbar-expand-lg navbar-dark bg-dark">
        <div class="container-fluid">
            <a class="navbar-brand">Spring Security Role Based Authorization Example</a>
            <button class="navbar-toggler" type="button"
                data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent"
                aria-controls="navbarSupportedContent" aria-expanded="false"
                aria-label="Toggle navigation">
                <span class="navbar-toggler-icon"></span>
            </button>
        </div>
    </nav>
    <br />
    <br />
    <div class="container">
        <div class="row">
            <div class="col-md-6 offset-md-3">

                <div th:if="${param.error}">
                    <div class="alert alert-danger">Invalid Username or Password</div>
                </div>
                <div th:if="${param.logout}">
                    <div class="alert alert-success">You have been logged out.</div>
                </div>

                <div class="card">
                    <div class="card-header">
                        <h2 class="text-center">Login</h2>
                    </div>
                    <div class="card-body">
                        <form method="post" role="form" th:action="@{/login}"
                            class="form-horizontal">
                            <div class="form-group mb-3">
                                <label class="control-label"> Username</label> <input type="text"
                                    id="username" name="username" class="form-control"
                                    placeholder="Enter username" />
                            </div>

                            <div class="form-group mb-3">
                                <label class="control-label"> Password</label> <input
                                    type="password" id="password" name="password"
                                    class="form-control" placeholder="Enter password" />
                            </div>
                            <div class="form-group mb-3">
                                <button type="submit" class="btn btn-primary">Login</button>
                            </div>
                        </form>
                    </div>
                </div>
            </div>
        </div>
    </div>
</body>
</html>

admin.html

<html lang="en"
      xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Admin</title>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css"
          rel="stylesheet">
</head>
<body>
<nav class="navbar navbar-expand-lg navbar-dark bg-dark">
    <div class="container-fluid">
        <a class="navbar-brand">Spring Security Role Based Authorization Example</a>
        <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
            <span class="navbar-toggler-icon"></span>
        </button>
        <div class="collapse navbar-collapse" id="navbarSupportedContent">
            <ul class="navbar-nav me-auto mb-2 mb-lg-0">
                <li class="nav-item">
                    <a class="nav-link active" aria-current="page" th:href="@{/logout}">Logout</a>
                </li>
            </ul>
        </div>
    </div>
</nav>
<br /><br />
<body>
<div class="container">
    <div class="row">
        <h1> Welcome to Admin Page</h1>
    </div>
</div>
</body>
</html>

manager.html

<html lang="en"
      xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Manager</title>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css"
          rel="stylesheet">
</head>
<body>
<nav class="navbar navbar-expand-lg navbar-dark bg-dark">
    <div class="container-fluid">
        <a class="navbar-brand">Spring Security Role Based Authorization Example</a>
        <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
            <span class="navbar-toggler-icon"></span>
        </button>
        <div class="collapse navbar-collapse" id="navbarSupportedContent">
            <ul class="navbar-nav me-auto mb-2 mb-lg-0">
                <li class="nav-item">
                    <a class="nav-link active" aria-current="page" th:href="@{/logout}">Logout</a>
                </li>
            </ul>
        </div>
    </div>
</nav>
<br /><br />

<body>
<div class="container">
    <div class="row">
        <h1>Welcome to Manager Page</h1>
    </div>
</div>
</body>
</html>

employee.html

<html lang="en"
      xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Employee</title>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css"
          rel="stylesheet">
</head>
<body>
<nav class="navbar navbar-expand-lg navbar-dark bg-dark">
    <div class="container-fluid">
        <a class="navbar-brand">Spring Security Role Based Authorization Example</a>
        <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
            <span class="navbar-toggler-icon"></span>
        </button>
        <div class="collapse navbar-collapse" id="navbarSupportedContent">
            <ul class="navbar-nav me-auto mb-2 mb-lg-0">
                <li class="nav-item">
                    <a class="nav-link active" aria-current="page" th:href="@{/logout}">Logout</a>
                </li>
            </ul>
        </div>
    </div>
</nav>
<br /><br />
<body>
<div class="container">
    <div class="row">
        <h1> Welcome to Employee Page</h1>
    </div>
</div>
</body>
</html>

5. Create a Controller class

HomeController.java

package com.springjava.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;

@Controller
public class HomeController {
    @GetMapping("/")
    public String greeting() {
        return "index";
    }

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

    @GetMapping("/admin")
    public String admin() {
        return "admin";
    }
    
    @GetMapping("/manager")
    public String manager() {
        return "manager";
    }
    
    @GetMapping("/employee")
    public String employee() {
        return "employee";
    }
    
    @GetMapping("/logout")
    public String logout() {
        return "redirect:/login";
    }
}

6. Create a Spring Security Config class

SecurityConfig.java

package com.springjava.security;
import java.io.IOException;
import java.util.Collection;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
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.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;

@Configuration
public class SecurityConfig {
    @Bean
    public static PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

    @Bean
    public SecurityFilterChain securityChain(HttpSecurity http) throws Exception {
        http.authorizeRequests()
        .antMatchers("/","/login").permitAll()
        .antMatchers("/admin").access("hasRole('ROLE_ADMIN')")
        .antMatchers("/manager").access("hasRole('ROLE_MANAGER')")
        .antMatchers("/employee").access("hasRole('ROLE_EMPLOYEE')")
        .and().formLogin().loginPage("/login")
        .and().formLogin().successHandler(new AuthenticationSuccessHandler() {
            
            @Override
            public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response,
                    Authentication authentication) throws IOException, ServletException {
                Collection<? extends GrantedAuthority> role= authentication.getAuthorities();
                for(GrantedAuthority a:role) {
                    if(a.getAuthority().equals("ROLE_ADMIN")) {
                        response.sendRedirect("http://localhost:8088/Spring_Security_Role_Based_Authorization_Example/admin");
                    }
                    if(a.getAuthority().equals("ROLE_MANAGER")) {
                        response.sendRedirect("http://localhost:8088/Spring_Security_Role_Based_Authorization_Example/manager");
                    }
                    if(a.getAuthority().equals("ROLE_EMPLOYEE")) {
                        response.sendRedirect("http://localhost:8088/Spring_Security_Role_Based_Authorization_Example/employee");
                    }
                }
                
            }
        })
        .and().logout().logoutSuccessUrl("/logout");
    
        return http.build();
    }

    @Bean
    public UserDetailsService userDetailsService() {

        UserDetails admin = User.builder().username("admin").password(passwordEncoder().encode("admin")).roles("ADMIN")
                .build();
        UserDetails manager = User.builder().username("manager").password(passwordEncoder().encode("mgr")).roles("MANAGER")
                .build();
        UserDetails employee = User.builder().username("employee").password(passwordEncoder().encode("emp")).roles("EMPLOYEE")
                .build();

        return new InMemoryUserDetailsManager(admin,manager,employee);
    }
}

7. Run the Application

To run this application right-click on the application click on Run As then select the Run on Server option. After successfully running this application on the browser custom login form is shown. 


Click on the Login

spring_security_role_based_authorization_in_spring_boot

Now enter a valid username and password then based on that user’s role redirect the page.

spring_security_role_based_authorization_in_spring_boot

After login admin page will redirect

spring_security_role_based_authorization_in_spring_boot

For logout click on the Logout then the login page will show

spring_security_role_based_authorization_in_spring_boot

11. Conclusion

In this example, we learnt how to use Spring Security Role-Based Access Authorization in the Spring Boot example.

Leave a Comment