Authentication and Authorization with Spring Security & JWT

Hello everyone, today we will learn how to handle authentication and authorization on RESTful APIs written with Spring Boot.GitHub repository link is provided at the end of this tutorial. You can download the source code.

Technologies used:

  • Spring boot is used to develop REST web services and microservices. Spring Boot has taken the Spring framework to the next level. It has drastically reduced the configuration and setup time required for spring projects. We can set up a project with almost zero configuration and start building the things that actually matter to your application.
  • Spring Security is a Java/Java EE framework that provides authentication, authorization, and other security features for enterprise applications.
  • JSON Web Token (JWT) is an open standard (RFC 7519) that defines a compact and self-contained way for securely transmitting information between parties as a JSON object. This information can be verified and trusted because it is digitally signed. JWTs can be signed using a secret or a public/private key pair.
  • Maven is a build automation tool used primarily for Java projects. Maven can also be used to build and manage projects written in C#, Ruby, Scala, and other languages.
  • Java 8 is a major feature release of JAVA programming language development. With the Java 8 release, Java provided fortifies for functional programming, incipient JavaScript engine, incipient APIs for date-time manipulation, incipient streaming API, etc.
  • MongoDB is a cross-platform document-oriented database program. Classified as a NoSQL database program, MongoDB uses JSON-like documents with optional schemas.

Flow Diagram



Project Directory


Maven[pom.xml] 

A Project Object Model or POM is the fundamental unit of work in Maven. It is an XML file that contains information about the project and configuration details utilized by Maven to build the project. It contains default values for most projects. Some of the configurations that can be designated in the POM are the project dependencies, the plugins or goals that can be executed, the build profiles, and so on. Other information such as the project version, description, developers, mailing lists, and such can withal be designated.
<?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.1.1.RELEASE</version>
<relativePath />
</parent>
<groupId>com.knf.dev</groupId>
<artifactId>spring-boot-security-jwt-mongodb</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>spring-boot-security-jwt-mongodb</name>
<description>Demo project for Spring Boot </description>

<properties>
<java.version>1.8</java.version>
</properties>

<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>
<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>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.9.1</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>

application.yaml

knf:
app:
jwtExpirationMs: 76300000
jwtSecret: knowledgeFactory
spring:
data:
mongodb:
database: demo_db
host: localhost
port: 27017

Document[Employee.java]

package com.knf.dev.models;

import java.util.HashSet;
import java.util.Set;
import javax.validation.constraints.Email;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.Size;
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.DBRef;
import org.springframework.data.mongodb.core.mapping.Document;

@Document(collection = "employees")
public class Employee {
@Id
private String id;

@NotBlank
@Size(max = 20)
private String employeename;

@NotBlank
@Size(max = 50)
@Email
private String email;

@NotBlank
@Size(max = 120)
private String password;

@DBRef
private Set<Role> roles = new HashSet<>();

public Employee() {
}

public Employee(String employeename, String email, String password) {
super();
this.employeename = employeename;
this.email = email;
this.password = password;
}

public String getEmployeename() {
return employeename;
}

public void setEmployeename(String employeename) {
this.employeename = employeename;
}

public String getId() {
return id;
}

public void setId(String id) {
this.id = id;
}

public String getEmail() {
return email;
}

public void setEmail(String email) {
this.email = email;
}

public String getPassword() {
return password;
}

public void setPassword(String password) {
this.password = password;
}

public Set<Role> getRoles() {
return roles;
}

public void setRoles(Set<Role> roles) {
this.roles = roles;
}
}

Document[Role.java]

package com.knf.dev.models;

import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.index.Indexed;
import org.springframework.data.mongodb.core.mapping.Document;

@Document(collection = "roles")
public class Role {
@Id
private String id;
@Indexed(unique = true)
private ERole name;

public Role() {

}

public Role(ERole name) {
this.name = name;
}

public String getId() {
return id;
}

public void setId(String id) {
this.id = id;
}

public ERole getName() {
return name;
}

public void setName(ERole name) {
this.name = name;
}
}

ERole.java

package com.knf.dev.models;

public enum ERole {
ROLE_EMPLOYEE, ROLE_ADMIN
}

Repository[EmployeeRepository.java]

package com.knf.dev.repository;

import java.util.Optional;
import org.springframework.data.mongodb.repository.MongoRepository;
import com.knf.dev.models.Employee;

