DEV Community

Pavan K Jadda
Pavan K Jadda

Posted on

JWT authentication in Spring Security and Angular

This blog post explains the JSON web token(JWT) authentication using Spring Security, Spring Boot, Spring Data and Angular. Source code uploaded to Github repository

Image by MasterTux from Pixabay

Introduction

JSON Web Token (JWT) is an open standard (RFC 7519) that defines a compact and self-contained way for securely transmitting information between parties as a JSON object. This information can be verified and trusted because it is digitally signed. JWTs can be signed using a secret (with the HMAC algorithm) or a public/private key pair using RSA or ECDSA.

JWT Token structure

In its compact form, JSON Web Tokens consist of three parts separated by dots (.), which are:

  • Header
  • Payload
  • Signature

Therefore, a JWT typically looks like the following.

xxxxx.yyyyy.zzzzz

Header

The header typically consists of two parts: the type of the token, which is JWT, and the signing algorithm being used, such as HMAC SHA256 or RSA.

For example:

{  
  "alg": "HS256",  
  "typ": "JWT"  
}
Enter fullscreen mode Exit fullscreen mode

Then, this JSON is Base64Url encoded to form the first part of the JWT.

Payload

The second part of the token is the payload, which contains the claims. Claims are statements about an entity (typically, the user) and additional data. There are three types of claims: registered, public, and private claims.

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. Please read https://jwt.io/introduction/ for detailed workflow and description

Technologies

  1. Spring Boot 2.2.x
  2. Spring Security
  3. Spring Data JPA
  4. Java JWT library
  5. H2 embedded database

Implementation

There are many open-source JWT implementations available for all languages. In this blog post, we use Java jjwt library in this blog post.

pom.xml

  1. Create an empty spring boot project with spring boot, security dependencies and add dependencies as shown above
  2. Create UserController class that accepts username and password parameters and authenticates users through UsernamePasswordAuthenticationToken class
@PostMapping(value = {**"/authenticate"**,**"/login"**})  
**public** Object loginUser(@RequestParam String username, @RequestParam String password)  
{  
   Authentication authentication=**authenticationManager**.authenticate( **new** UsernamePasswordAuthenticationToken(username, password));  

**return** mapUserAndReturnJwtToken(authentication,**true**);  
}
Enter fullscreen mode Exit fullscreen mode

4. Create SecurityConfig class(shown below) that defines standard Spring Security configuration for the project.

5. Method public void configure(HttpSecurity http)allows all requests to login URLs since authentication is being done manually through in UserController class

SecurityConfig.java

6. JwtUtil class is responsible to issue and validate the tokens. In particular, createToken() method creates token with 24 hours expiration and sign with custom key from properties file(make sure keep this long and hard to guess)

JwtUtil.java

7. validateToken() method validates the supplied token by validating the expiration date

8. Create JwtRequestFilter filter that intercepts all requests from client and looks for Bearer token. If the token is present, extract the username and validate the expiration date.

9. If the token is valid, create new UsernamePasswordAuthenticationToken and set userDetails and userDetails authorities. Save this as Spring Security authentication object, which tells spring security that this user is authenticated and continue with security chain.

10. In order for this filter to work, in SecurityConfig add it before UsernamePasswordAuthenticationFilter

http.addFilterBefore(**jwtRequestFilter**,UsernamePasswordAuthenticationFilter.**class**);
Enter fullscreen mode Exit fullscreen mode

11. To show case the demo, generated Angular project with 2 pages. Login and Home page

Testing

  1. This project uses in H2 memory database as database. And schema.sql file in src/main/resources directory creates the required tables and data.sql file inserts sample users and roles
  2. Run the spring boot class JwtSpringSecurityApplication to start the application
  3. Now go to http://localhost:8080/h2-console to see the database and enter the credentials(shown below)

h2 in memory database

4. Check the existing users with the query SELECT * FROM CORE_USER. If you do not see any results, copy SQL statements from data.sql in src/main/resources and execute it

5. Now go to src/webapp directory and install all dependencies

$ npm install
Enter fullscreen mode Exit fullscreen mode

6. Start the Angular application with the following command

$ npm run start --watch
Enter fullscreen mode Exit fullscreen mode

7. Now go to http://localhost:4200 and you will be redirected to login page

8. Enter credentials admin/admin and you will be redirected to home page.

9. In home page, during initial load we use the token from previous page(stored as cookie) and get user information by presenting that token to spring boot application(just to make sure that token is valid)

9. See the network tab for JWT token with expiration date

Home page

Conclusion

Code is uploaded to Github for reference, Happy Coding :)

Discussion (0)