Firstly in this post we are going to setup Spring Security JWT token authentication in Spring boot. Finally all front end tests will be done using postman client application.
1. Overview
We will use spring security, spring data JPA, MySQL. We will write following config classes Initial Data Loader, JWT Authentication Filter, JWT Login Filter, Token Authentication Service and Web Security Config
The first thing is to find out that what are the required dependencies. In short we need following dependencies in our project spring boot, spring security, JPA and JDBC java connector.
Required Maven Dependencies for following purposes:
- WEB, Restful and Spring MVC.
- Writing unit test cases, It also default requirement in spring.
- Spring Security.
- Spring Data, JPA and Hibernate.
- JDBC driver type 4 for MySQL.
- JSON Web.
2. Project Setup
We are using IntelliJ IDE for this project. In the project setup, You will see each file’s usage and it’s purpose so that You could understand easily project setup.

In above figure you can see list of directories and list of files. Some directories and files are important to describe their usage for example source directory and target directory.
- Src directoryis used for writing Java Source code and Unit test cases.
- Development file is saved into target directory.
- When you need any dependency / library in your project then you just need to add an entry in pom file. It imports all dependencies in the project.
2.1 Adding dependencies into pom.xml file
Adding all required dependencies in pom.xml file because we need libraries in our project.
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>demo</name>
<description>Demo project for Spring Boot</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.8.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<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>
<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.15</version>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.7.0</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
You can see that I have inserted all required dependencies into pom file because we need libraries in our project.
There is maven project component so in this component we can clean and install maven project.

In above figure you can see maven life cycle and life of commands.
2.2 Project directory structure
I am creating each separate package for each section for example configuration, controllers, entities, repositories and services. Application properties reside into resources directory. Let’s see structure and then start to write application properties first.

In above figure you can find each separate package moreover in the resources directory you will find application.properties.
2.3 Application Properties
In the application.properties file we always assign custom property values to the application configuration because an application configuration needs custom config values for example database name, database username, database password, server port etc.
server.port = 8090
# create and drop tables and sequences, loads import.sql
spring.jpa.hibernate.ddl-auto=create-drop
#MySQL database
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/test?autoReconnect=true
spring.datasource.username=root
spring.datasource.password=12345
# logging
logging.pattern.console=%d{yyyy-MM-dd HH:mm:ss} %-5level %logger{36} - %msg%n
logging.level.org.hibernate.SQL=debug
MySQL database is running on local machine therefore we used localhost in database URL and schema name.
3. Write Project Code
Before starting to write code, Let’s check project structure first.