public interface EmployeeRepository
extends MongoRepository<Employee, String> {
Optional<Employee> findByEmployeename(String employeename);

Boolean existsByEmployeename(String employeename);

Boolean existsByEmail(String email);
}

Repository[RoleRepository.java]

package com.knf.dev.repository;

import java.util.Optional;
import org.springframework.data.mongodb.repository.MongoRepository;
import com.knf.dev.models.ERole;
import com.knf.dev.models.Role;

public interface RoleRepository extends MongoRepository<Role, String> {
Optional<Role> findByName(ERole name);
}

EmployeeDetailsImpl.java

package com.knf.dev.security.services;

import java.util.Collection;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.knf.dev.models.Employee;

public class EmployeeDetailsImpl implements UserDetails {
private static final long serialVersionUID = 1L;

private String id;

private String username;

private String email;

@JsonIgnore
private String password;

private Collection<? extends GrantedAuthority> authorities;

public EmployeeDetailsImpl(String id, String username, String email,
String password,
Collection<? extends GrantedAuthority> authorities) {
this.id = id;
this.username = username;
this.email = email;
this.password = password;
this.authorities = authorities;
}

public static EmployeeDetailsImpl build(Employee user) {
List<GrantedAuthority> authorities = user.getRoles().stream()
.map(role -> new SimpleGrantedAuthority
(role.getName().name())).collect(Collectors.toList());

return new EmployeeDetailsImpl(user.getId(), user.getEmployeename(),
user.getEmail(), user.getPassword(),
authorities);
}

@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
return authorities;
}

public String getId() {
return id;
}

public String getEmail() {
return email;
}

@Override
public String getPassword() {
return password;
}

@Override
public String getUsername() {
return username;
}

@Override
public boolean isAccountNonExpired() {
return true;
}

@Override
public boolean isAccountNonLocked() {
return true;
}

@Override
public boolean isCredentialsNonExpired() {
return true;
}

@Override
public boolean isEnabled() {
return true;
}

@Override
public boolean equals(Object o) {
if (this == o)
return true;
if (o == null || getClass() != o.getClass())
return false;
EmployeeDetailsImpl user = (EmployeeDetailsImpl) o;
return Objects.equals(id, user.id);
}
}

EmployeeDetailsServiceImpl.java

package com.knf.dev.security.services;

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 org.springframework.transaction.annotation.Transactional;
import com.knf.dev.models.Employee;
import com.knf.dev.repository.EmployeeRepository;

@Service
public class EmployeeDetailsServiceImpl implements UserDetailsService {
@Autowired
EmployeeRepository employeeRepository;

@Override
@Transactional
public UserDetails loadUserByUsername(String employeename)
throws UsernameNotFoundException {
Employee employee = employeeRepository.findByEmployeename(employeename)
.orElseThrow(() -> new UsernameNotFoundException
("Employee Not Found with username: " + employeename));

return EmployeeDetailsImpl.build(employee);
}
}

JwtUtils.java

package com.knf.dev.security.jwt;

import java.util.Date;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.core.Authentication;
import org.springframework.stereotype.Component;
import com.knf.dev.security.services.EmployeeDetailsImpl;
import io.jsonwebtoken.*;

@Component
public class JwtUtils {
private static final Logger logger = LoggerFactory.getLogger
(JwtUtils.class);
@Value("${knf.app.jwtExpirationMs}")
private int jwtExpirationMs;
@Value("${knf.app.jwtSecret}")
private String jwtSecret;

public boolean validateJwtToken(String authToken) {
try {
Jwts.parser().setSigningKey(jwtSecret).parseClaimsJws(authToken);
return true;
} catch (SignatureException e) {
logger.error("Invalid JWT signature: {}", e.getMessage());
} catch (MalformedJwtException e) {
logger.error("Invalid JWT token: {}", e.getMessage());
} catch (ExpiredJwtException e) {
logger.error("JWT token is expired: {}", e.getMessage());
} catch (UnsupportedJwtException e) {
logger.error("JWT token is unsupported: {}", e.getMessage());
} catch (IllegalArgumentException e) {
logger.error("JWT claims string is empty: {}", e.getMessage());
}

return false;
}

public String generateJwtToken(Authentication authentication) {

EmployeeDetailsImpl employeePrincipal = (EmployeeDetailsImpl)
authentication.getPrincipal();

return Jwts.builder().setSubject((employeePrincipal.getUsername())).
setIssuedAt(new Date())
.setExpiration(new Date((new Date()).getTime() +
jwtExpirationMs))
.signWith(SignatureAlgorithm.HS512, jwtSecret).compact();
}

public String getEmployeeNameFromJwtToken(String token) {
return Jwts.parser().setSigningKey(jwtSecret).parseClaimsJws(token).
getBody().getSubject();
}
}

