Angular Spring Boot JWT Authentication example | Angular 6 + Spring Security + MySQL Full Stack – Part 2: Build Backend

spring-boot-angular-spring-security-jwt-authentication-feature-image

The tutorial is Part 2 of the series: Angular Spring Boot JWT Authentication example | Angular 6 + Spring Security + MySQL Full Stack. Today we’re gonna build a SpringBoot Security RestAPIs that can interact with MySQL database.

Part 1: Overview and Architecture.
Part 3: Build Angular Frontend

JWT Authentication with SpringBoot Security RestAPIs

Demo

Overview

Look back to the diagram for Spring Security/JWT classes that are separated into 3 layers:
– HTTP
– Spring Security
– REST API

spring-boot-angular-spring-security-jwt-authentication-architecture-diagram-back-end-server

For more details about this Architecture, please visit:
Spring Security – JWT Authentication Architecture | Spring Boot

Generate/Validate Token

We use a class named JwtProvider. It gets username from Authentication object, then builds JWT Token with username, Date() object, secretKey. JwtProvider can also be used to validate JWT Token:

Filter the Request

We add our JwtAuthTokenFilter (that extends Spring OncePerRequestFilter abstract class) to the chain of filters.

JwtAuthTokenFilter validates the Token using JwtProvider:

Now we have 2 cases:
– Login/SignUp: RestAPI with non-protected APIs -> authenticate Login Request with AuthenticationManager, if error occurs, handle AuthenticationException with AuthenticationEntryPoint.
– With protected Resources:
+ jwt token is null/invalid -> if Authenticated Error occurs, handle AuthenticationException with AuthenticationEntryPoint.
+ jwt token is valid -> from token, get User information, then create AuthenticationToken.

Create AuthenticationToken from Token

JwtAuthTokenFilter extracts username/password from the received token using JwtProvider, then based on the extracted data, JwtAuthTokenFilter:
– creates a AuthenticationToken (that implements Authentication)
– uses the AuthenticationToken as Authentication object and stores it in the SecurityContext for future filter uses (e.g: Authorization filters).

In this tutorial, we use UsernamePasswordAuthenticationToken:

Store Authentication object in SecurityContext

SecurityContextHolder is the most fundamental object where we store details of the present security context of the application (includes details of the principal). Spring Security uses an Authentication object to represent this information and we can query this Authentication object from anywhere in our application:

getContext() returns an instance of SecurityContext interface that holds the Authentication and possibly request-specific security information.

Authenticate with AuthenticationProvider

These are some authentication providers that Spring Framework provides, in this example, we use DaoAuthenticationProvider. This Provider works well with form-based logins or HTTP Basic authentication which submits a simple username/password authentication request.
It authenticates the User simply by comparing the password submitted in a UsernamePasswordAuthenticationToken against the one loaded by the UserDetailsService (as a DAO):

Configuring this provider is simple with AuthenticationManagerBuilder:

For more details about AuthenticationManager & AuthenticationProvider, please visit:
Delegate AuthenticationToken for AuthenticationManagager.

Retrieve User details with UserDetailsService

We can obtain a principal from the Authentication object. This principal can be cast into a UserDetails object to lookup the username, password and GrantedAuthoritys.

Therefore, after authenticating is successful, we can simply get UserDetails from Authentication object:

DaoAuthenticationProvider also uses UserDetailsService for getting UserDetails object. This is the common approach in which we only pass a String-based ‘username’ argument and returns a UserDetails:

It is simple to implement UserDetailsService and easy for us to retrieve authentication information using a persistence strategy:

Protect Resources with HTTPSecurity & Method Security Expressions
Configure HTTPSecurity

To help Spring Security know when we want to require all users to be authenticated, which Exception Handler to be chosen, which filter and when we want it to work. We implement WebSecurityConfigurerAdapter and provide a configuration in the configure(HttpSecurity http) method:

Method Security Expressions

Spring Security provides some annotations for pre and post-invocation authorization checks, filtering of submitted collection arguments or return values: @PreAuthorize, @PreFilter, @PostAuthorize and @PostFilter.

To enable Method Security Expressions, we use @EnableGlobalMethodSecurity annotation:

In the code below, we use the most useful annotation @PreAuthorize to decide whether a method can actually be invoked or not:

Handle AuthenticationException – AuthenticationEntryPoint

If the user requests a secure HTTP resource without being authenticated, AuthenticationEntryPoint will be called. At this time, an AuthenticationException is thrown, commence() method on the entry point is triggered:

Spring Boot server for JWT Authentication Overview

Goal

The diagram below show how our system handles User Registration and User Login processes:

angular-spring-security-jwt-authentication-work-process-diagram

– We expose 2 RestAPIs to signup and signin:

  • /api/auth/signup -> sign up

    spring-boot-angular-spring-security-jwt-authentication-back-end-spring-signup-request

  • /api/auth/signin -> sign in

    spring-boot-angular-spring-security-jwt-authentication-back-end-spring-signin-request

– We expose 3 RestAPIs to test protected resources:

  • Access Successfully ->

    spring-boot-angular-spring-security-jwt-authentication-back-end-spring-access-user-role-request

  • Unauthorized ->

    spring-boot-angular-spring-security-jwt-authentication-back-end-spring-access-request-unauthorized

Technologies

– Spring Boot 2
– jjwt – 0.9.0
– Spring Security
– Spring JPA
– MySQL

Project Structure

spring-boot-angular-spring-security-jwt-authentication-back-end-spring-project-structure

model package defines 2 entities User & Role that have many-to-many relationship:

spring-security-jwt-json-web-token-authentication-springboot-spring-jpa-postgresql-uml-modeling

