Spring Security JWT Authentication + PostgreSQL – RestAPIs SpringBoot + Spring MVC + Spring JPA

spring-security-jwt-json-web-token-authentication-springboot-spring-jpa-postgresql-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 + PostgreSQL + Bootstrap
SQL Tutorial – MySQL Many-to-Many Relationship
Spring JPA Hibernate Many to Many – SpringBoot + PostgreSQL

Technologies

– Spring Boot
– jjwt – 0.9.0
– Spring Security
– Spring JPA
– PostgreSQL

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

Project Structure

We create a SpringBoot project as below:

spring-security-jwt-json-web-token-authentication-springboot-spring-jpa-postgresql-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 PostgreSQL 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-json-web-token-authentication-springboot-spring-jpa-postgresql-signup-ADAM

  • /api/auth/signin -> sign in

    spring-security-jwt-json-web-token-authentication-springboot-spring-jpa-postgresql-ADAM-sign-in

– We expose 3 RestAPIs to test protected resources:

  • Access Successfully ->

    spring-security-jwt-json-web-token-authentication-springboot-spring-jpa-postgresql-ADAM-access-USER-API-successfully

  • Unauthorized ->

    spring-security-jwt-json-web-token-authentication-springboot-spring-jpa-postgresql-ADAM-can-NOT-access-PM-API

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-json-web-token-authentication-springboot-spring-jpa-postgresql-list-all-tables

spring-security-jwt-json-web-token-authentication-springboot-spring-jpa-postgresql-schema-tables

spring-security-jwt-json-web-token-authentication-springboot-spring-jpa-postgresql-select-row-tables

– Insert data to roles table ->

spring-security-jwt-json-web-token-authentication-springboot-spring-jpa-postgresql-insert-record-to-roles-tables

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-json-web-token-authentication-springboot-spring-jpa-postgresql-signup-ADAM

– Check database’s tables ->

spring-security-jwt-json-web-token-authentication-springboot-spring-jpa-postgresql-record-table-after-signup

SignIn and Access Protected Resources

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

-> Access Protected Resources:

spring-security-jwt-json-web-token-authentication-springboot-spring-jpa-postgresql-ADAM-access-USER-API-successfully

spring-security-jwt-json-web-token-authentication-springboot-spring-jpa-postgresql-ADAM-can-NOT-access-PM-API

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

-> Sign In:

spring-security-jwt-json-web-token-authentication-springboot-spring-jpa-postgresql-JACK-sign-in

-> Access Protected Resources:

spring-security-jwt-json-web-token-authentication-springboot-spring-jpa-postgresql-JACK-can-access-USER-APIs

spring-security-jwt-json-web-token-authentication-springboot-spring-jpa-postgresql-JACK-can-access-PM-API-successfully

spring-security-jwt-json-web-token-authentication-springboot-spring-jpa-postgresql-JACK-can-NOT-access-ADMIN-API-successfully

Thomas can access all URLs.

-> Sign In:

spring-security-jwt-json-web-token-authentication-springboot-spring-jpa-postgresql-THOMAS-sign-in

-> Access Protected Resource:

spring-security-jwt-json-web-token-authentication-springboot-spring-jpa-postgresql-THOMAS-can-access-ADMIN-API-successfully

SourceCode

SpringBootJwtAuthentication

By grokonez | October 11, 2018.



Related Posts


2 thoughts on “Spring Security JWT Authentication + PostgreSQL – RestAPIs SpringBoot + Spring MVC + Spring JPA”

  1. Thanks so much. I lost a lot of time to find document about that. So, Iam really happy when I see your post. Once again, hope you have more post useful.

Got Something To Say:

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

*