AuthTokenFilter.java

package com.knf.dev.security.jwt;

import java.io.IOException;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.
UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.web.authentication.
WebAuthenticationDetailsSource;
import org.springframework.util.StringUtils;
import org.springframework.web.filter.OncePerRequestFilter;

import com.knf.dev.security.services.EmployeeDetailsServiceImpl;

public class AuthTokenFilter extends OncePerRequestFilter {
@Autowired
private JwtUtils jwtUtils;

@Autowired
private EmployeeDetailsServiceImpl employeeDetailsService;

private static final Logger logger = LoggerFactory.getLogger
(AuthTokenFilter.class);

@Override
protected void doFilterInternal(HttpServletRequest request,
HttpServletResponse response, FilterChain filterChain)
throws ServletException, IOException {
try {
String jwt = parseJwt(request);
if (jwt != null && jwtUtils.validateJwtToken(jwt)) {
String employeename = jwtUtils.getEmployeeNameFromJwtToken(jwt);

UserDetails employeeDetails = employeeDetailsService.
loadUserByUsername(employeename);
UsernamePasswordAuthenticationToken authentication =
new UsernamePasswordAuthenticationToken(
employeeDetails, null, employeeDetails.getAuthorities())
;
authentication.setDetails(new WebAuthenticationDetailsSource().
buildDetails(request));

SecurityContextHolder.getContext().setAuthentication
(authentication);
}
} catch (Exception e) {
logger.error("Cannot set employee authentication: {}", e);
}

filterChain.doFilter(request, response);
}

private String parseJwt(HttpServletRequest request) {
String headerAuth = request.getHeader("Authorization");

if (StringUtils.hasText(headerAuth) && headerAuth.startsWith("Bearer")) {
return headerAuth.substring(7, headerAuth.length());
}

return null;
}
}

AuthEntryPointJwt.java

package com.knf.dev.security.jwt;

import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.stereotype.Component;

@Component
public class AuthEntryPointJwt implements AuthenticationEntryPoint {

private static final Logger logger = LoggerFactory.getLogger
(AuthEntryPointJwt.class);

@Override
public void commence(HttpServletRequest request, HttpServletResponse
response,
AuthenticationException authException) throws IOException,
ServletException {
logger.error("Unauthorized error: {}", authException.getMessage());
response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Error: Unauthorized");
}
}

WebSecurityConfig.java

package com.knf.dev.security;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.
builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.
EnableGlobalMethodSecurity;
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.config.http.SessionCreationPolicy;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.authentication.
UsernamePasswordAuthenticationFilter;

import com.knf.dev.security.jwt.AuthEntryPointJwt;
import com.knf.dev.security.jwt.AuthTokenFilter;
import com.knf.dev.security.services.EmployeeDetailsServiceImpl;

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private AuthEntryPointJwt unauthorizedHandler;
@Autowired
EmployeeDetailsServiceImpl employeeDetailsService;

@Override
protected void configure(HttpSecurity http) throws Exception {
http.cors().and().csrf().disable().exceptionHandling().
authenticationEntryPoint(unauthorizedHandler).and()
.sessionManagement().sessionCreationPolicy
(SessionCreationPolicy.STATELESS).and().authorizeRequests()
.antMatchers("/api/auth/**").permitAll().
antMatchers("/api/test/**").permitAll().anyRequest()
.authenticated();

http.addFilterBefore(authenticationJwtTokenFilter(),
UsernamePasswordAuthenticationFilter.class);
}

@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}

@Bean
public AuthTokenFilter authenticationJwtTokenFilter() {
return new AuthTokenFilter();
}

@Override
public void configure(AuthenticationManagerBuilder
authenticationManagerBuilder) throws Exception {
authenticationManagerBuilder.userDetailsService(employeeDetailsService).
passwordEncoder(passwordEncoder());
}

@Bean
@Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
}

LoginRequest.java

package com.knf.dev.request;

import javax.validation.constraints.NotBlank;

