Spring Security JWT Authentication example – RestAPIs SpringBoot + Spring MVC + Spring JPA + MySQL

spring-security-jwt-json-web-token-authentication-springboot-spring-jpa-mysql-crud-restapi-feature-image

JSON Web Token defines a compact and self-contained way for securely transmitting information as a JSON object.
In the tutorial, we show how to build a SpringBoot Security RestAPIs with JSON Web Token (JWT).

Related posts:
Spring Security – JDBC Authentication – SpringBoot + MySQL + Bootstrap
SQL Tutorial – MySQL Many-to-Many Relationship
Spring JPA Hibernate Many to Many – SpringBoot + PostgreSQL

Series: Angular Spring Boot JWT Authentication example | Angular 6 + Spring Security + MySQL Full Stack

Technologies

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

JSON Web Token

JSON Web Token (JWT) defines a compact and self-contained way for securely transmitting information between parties as a JSON object.

Scenarios where JSON Web Tokens are useful:

  • Authorization: the most common scenario for using JWT. Single Sign On is a feature that widely uses JWT
  • Information Exchange: Because JWTs can be signed, JSON Web Tokens are a good way of securely transmitting information between parties.

JSON Web Tokens consist of 3 parts:

  • Header
  • Payload
  • Signature

-> JWT looks like Header-Base64-String.Payload-Base64-String.Signature-Base64-String

Header consists of two parts:

  • token type.
  • hashing algorithm.

-> Example:

Payload contains the claims. Claims are statements about an entity and additional information.
There are 3 types of claims ->

  • Registered claims -> These are a set of predefined claims: iss (issuer), exp (expiration time), sub (subject)
  • Public claims
  • Private claims

Example ->

Signature -> To create the signature part you have to take the encoded header, the encoded payload, a secret, the algorithm specified in the header, and sign that.

Example ->

Combine all together, we get 3 Base64-URL strings separated by dots,

-> Example:

When accessing a protected route or resource, the user agent should send the JWT, typically in the Authorization header using the Bearer schema.

-> Example:

See more at: Introduction to JSON Web Tokens

Overview

Demo

Project Structure

We create a SpringBoot project as below:

spring-security-jwt-authentication-restapi-springboot-spring-mvc-spring-jpa-mysql-project-structure

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

spring-security-jwt-springboot-restapi-jwt-json-web-token-authentication-many-to-many-user-role

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.

Goal

– We expose 2 RestAPIs to signup and signin:

  • /api/auth/signup -> sign up

    spring-security-jwt-authentication-restapi-springboot-spring-mvc-spring-jpa-mysql-sign-up-form

  • /api/auth/signin -> sign in

    spring-security-jwt-authentication-restapi-springboot-spring-mvc-spring-jpa-mysql-sign-in-with-user-role

– We expose 3 RestAPIs to test protected resources:

  • Access Successfully ->

    spring-security-jwt-authentication-restapi-springboot-spring-mvc-spring-jpa-mysql-access-user-api-success-with-user-role

  • Unauthorized ->

    spring-security-jwt-authentication-restapi-springboot-spring-mvc-spring-jpa-mysql-access-pm-api-fail-with-user-role

Practice

Create SpringBoot project

We create a SpringBoot project with below dependencies:

Create Models

User.java model contains 5 attributes:

  • id
  • name
  • username
  • email
  • password

Role.java model contains 2 attributes:

  • id
  • rolename

RoleName.java ->

Implement Repository

UserRepository ->

RoleRepository.java ->

Implement JWT Security

– Configure WebSecurityConfig.java:

@EnableWebSecurity is used to enable web security in a project.
@EnableGlobalMethodSecurity(prePostEnabled = true) is used to enable Spring Security global method security.

-> Example:

PasswordEncoder uses the BCrypt strong hashing function.

UserDetails Service

UserDetailsServiceImpl implements UserDetailsService that will override loadUserByUsername method.
loadUserByUsername method will find a record from users database tables to build a UserDetails object for authentication.

-> 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.

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.

In JwtAuthTokenFilter class, the doFilterInternal method will do:

  • 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

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

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

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

Implement RestControllers
Create Payload Message

LoginForm.java contains username & password ->

SignUpForm.java contains:

  • name
  • username
  • email
  • role
  • password

JwtResponse.java is returned by SpringBoot server after successful authentication, it contains 2 parts:

  • JWT Token
  • Schema Type of Token

RestAPIs Controller

AuthRestAPIs.java 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

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

Application Properties

application.properties file ->

Run & Check Results
Start SpringBoot

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

– Check database tables ->

spring-security-jwt-authentication-restapi-springboot-spring-mvc-spring-jpa-mysql-authentication-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-security-jwt-authentication-restapi-springboot-spring-mvc-spring-jpa-mysql-sign-up-form

– Check database’s tables ->

spring-security-jwt-authentication-restapi-springboot-spring-mvc-spring-jpa-mysql-data-in-tables-after-sign-up

SignIn and Access Protected Resources

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

-> Sign In:

spring-security-jwt-authentication-restapi-springboot-spring-mvc-spring-jpa-mysql-sign-in-with-user-role

-> Access Protected Resources:

spring-security-jwt-authentication-restapi-springboot-spring-mvc-spring-jpa-mysql-access-user-api-success-with-user-role

spring-security-jwt-authentication-restapi-springboot-spring-mvc-spring-jpa-mysql-access-pm-api-fail-with-user-role

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

-> Sign In:

spring-security-jwt-authentication-restapi-springboot-spring-mvc-spring-jpa-mysql-sign-in-with-admin-role-thomas

-> Access Protected Resources:

spring-security-jwt-authentication-restapi-springboot-spring-mvc-spring-jpa-mysql-access-user-api-success-with-pm-role-adam

spring-security-jwt-authentication-restapi-springboot-spring-mvc-spring-jpa-mysql-access-pm-api-success-with-pm-role-adam

spring-security-jwt-authentication-restapi-springboot-spring-mvc-spring-jpa-mysql-access-admin-api-fail-with-pm-role-adam

Thomas can access all URLs.

-> Sign In:

spring-security-jwt-authentication-restapi-springboot-spring-mvc-spring-jpa-mysql-sign-in-with-pm-role-adam

-> Access Protected Resource:

spring-security-jwt-authentication-restapi-springboot-spring-mvc-spring-jpa-mysql-access-admin-api-success-with-admin-role-admin

SourceCode

SpringBootJwtAuthentication
By grokonez | September 23, 2018.



Related Posts


9 thoughts on “Spring Security JWT Authentication example – RestAPIs SpringBoot + Spring MVC + Spring JPA + MySQL”

    1. I say the same. This is the best tutorial I ever read. I’m from Brazil, and I couldn’t find a tutorial like this one in portuguese or in english. I don’t speak english very well, but I could understand all this tutorial. Thanks a lot! 😀

  1. Hi grokonez
    thank you for your sharing. I have a question, shall we remove the UsernamePasswordFilter from the inctercepters of http.

Got Something To Say:

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

*