Hey Learners, In this post we will learn Role Based Authorization Using Spring Security full tutorials with video. This tutorials will be helpful for you Role Based Authorization Using Spring boot, Spring security, MVC, Data Jpa , & Thymeleaf.
Guys first watch this video after used this code you will be easily understand. In this tutorials i used backend spring boot ,Spring mvc , Spring security Data JPA and frontend Thymleaf technologies, Html, CSS & Bootstrap.
Role based Login Page Source Code
Roles Based Authorization Using Spring boot Video
Role Based Authorization Using Spring Security Source Code

Backend Source Code
UserManagementAppApplication.java
package com.becoder;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class UserManagementAppApplication {
public static void main(String[] args) {
SpringApplication.run(UserManagementAppApplication.class, args);
}
}
CustomSuccessHandler.java
package com.becoder.config;
import java.io.IOException;
import java.util.Set;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
@Configuration
public class CustomSuccessHandler 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/");
} else if (roles.contains("ROLE_TEACHER")) {
response.sendRedirect("/teacher/");
} else {
response.sendRedirect("/user/");
}
}
}
CustomUserDetails.java
package com.becoder.config;
import java.util.Arrays;
import java.util.Collection;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import com.becoder.model.UserDtls;
public class CustomUserDetails implements UserDetails {
private UserDtls user;
public CustomUserDetails(UserDtls user) {
super();
this.user = user;
}
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
SimpleGrantedAuthority simpleGrantedAuthority = new SimpleGrantedAuthority(user.getRole());
return Arrays.asList(simpleGrantedAuthority);
}
@Override
public String getPassword() {
// TODO Auto-generated method stub
return user.getPassword();
}
@Override
public String getUsername() {
// TODO Auto-generated method stub
return user.getEmail();
}
@Override
public boolean isAccountNonExpired() {
// TODO Auto-generated method stub
return true;
}
@Override
public boolean isAccountNonLocked() {
// TODO Auto-generated method stub
return true;
}
@Override
public boolean isCredentialsNonExpired() {
// TODO Auto-generated method stub
return true;
}
@Override
public boolean isEnabled() {
// TODO Auto-generated method stub
return true;
}
}
SecurityConfig.java
package com.becoder.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Bean
public UserDetailsService getUserDetailsService() {
return new UserDetailsServiceImpl();
}
@Bean
public BCryptPasswordEncoder getPasswordEncoder() {
return new BCryptPasswordEncoder();
}
@Bean
public DaoAuthenticationProvider getDaoAuthProvider() {
DaoAuthenticationProvider daoAuthenticationProvider = new DaoAuthenticationProvider();
daoAuthenticationProvider.setUserDetailsService(getUserDetailsService());
daoAuthenticationProvider.setPasswordEncoder(getPasswordEncoder());
return daoAuthenticationProvider;
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(getDaoAuthProvider());
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests().antMatchers("/admin/**").hasRole("ADMIN").antMatchers("/user/**").hasRole("USER")
.antMatchers("/**").permitAll().and().formLogin().loginPage("/signin").loginProcessingUrl("/login")
.defaultSuccessUrl("/user/").and().csrf().disable();
}
}
UserDetailsServiceImpl.java
package com.becoder.config;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;
import com.becoder.model.UserDtls;
import com.becoder.repository.UserRepository;
@Service
public class UserDetailsServiceImpl implements UserDetailsService {
@Autowired
private UserRepository userRepo;
@Override
public UserDetails loadUserByUsername(String email) throws UsernameNotFoundException {
UserDtls user = userRepo.findByEmail(email);
if (user != null) {
return new CustomUserDetails(user);
}
throw new UsernameNotFoundException("user not available");
}
}
AdminController.java
package com.becoder.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
@RequestMapping("/admin")
public class AdminController {
@GetMapping("/")
public String home() {
return "admin/home";
}
}
TeacherController.java
package com.becoder.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
@RequestMapping("/teacher")
public class TeacherController {
@GetMapping("/")
public String home() {
return "teacher/home";
}
}
HomeController.java
package com.becoder.controller;
import javax.servlet.http.HttpSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;
import com.becoder.model.UserDtls;
import com.becoder.service.UserService;
@Controller
public class HomeController {
@Autowired
private UserService userService;
@GetMapping("/")
public String index() {
return "index";
}
@GetMapping("/signin")
public String login() {
return "login";
}
@GetMapping("/register")
public String register() {
return "register";
}
@PostMapping("/createUser")
public String createuser(@ModelAttribute UserDtls user, HttpSession session) {
// System.out.println(user);
boolean f = userService.checkEmail(user.getEmail());
if (f) {
session.setAttribute("msg", "Email Id alreday exists");
}
else {
UserDtls userDtls = userService.createUser(user);
if (userDtls != null) {
session.setAttribute("msg", "Register Sucessfully");
} else {
session.setAttribute("msg", "Something wrong on server");
}
}
return "redirect:/register";
}
}
UserController.java
package com.becoder.controller;
import java.security.Principal;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import com.becoder.model.UserDtls;
import com.becoder.repository.UserRepository;
@Controller
@RequestMapping("/user")
public class UserController {
@Autowired
private UserRepository userRepo;
@ModelAttribute
private void userDetails(Model m, Principal p) {
String email = p.getName();
UserDtls user = userRepo.findByEmail(email);
m.addAttribute("user", user);
}
@GetMapping("/")
public String home() {
return "user/home";
}
}
UserDtls.java
package com.becoder.model;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import lombok.Data;
@Data
@Entity
public class UserDtls {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
private String fullName;
private String email;
private String address;
private String qualification;
private String password;
private String role;
}
UserRepository.java
package com.becoder.repository;
import org.springframework.data.jpa.repository.JpaRepository;
import com.becoder.model.UserDtls;
public interface UserRepository extends JpaRepository<UserDtls, Integer> {
public boolean existsByEmail(String email);
public UserDtls findByEmail(String email);
}
UserService.java
package com.becoder.service;
import com.becoder.model.UserDtls;
public interface UserService {
public UserDtls createUser(UserDtls user);
public boolean checkEmail(String email);
}
UserServiceImpl.java
package com.becoder.service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import com.becoder.model.UserDtls;
import com.becoder.repository.UserRepository;
@Service
public class UserServiceImpl implements UserService {
@Autowired
private UserRepository userRepo;
@Autowired
private BCryptPasswordEncoder passwordEncode;
@Override
public UserDtls createUser(UserDtls user) {
user.setPassword(passwordEncode.encode(user.getPassword()));
user.setRole("ROLE_USER");
return userRepo.save(user);
}
@Override
public boolean checkEmail(String email) {
return userRepo.existsByEmail(email);
}
}
Fronentend Source code
home.html
<!DOCTYPE html>
<html>
<head>
<meta charset="ISO-8859-1">
<title>Insert title here</title>
</head>
<body>
<h1>User After Login: Home Page</h1>
<a href="/logout">Logout</a>
<h1>Name : [[${user.fullName}]]</h1>
<h1>Email : [[${user.email}]]</h1>
<h1>Qualification : [[${user.qualification}]]</h1>
</body>
</html>
base.html
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org"
th:fragment="layout(content)">
<head>
<meta charset="ISO-8859-1">
<title>Insert title here</title>
<link
href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css"
rel="stylesheet"
integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC"
crossorigin="anonymous">
</head>
<body class="bg-light">
<nav class="navbar navbar-expand-lg navbar-dark bg-primary">
<div class="container-fluid">
<a class="navbar-brand" href="#">User Managment</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" href="/">Home</a></li>
<li class="nav-item"><a class="nav-link" href="register">Register</a></li>
<li class="nav-item"><a class="nav-link" href="signin">Login</a></li>
</ul>
</div>
</div>
</nav>
<div th:replace="${content}"></div>
<script
src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js"
integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM"
crossorigin="anonymous"></script>
</body>
</html>
Index.html
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org"
th:replace="base::layout(~{::section})">
<head>
<meta charset="ISO-8859-1">
<title>Insert title here</title>
</head>
<body>
<section>
<h1>index</h1>
</section>
</body>
</html>
login.html
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org"
th:replace="base::layout(~{::section})">
<head>
<meta charset="ISO-8859-1">
<title>Insert title here</title>
</head>
<body>
<section>
<div class="container p-5">
<div class="row">
<div class="col-md-6 offset-md-3">
<div class="card">
<div class="card-header text-center fs-4">Login Page</div>
<div th:if="${param.error}" class="alert alert-danger">
Invalid username & Password</div>
<div th:if="${param.logout}" class="alert alert-success">
Logout Sucessfully</div>
<div class="card-body">
<form action="/login" method="post">
<div class="mb-3">
<label>Enter Email</label> <input type="text" name="username"
class="form-control">
</div>
<div class="mb-3">
<label>Enter Password</label> <input type="text"
name="password" class="form-control">
</div>
<button class="btn btn-primary col-md-12">Login</button>
</form>
</div>
</div>
</div>
</div>
</div>
</section>
</body>
</html>
register.html
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org"
th:replace="base::layout(~{::section})">
<head>
<meta charset="ISO-8859-1">
<title>Insert title here</title>
</head>
<body>
<section>
<div class="container p-3">
<div class="row">
<div class="col-md-6 offset-md-3">
<div class="card">
<div class="card-header text-center fs-4">Register Page</div>
<th:block th:if="${session.msg}">
<p class="text-center fs-4 text-success">[[${session.msg}]]</p>
<th:block th:text="${#session.removeAttribute('msg')}"></th:block>
</th:block>
<div class="card-body">
<form action="createUser" method="post">
<div class="mb-3">
<label>Enter Full Name</label> <input type="text"
name="fullName" class="form-control">
</div>
<div class="mb-3">
<label>Enter Email</label> <input type="text" name="email"
class="form-control">
</div>
<div class="mb-3">
<label>Enter Address</label> <input type="text" name="address"
class="form-control">
</div>
<div class="mb-3">
<label>Enter Qualification</label> <input type="text"
name="qualification" class="form-control">
</div>
<div class="mb-3">
<label>Enter Password</label> <input type="text"
name="password" class="form-control">
</div>
<button class="btn btn-primary col-md-12">Register</button>
</form>
</div>
</div>
</div>
</div>
</div>
</section>
</body>
</html>
application.properties
spring.datasource.url=jdbc:mysql://localhost:3306/user_management
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.username=root
spring.datasource.password=password
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL8Dialect
spring.jpa.hibernate.ddl-auto=update
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.6.5</version>
<relativePath /> <!-- lookup parent from repository -->
</parent>
<groupId>com.becoder</groupId>
<artifactId>User_Management_App</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>User_Management_App</name>
<description>User Management Project</description>
<properties>
<java.version>11</java.version>
</properties>
<dependencies>
<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-security -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
</project>