public class LoginRequest {
@NotBlank
private String employeename;

@NotBlank
private String password;

public String getEmployeename() {
return employeename;
}

public void setEmployeename(String employeename) {
this.employeename = employeename;
}

public String getPassword() {
return password;
}

public void setPassword(String password) {
this.password = password;
}
}

SignupRequest.java

package com.knf.dev.request;

import java.util.Set;
import javax.validation.constraints.*;

public class SignupRequest {
@NotBlank
@Size(min = 3, max = 20)
private String employeename;

@NotBlank
@Size(max = 50)
@Email
private String email;

private Set<String> roles;

@NotBlank
@Size(min = 6, max = 40)
private String password;

public String getEmployeename() {
return employeename;
}

public void setEmployeename(String employeename) {
this.employeename = employeename;
}

public String getEmail() {
return email;
}

public void setEmail(String email) {
this.email = email;
}

public String getPassword() {
return password;
}

public void setPassword(String password) {
this.password = password;
}

public Set<String> getRoles() {
return this.roles;
}

public void setRole(Set<String> roles) {
this.roles = roles;
}
}

JwtResponse.java

package com.knf.dev.response;

import java.util.List;

public class JwtResponse {
private String token;
private String type = "Bearer";
private String id;
private String employeename;
private String email;
private List<String> roles;

public JwtResponse(String accessToken, String id,
String employeename, String email, List<String> roles) {
this.token = accessToken;
this.id = id;
this.employeename = employeename;
this.email = email;
this.roles = roles;
}

public String getAccessToken() {
return token;
}

public void setAccessToken(String accessToken) {
this.token = accessToken;
}

public String getTokenType() {
return type;
}

public void setTokenType(String tokenType) {
this.type = tokenType;
}

public String getId() {
return id;
}

public void setId(String id) {
this.id = id;
}

public String getEmail() {
return email;
}

public void setEmail(String email) {
this.email = email;
}

public String getEmployeename() {
return employeename;
}

public void setEmployeename(String employeename) {
this.employeename = employeename;
}

public List<String> getRoles() {
return roles;
}
}

MessageResponse.java

package com.knf.dev.response;

public class MessageResponse {
private String message;

public MessageResponse(String message) {
this.message = message;
}

public String getMessage() {
return message;
}

public void setMessage(String message) {
this.message = message;
}
}

AuthController.java

package com.knf.dev.controllers;

import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import javax.validation.Valid;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.
UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.knf.dev.models.ERole;
import com.knf.dev.models.Role;
import com.knf.dev.models.Employee;
import com.knf.dev.repository.RoleRepository;
import com.knf.dev.repository.EmployeeRepository;
import com.knf.dev.request.LoginRequest;
import com.knf.dev.request.SignupRequest;
import com.knf.dev.response.JwtResponse;
import com.knf.dev.response.MessageResponse;
import com.knf.dev.security.jwt.JwtUtils;
import com.knf.dev.security.services.EmployeeDetailsImpl;