repository package contains interfaces that use Hibernate JPA to store/retrieve data from MySQL database.
controller package defines RestAPIs for user signup/signin and testing protected resources that is secured with JWT.
message package defines payload data transferred from user agents (Browser/RestClient…) to RestAPIs and message back.
security package is the main part of the project that implements JWT security.

Practice

Create SpringBoot project

Dependency for the Project:

Create Models

User model includes 5 attributes:

  • id
  • name
  • username
  • email
  • password

model/User.java

Role model with 2 attributes:

  • id
  • rolename

model/Role.java

model/RoleName.java

Implement Repository

repository/UserRepository.java

repository/UserRepository.java

For more details about Spring JPA with MySQL, please visit:
How to use Spring JPA MySQL | Spring Boot

Implement JWT Security

security/WebSecurityConfig.java

Create UserDetails Service

UserDetailsServiceImpl implements UserDetailsService and overrides loadUserByUsername() method.

loadUserByUsername method finds a record from users database tables to build a UserDetails object for authentication.

security/services/UserDetailsServiceImpl.java

UserPrinciple will implement UserDetails.
UserPrinciple is not used directly by Spring Security for security purposes.
It simply stores user information which is later encapsulated into Authentication objects. This allows non-security related user information (such as email addresses, telephone numbers etc) to be stored.

security/services/UserPrinciple.java

JWT Authentication Classes

JwtAuthTokenFilter extends OncePerRequestFilter.

org.springframework.web.filter.OncePerRequestFilter
-> Executes once per request. This is a filter base class that is used to guarantee a single execution per request dispatch. It provides a doFilterInternal method with HttpServletRequest and HttpServletResponse arguments.

Inside JwtAuthTokenFilter class, the doFilterInternal method will:

  • get JWT token from header
  • validate JWT
  • parse username from validated JWT
  • load data from users table, then build an authentication object
  • set the authentication object to Security Context

security/jwt/JwtAuthTokenFilter.java

JwtAuthEntryPoint is used to handle Error exception when having unauthorized requests.

security/jwt/JwtAuthEntryPoint.java

JwtProvider is an util class -> it implements useful functions:

  • generate a JWT token
  • valiate a JWT token
  • parse username from JWT token

security/jwt/JwtProvider.java

Implement RestControllers
Create Payload Message

LoginForm with username & password.

message/request/LoginForm.java

SignUpForm includes:

  • name
  • username
  • email
  • role
  • password

message/request/SignUpForm.java

JwtResponse object will be returned by SpringBoot server once an authentication is successful, it contains:

  • JWT Token
  • Schema Type of Token
  • Username
  • Array of User’s Authorities

message/response/JwtResponse.java

ResponseMessage object is just a message object.

message/response/ResponseMessage.java

RestAPIs Controller

AuthRestAPIs defines 2 APIs:

  • /api/auth/signup: sign up
    -> check username/email is already in use.
    -> create User object
    -> store to database
  • /api/auth/signin: sign in
    -> attempt to authenticate with AuthenticationManager bean.
    -> add authentication object to SecurityContextHolder
    -> Generate JWT token, then return JWT to client

controller/AuthRestAPIs.java

TestRestAPIs define 3 RestAPIs:

  • /api/test/user -> access by users has USER_ROLE or ADMIN_ROLE
  • /api/test/pm -> access by users has USER_PM or ADMIN_ROLE
  • /api/test/admin -> access by users has ADMIN_ROLE

controller/TestRestAPIs.java

Configure Spring Datasource, JPA and define App Properties

application.properties

Run & Check Results
Start SpringBoot

– Start Springboot server by commandline mvn spring-boot:run

– Check database tables ->

spring-boot-angular-spring-security-jwt-authentication-back-end-mysql-tables-schema

– Insert data to roles table ->

SignUp

Sign-Up 3 users:

  • Jack has ROLE_USER role
  • Adam has ROLE_PM & ROLE_USER roles
  • Thomas has ROLE_ADMIN role

spring-boot-angular-spring-security-jwt-authentication-back-end-sign-up

– Check database’s tables ->

spring-boot-angular-spring-security-jwt-authentication-back-end-sign-up-database

SignIn and Access Protected Resources

Jack can access api/test/user url, can NOT access others.

-> Sign In:

spring-boot-angular-spring-security-jwt-authentication-back-end-sign-in-user

-> Access Protected Resources:

spring-boot-angular-spring-security-jwt-authentication-back-end-access-user-api-success-with-user-role

spring-boot-angular-spring-security-jwt-authentication-back-end-access-pm-role-fail-with-user-role

Thomas can access all URLs.

-> Sign In:

spring-boot-angular-spring-security-jwt-authentication-back-end-sign-in-admin

-> Access Protected Resources:

spring-boot-angular-spring-security-jwt-authentication-back-end-access-user-api-success-with-admin-role

spring-boot-angular-spring-security-jwt-authentication-back-end-access-pm-api-success-with-admin-role

spring-boot-angular-spring-security-jwt-authentication-back-end-access-admin-api-success-with-admin-role

Adam can access api/test/user and api/test/pm url.
Can NOT access /api/test/admin url.

SourceCode

SpringBootJwtAuthentication

By grokonez | October 26, 2018.



Related Posts


2 thoughts on “Angular Spring Boot JWT Authentication example | Angular 6 + Spring Security + MySQL Full Stack – Part 2: Build Backend”

    1. Not sure if it is, but I am very happy with Postman. It was a web browser (chrome) plugin but is now available as a standalone program.

Got Something To Say:

Your email address will not be published. Required fields are marked *

*