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


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

  2. Hello,

    I got this message when I tried to signin: Unable to load class named [io.jsonwebtoken.impl.DefaultJwtBuilder]

    my io.jsonwebtoken version is 0.10.5

  3. Hello, Mr. Grokonez.
    Firstly I would like to thank for the tuto, it’s very comprehensive.
    But I have an issue. I m using Eclipse JEE Photon, when I m trying to run your project it giving this error -> Error: Could not find or load main class SpringBootJwtAuthenticationApplication

    1. Hi Tomas, Is everything worked with you? because When running the project the tables are not got created. So I dont know what to do, any suggestion plz?

      1. Hi Ayind I’m using HSQLDB. I just had to update it’s version so that JpaRepository can work with it. If that’s not the case then maybe you’re misconfigured something in application.properties file.

  4. Hello, Excuse my English, I tried to implement this in payara server and I could not. Is there any way to do it ?. Thank you.

  5. Hello, great tutorial, I have tried to do in a war to deploy it in payara, when I do the test it generates the token well, but after accessing a resource it says not authorized, to a sending the token. could you give me a suggestion? Thank you. Excuse me, I’m learning English.

Got Something To Say:

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

*