In project structure you can find five different packages in the project. You may see a package for configuration For example, config package contains web security configuration class, jwt token authentication config classes. You also can find controllers, repositories, entities and services.
3.1 Default Package
3.1.1 DemoApplication
In default package you will find DemoApplication.java which contains main method in other words It is starting point of the application.
package com.example.demo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@SpringBootApplication
@RestController
@EnableAutoConfiguration
@ComponentScan(basePackages = {"com.example.demo"})
public class DemoApplication {
@RequestMapping("/")
public String hello(){
return "Hello World";
}
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
@Bean
public BCryptPasswordEncoder bCryptPasswordEncoder() {
return new BCryptPasswordEncoder();
}
}
- @SpringBootApplication; we put this annotation instead of auto-configuration, component-scan and extra configuration.
- @RestController; we place this annotation instead of @Controller and @ResponseBody.
- @EnableAutoConfiguration; we place this annotation for enabling auto configuration for beans so those are present at the classpath.
3.2 Config Package
Config package consists of all configuration classes so configuration for Spring security, JWT authentication and Web Configuration etc
3.2.1AccountCredentials.java
package com.example.demo.config;
/**
* Created by sadiq.odho on 9/11/2018.
*/
public class AccountCredentials {
private String username;
private String password;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
AccountCredentials; It is a very simple entity class which contains two properties for instance username and password.
3.2.2 InitialDataLoader.java
Following class is used for saving a single user with role and privilege which is done when application listener is called.
package com.example.demo.config;
import com.example.demo.entities.Privilege;
import com.example.demo.entities.Role;
import com.example.demo.entities.User;
import com.example.demo.repositories.PrivilegeRepository;
import com.example.demo.repositories.RoleRepository;
import com.example.demo.repositories.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Component;
import javax.transaction.Transactional;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
/**
* Created by sadiq.odho on 2/1/2019.
*/
@Component
public class InitialDataLoader implements
ApplicationListener<ContextRefreshedEvent> {
boolean alreadySetup = false;
@Autowired
private UserRepository userRepository;
@Autowired
private RoleRepository roleRepository;
@Autowired
private PrivilegeRepository privilegeRepository;
@Autowired
private PasswordEncoder passwordEncoder;
@Override
@Transactional
public void onApplicationEvent(ContextRefreshedEvent event) {
if (alreadySetup)
return;
Privilege readPrivilege
= createPrivilegeIfNotFound("READ_PRIVILEGE");
Privilege writePrivilege
= createPrivilegeIfNotFound("WRITE_PRIVILEGE");
List<Privilege> adminPrivileges = Arrays.asList(
readPrivilege, writePrivilege);
createRoleIfNotFound("ROLE_ADMIN", adminPrivileges);
createRoleIfNotFound("ROLE_USER", Arrays.asList(readPrivilege));
Role adminRole = roleRepository.findByName("ROLE_ADMIN");
User user = new User();
user.setName("First Name");
user.setPassword(passwordEncoder.encode("test"));
user.setEmail("test@test.com");
user.setRoles(Arrays.asList(adminRole));
user.setEnabled(true);
userRepository.save(user);
alreadySetup = true;
}
@Transactional
private Privilege createPrivilegeIfNotFound(String name) {
Privilege privilege = privilegeRepository.findByName(name);
if (privilege == null) {
privilege = new Privilege();
privilege.setName(name);
privilegeRepository.save(privilege);
}
return privilege;
}
@Transactional
private Role createRoleIfNotFound(
String name, Collection<Privilege> privileges) {
Role role = roleRepository.findByName(name);
if (role == null) {
role = new Role();
role.setName(name);
role.setPrivileges(privileges);
roleRepository.save(role);
}
return role;
}
}
InitialDataLoader which implements ApplicationListener for ContextRefreshedEvent, we override a method onApplicationEvent which called when context is refreshed.
In that method we created two privileges for example “READ_PRIVILEGE” and “WRITE_PRIVILEGE“. We have also created two roles for example “ROLE_ADMIN” and “ROLE_USER“.
We need to create now user with email and password because we should have these credentials for login in the system.
3.2.3 JWTAuthenticationFilter.java
This is a filter class which will be added filter before in spring security config file. All request gonna be filtered before processing any thing request. User may not be logged in therefore we use filter to check first then process.
package com.example.demo.config;
/**
* Created by sadiq.odho on 9/11/2018.
*/
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.filter.GenericFilterBean;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
public class JWTAuthenticationFilter extends GenericFilterBean {
@Override
public void doFilter(ServletRequest request,
ServletResponse response,
FilterChain filterChain)
throws IOException, ServletException {
Authentication authentication = TokenAuthenticationService
.getAuthentication((HttpServletRequest)request);
SecurityContextHolder.getContext()
.setAuthentication(authentication);
filterChain.doFilter(request,response);
}
}
The JWTAuthenticationFilter extends GenericFilterBean so we overriding doFilter method. In this filter we are setting Http Servlet Request to authentication and setting into security context.
3.2.4 JWTLoginFilter.java
In this login filter we will get the user credentials and try to attempt authentication. If it is successful attempt then we will make JWT token and then set into header response.
package com.example.demo.config;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import static java.util.Collections.emptyList;
public class JWTLoginFilter extends AbstractAuthenticationProcessingFilter {
public JWTLoginFilter(String url, AuthenticationManager authManager) {
super(new AntPathRequestMatcher(url));
setAuthenticationManager(authManager);
}
@Override
public Authentication attemptAuthentication(
HttpServletRequest req, HttpServletResponse res)
throws AuthenticationException, IOException, ServletException {
AccountCredentials creds = new ObjectMapper()
.readValue(req.getInputStream(), AccountCredentials.class);
return getAuthenticationManager().authenticate(
new UsernamePasswordAuthenticationToken(
creds.getUsername(),
creds.getPassword(),
emptyList()
)
);
}
@Override
protected void successfulAuthentication(
HttpServletRequest req,
HttpServletResponse res, FilterChain chain,
Authentication auth) throws IOException, ServletException {
TokenAuthenticationService
.addAuthentication(res, auth.getName());
}
}
JWT Login Filter extends Abstract Authentication Processing Filter and have two override methods attempt Authentication and successful authentication.
In attempt authentication method, we extracts credentials and set into account credentials and then we authenticate with Username Password Authentication Token.
In successful authentication method. We are adding JWT token into header using method add Authentication in Token Authentication Service class.
3.2.5 TokenAuthenticationService.java
TSo it is simple class for getting JWT token from request header and setting JWT token into response header. In addition each request must have JWT token in header.
package com.example.demo.config;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Date;
import static java.util.Collections.emptyList;
/**
* Created by sadiq.odho on 9/11/2018.
*/
public class TokenAuthenticationService {
static final long EXPIRATIONTIME = 864_000_000; // 10 days
static final String SECRET = "ThisIsASecret";
static final String TOKEN_PREFIX = "Bearer";
static final String HEADER_STRING = "Authorization";
static void addAuthentication(HttpServletResponse res, String username) {
String JWT = Jwts.builder()
.setSubject(username)
.setExpiration(new Date(System.currentTimeMillis() + EXPIRATIONTIME))
.signWith(SignatureAlgorithm.
HS512, SECRET)
.compact();
res.addHeader(HEADER_STRING, TOKEN_PREFIX + " " + JWT);
}
static Authentication getAuthentication(HttpServletRequest request) {
String token = request.getHeader(HEADER_STRING);
if (token != null) {
// parse the token.
String user = Jwts.parser()
.setSigningKey(SECRET)
.parseClaimsJws(token.replace(TOKEN_PREFIX, ""))
.getBody()
.getSubject();
return user != null ?
new UsernamePasswordAuthenticationToken(user, null, emptyList()) :
null;
}
return null;
}
}
3.2.6 WebSecurityConfig.java
Further we configure all security configuration in configure method with http request we are adding some filters and making some URLs restricted without login. For spring security you will find more details on following guide Link
package com.example.demo.config;
import com.example.demo.services.UserDetailServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
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.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.factory.PasswordEncoderFactories;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
/**
* Created by sadiq.odho on 9/11/2018.
*/
@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private UserDetailServiceImpl userDetailService;
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable().authorizeRequests()
.antMatchers("/", "/users/register").permitAll()
.antMatchers("/login").permitAll()
// .antMatchers("/quotes").permitAll()
.anyRequest().authenticated()
.and()
// We filter the api/login requests
.addFilterBefore(new JWTLoginFilter("/login", authenticationManager()),
UsernamePasswordAuthenticationFilter.class)
// And filter other requests to check the presence of JWT in header
.addFilterBefore(new JWTAuthenticationFilter(),
UsernamePasswordAuthenticationFilter.class);
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
// Create a default account
BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();
auth.userDetailsService(userDetailService).passwordEncoder(bCryptPasswordEncoder);
/*auth.inMemoryAuthentication()
.withUser("admin")
.password(encoder.encode("password"))
.roles("ADMIN");*/
}
}
3.3 Controllers Package
UserController.java; In this controller package we have only User Controller with three methods.
- get Users: we will get all users by calling this method.
- get Logged In User: By using this method we can retrieve current logged in user.
- sing Up: One can register using sing up method.
package com.example.demo.controllers;
import com.example.demo.entities.User;
import com.example.demo.repositories.RoleRepository;
import com.example.demo.repositories.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.handler.UserRoleAuthorizationInterceptor;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
/**
* Created by sadiq.odho on 9/11/2018.
*/
@RestController
@RequestMapping("/users")
public class UserController {
@Autowired
private UserRepository userRepository;
@Autowired
private PasswordEncoder passwordEncoder;
@Autowired
private RoleRepository roleRepository;
/* Maps to all HTTP actions by default (GET,POST,..)*/
@RequestMapping("/all")
public @ResponseBody
List<User> getUsers() {
return userRepository.findAll();
}
@RequestMapping("/get-logged-in-user")
public User getLoggedInUser(){
String username = SecurityContextHolder.getContext().getAuthentication().getName();
if(username != null){
return userRepository.findByEmail(username);
}
return null;
}
@PostMapping("/register")
public User singUp(@RequestBody User user) throws Exception{
if (userRepository.findByEmail(user.getEmail()) != null) {
throw new Exception("There is an account with that email adress: " + user.getEmail());
}
User newUser = new User();
newUser.setName(user.getName());
user.setPassword(passwordEncoder.encode(user.getPassword()));
user.setEmail(user.getEmail());
user.setRoles(Arrays.asList(roleRepository.findByName("ROLE_USER")));
return userRepository.save(user);
}
}
3.4 Entities Package
Entities package contains only model classes For example User, Role and
Privilege classes.
Privilege.java; Privilege class can contains privileges of roles for example READ_PRIVILEGE and WRITE_PRIVILEGE
package com.example.demo.entities;
import com.fasterxml.jackson.annotation.JsonManagedReference;
import javax.persistence.*;
import java.util.Collection;
/**
* Created by sadiq.odho on 1/31/2019.
*/
@Entity
public class Privilege implements java.io.Serializable{
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String name;
@ManyToMany(mappedBy = "privileges")
private Collection<Role> roles;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Collection<Role> getRoles() {
return roles;
}
public void setRoles(Collection<Role> roles) {
this.roles = roles;
}
}
Role.java; Role class contains roles of the users for example ROLE_ADMIN and ROLE_USER
package com.example.demo.entities;
import com.fasterxml.jackson.annotation.JsonBackReference;
import com.fasterxml.jackson.annotation.JsonManagedReference;
import javax.persistence.*;
import java.util.Collection;
/**
* Created by sadiq.odho on 1/31/2019.
*/
@Entity
public class Role implements java.io.Serializable{
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
@Column
private String name;
@ManyToMany(mappedBy = "roles")
private Collection<User> users;
@ManyToMany
@JoinTable(
name = "roles_privileges",
joinColumns = @JoinColumn(
name = "role_id", referencedColumnName = "id"),
inverseJoinColumns = @JoinColumn(
name = "privilege_id", referencedColumnName = "id"))
private Collection<Privilege> privileges;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Collection<User> getUsers() {
return users;
}
public void setUsers(Collection<User> users) {
this.users = users;
}
public Collection<Privilege> getPrivileges() {
return privileges;
}
public void setPrivileges(Collection<Privilege> privileges) {
this.privileges = privileges;
}
}
User.java; User class is used for logged in user information for instance username, email, password.
package com.example.demo.entities;
import com.fasterxml.jackson.annotation.JsonBackReference;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonManagedReference;
import javax.persistence.*;
import java.util.Collection;
/**
* Created by sadiq.odho on 1/31/2019.
*/
@Entity
public class User {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String name;
private String email;
private String password;
private boolean enabled;
private boolean tokenExpired;
@JsonIgnore
@ManyToMany
@JoinTable(
name = "users_roles",
joinColumns = @JoinColumn(
name = "user_id", referencedColumnName = "id"),
inverseJoinColumns = @JoinColumn(
name = "role_id", referencedColumnName = "id"))
private Collection<Role> roles;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
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 boolean isEnabled() {
return enabled;
}
public void setEnabled(boolean enabled) {
this.enabled = enabled;
}
public boolean isTokenExpired() {
return tokenExpired;
}
public void setTokenExpired(boolean tokenExpired) {
this.tokenExpired = tokenExpired;
}
public Collection<Role> getRoles() {
return roles;
}
public void setRoles(Collection<Role> roles) {
this.roles = roles;
}
}
3.5 Repositories package
These repositories are used for accessing data objects in the project so in this package you will find repositories for User, Roles and Privileges.
PrivilegeRepository.java; we create privilege repository for accessing data object of privilege entity
package com.example.demo.repositories;
import com.example.demo.entities.Privilege;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.stereotype.Repository;
/**
* Created by sadiq.odho on 2/1/2019.
*/
@Repository
public interface PrivilegeRepository extends JpaRepository<Privilege, Integer>, JpaSpecificationExecutor<Privilege> {
public Privilege findByName(String name);
}
RoleRepository.java; we create role repository for accessing data object of role entity.
package com.example.demo.repositories;
import com.example.demo.entities.Role;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.stereotype.Repository;
/**
* Created by sadiq.odho on 2/1/2019.
*/
@Repository
public interface RoleRepository extends JpaRepository<Role, Integer>, JpaSpecificationExecutor<Role> {
public Role findByName(String name);
}
UserRepository.java; we create user repository for accessing data object of User entity
package com.example.demo.repositories;
import com.example.demo.entities.User;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;
/**
* Created by sadiq.odho on 1/31/2019.
*/
@Repository
public interface UserRepository extends JpaRepository<User, Integer>, JpaSpecificationExecutor<User>{
@Query(value = "FROM User WHERE email = :email", nativeQuery = false)
public User findByEmail(@Param("email") String email);
}
3.6 Services package
This Service package contains all classes for business logic.
UserDetailServiceImpl.java; UserDetailServiceImpl contains all business logic for user entity object.
package com.example.demo.services;
import com.example.demo.entities.Privilege;
import com.example.demo.entities.Role;
import com.example.demo.entities.User;
import com.example.demo.repositories.RoleRepository;
import com.example.demo.repositories.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.MessageSource;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
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.Component;
import org.springframework.stereotype.Service;
import javax.transaction.Transactional;
import java.util.*;
/**
* Created by sadiq.odho on 1/31/2019.
*/
@Service
@Transactional
public class UserDetailServiceImpl implements UserDetailsService{
@Autowired
private UserRepository userRepository;
@Autowired
private MessageSource messages;
@Autowired
private RoleRepository roleRepository;
@Override
public UserDetails loadUserByUsername(String username)throws UsernameNotFoundException{
User user = userRepository.findByEmail(username);
if(user == null){
return new org.springframework.security.core.userdetails.User(
" ", " ", true, true, true, true,
getAuthorities(Arrays.asList(
roleRepository.findByName("ROLE_USER"))));
}
return new org.springframework.security.core.userdetails.User(
user.getEmail(), user.getPassword(), user.isEnabled(), true, true,
true, getAuthorities(user.getRoles()));
}
private Collection<? extends GrantedAuthority> getAuthorities(
Collection<Role> roles) {
return getGrantedAuthorities(getPrivileges(roles));
}
private List<String> getPrivileges(Collection<Role> roles) {
List<String> privileges = new ArrayList<>();
List<Privilege> collection = new ArrayList<>();
for (Role role : roles) {
collection.addAll(role.getPrivileges());
}
for (Privilege item : collection) {
privileges.add(item.getName());
}
return privileges;
}
private List<GrantedAuthority> getGrantedAuthorities(List<String> privileges) {
List<GrantedAuthority> authorities = new ArrayList<>();
for (String privilege : privileges) {
authorities.add(new SimpleGrantedAuthority(privilege));
}
return authorities;
}
}
4. Test in Postman Client
Postman Client is a browser extension which helps us in web
testing services however it is very useful application.
4.1 Login User
Let’s try to login user, basically you need JWT token for accessing any authenticated request.

Following details of Login User postman
- URL and HTTP method: localhost:8090/login and Post method
- Data Type: JSON (application / json)
- Response Header: If there is successful login authentication then you will find authorization code in response header which starts with Bearer.
4.2 Get logged In User
In following Example we will see that How to avail logged in user in spring security.

Following details of Get Logged in User figure
- URL and HTTP method: localhost:8090/users/get-logged-in-user and GET method.
- Request Header: In request header you must set Authorization with JWT token so it is already retrieved in above example.
- Response Body: After successful authorization you will receive logged in user information in other words you can get authentication after logged in.
5. Conclusion
In conclusion we have implemented spring boot project for Spring security JWT token authentication.
Finally we have tested this application in postman client application.