@CrossOrigin(origins = "*", maxAge = 3600)
@RestController
@RequestMapping("/api/auth")
public class AuthController {
@Autowired
AuthenticationManager authenticationManager;

@Autowired
EmployeeRepository employeeRepository;

@Autowired
RoleRepository roleRepository;

@Autowired
PasswordEncoder encoder;

@Autowired
JwtUtils jwtUtils;

@PostMapping("/signin")
public ResponseEntity<?> authenticateEmployee
(@Valid @RequestBody LoginRequest loginRequest) {

Authentication authentication = authenticationManager.authenticate(
new UsernamePasswordAuthenticationToken(loginRequest.
getEmployeename(), loginRequest.getPassword()));

SecurityContextHolder.getContext().setAuthentication(authentication);
String jwt = jwtUtils.generateJwtToken(authentication);

EmployeeDetailsImpl employeeDetails = (EmployeeDetailsImpl)
authentication.getPrincipal();
List<String> roles = employeeDetails.getAuthorities().stream().
map(item -> item.getAuthority())
.collect(Collectors.toList());

return ResponseEntity.ok(new JwtResponse(jwt, employeeDetails.getId(),
employeeDetails.getUsername(),
employeeDetails.getEmail(), roles));
}

@PostMapping("/signup")
public ResponseEntity<?> registerUser(@Valid @RequestBody
SignupRequest signUpRequest) {
if (employeeRepository.existsByEmployeename(signUpRequest.
getEmployeename())) {
return ResponseEntity.badRequest().body(new MessageResponse
("Error: Employeename is already taken!"));
}

if (employeeRepository.existsByEmail(signUpRequest.getEmail())) {
return ResponseEntity.badRequest().body(new MessageResponse
("Error: Email is already in use!"));
}

// Create new employee account
Employee employee = new Employee(signUpRequest.getEmployeename(),
signUpRequest.getEmail(),
encoder.encode(signUpRequest.getPassword()));

Set<String> strRoles = signUpRequest.getRoles();
Set<Role> roles = new HashSet<>();

if (strRoles == null) {
Role employeeRole = roleRepository.findByName(ERole.ROLE_EMPLOYEE)
.orElseThrow(() -> new RuntimeException
("Error: Role is not found."));
roles.add(employeeRole);
} else {
strRoles.forEach(role -> {
switch (role) {
case "admin":
Role adminRole = roleRepository.findByName(ERole.ROLE_ADMIN)
.orElseThrow(() -> new RuntimeException
("Error: Role is not found."));
roles.add(adminRole);

break;
default:
Role defaultRole = roleRepository.findByName
(ERole.ROLE_EMPLOYEE)
.orElseThrow(() -> new RuntimeException
("Error: Role is not found."));
roles.add(defaultRole);
}
});
}

employee.setRoles(roles);
employeeRepository.save(employee);

return ResponseEntity.ok(new MessageResponse
("Employee registered successfully!"));
}
}

EmployeeController.java

package com.knf.dev.controllers;

import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.knf.dev.response.MessageResponse;

@CrossOrigin(origins = "*", maxAge = 4800)
@RestController
@RequestMapping("/api/test")
public class EmployeeController {
@GetMapping("/all")
public MessageResponse allAccess() {
return new MessageResponse("Public ");
}

@GetMapping("/employee")
@PreAuthorize("hasRole('EMPLOYEE') ")
public MessageResponse employeeAccess() {

return new MessageResponse("Employee zone");
}

@GetMapping("/admin")
@PreAuthorize("hasRole('ADMIN')")
public MessageResponse adminAccess() {
return new MessageResponse("Admin zone");
}
}

Spring Boot Main class

package com.knf.dev;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

import com.knf.dev.models.ERole;
import com.knf.dev.models.Role;
import com.knf.dev.repository.RoleRepository;

@SpringBootApplication
public class Application implements CommandLineRunner {
@Autowired
RoleRepository roleRepository;

public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}

//Add some rows into roles collection before
// assigning any role to Employee.
@Override
public void run(String... args) throws Exception {
try {
Role role = new Role();
role.setName(ERole.ROLE_EMPLOYEE);
roleRepository.save(role);
Role role2 = new Role();
role2.setName(ERole.ROLE_ADMIN);
roleRepository.save(role2);
} catch (Exception e) {

}
}
}

Run & Test

Github repository download link is provided at the end of this tutorial

Local Setup:

Step 1: Download or clone the source code to a local machine.

Step 2mvn clean install

Step 3: Run the Spring Boot application
mvn spring-boot:run


Register employee:
http://localhost:8080/api/auth/signup API



Employee Sign in to an account:
http://localhost:8080/api/auth/signin API


Using accessToken access ROLE_EMPLOYEE resource:
http://localhost:8080/api/test/employee API



Register Admin:
http://localhost:8080/api/auth/signup API



Admin Sign in to an account:
http://localhost:8080/api/auth/signin API


Using accessToken access ROLE_ADMIN resource:
http://localhost:8080/api/test/admin API



git clone: 

More related topics,

Java - Angular - VueJS - ReactJS

NodeJS - Angular - VueJS - ReactJS

Python - Flask  - Angular - VueJS - ReactJS

Popular posts from this blog

Spring boot video streaming example-HTML5

Learn Java 8 streams with an example - print odd/even numbers from Array and List

Spring Boot + Mockito simple application with 100% code coverage

Spring Boot + OpenCSV Export Data to CSV Example

Custom Exception Handling in Quarkus REST API

DataTable-Pagination example with Spring boot, jQuery and ajax

Registration and Login with Spring Boot + Spring Security + Thymeleaf

Node JS mini projects with source code - free download

Spring boot web project free download:User Registration System

Java - Blowfish Encryption and decryption Example