Categories: AngularSpring Boot

Securing your Spring Boot and Angular app with JWT #1 – Introduction

You can use the JSON Web Token standard as a part of your authentication and authorisation solution in a project built with Spring Boot and Angular. Check out this post to learn how to apply Spring Security, AuthGuard and JWT to your apps.

What we are going to build

The goal is to secure a multi-module application, written in Java 11 with Spring Boot for the backend and Angular for the frontend. The project can be built into a single jar file using Maven but we can also run the Angular app separately during development with the  $ ng serve  command.

The finished project is available in the GitHub repository – little-pinecone/jwt-spring-boot-angular-scaffolding.

Architecture overview

You can see the final directory tree for the project on the image below:

The structure of the backend and frontend modules will be presented in the corresponding sections.

Requirements

I try to keep the project up to date. Visit the releases list to keep track of the current versions of frameworks and libraries used.
  • We are working on a Spring Boot 2.1.1 project with the Web and H2 dependencies. You  can read about setting up this project with Spring Initializr in How to create a new Spring Boot Project.
  • Angular CLI – a command line interface tool that generates a project as well as performs many development tasks.
    I’m working on Angular 7:
    $ ng --version
     
    Angular CLI: 7.1.4
    Node: 10.15.0
    OS: linux x64
    Angular: 
    ... 
    
    Package                      Version
    ------------------------------------------------------
    @angular-devkit/architect    0.11.4
    @angular-devkit/core         7.1.4
    @angular-devkit/schematics   7.1.4
    @schematics/angular          7.1.4
    @schematics/update           0.11.4
    rxjs                         6.3.3
    typescript                   3.1.6
  • Java 11 – In case of problems with building an app, the Debugging the “Fatal error compiling: invalid target release: 11” issue. How to switch your development environment and IntelliJ settings to Java 11 post may help you find the reason.
    $ java -version
    openjdk version "11" 2018-09-25
    OpenJDK Runtime Environment 18.9 (build 11+28)
    OpenJDK 64-Bit Server VM 18.9 (build 11+28, mixed mode)
  • This project was created on Kubuntu (Ubuntu 18.04 LTS) – remember to adjust commands if you don’t work on Linux OS.
    $ lsb_release -a
    Distributor ID:	Ubuntu
    Description:	Ubuntu 18.04.1 LTS
    Release:	18.04
    Codename:	bionic
  • For the IDE I recommend IntelliJ IDEA Community Edition.

The starting point

We will start with an application having:

  • a login page that is available for all users;
  • an API endpoint serving a hardcoded list of cookies;
  • a page displaying those cookies – we want to show it only to authorized users.

If you want to learn how to build a similar multi module application, check out the Integrate Angular with a Spring Boot project post.

Our starting point is marked by the 0.1.1 tag in the repository. From here we are beginning our work to secure the application.

This app serves two pages – one for the login form:

the second one for displaying cookies taken from the API:

We don’t want to show our treats to everyone, so we will apply the login/logout functionality to the project.

Mind the CORS configuration

In our Cookie dispenser app we have the Cross-Origin Resource Sharing already configured to allow calling the API and obtaining the Authorization header:

// jwt-spring-boot-angular-scaffolding/backend/src/main/java/in/keepgrowing/jwtspringbootangularscaffolding/config/DevCorsConfiguration.java
…
@Configuration
@Profile("development")
public class DevCorsConfiguration implements WebMvcConfigurer {

    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/api/**")
                .allowedMethods("GET", "POST", "PUT", "PATCH", "DELETE", "OPTIONS")
                .exposedHeaders("Authorization");
    }
}

We need this configuration activated only on the development environment to run frontend on  the default http://localhost:4200/. We don’t want to be forced to rebuild the whole app only to see the changes made solely in the frontend part.

The CORS config is not needed on the production environment as the project is build into a single jar file and the whole app is served from the same origin.

Mind the routing control

In our Cookie dispenser app Spring Boot already surrenders routing control to Angular:

// in.keepgrowing.jwtspringbootangularscaffolding.config/MvcConfiguration
…
@Configuration
public class MvcConfiguration implements WebMvcConfigurer {
    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/**")
                .addResourceLocations("classpath:/static/")
                .resourceChain(true)
                .addResolver(new PathResourceResolver() {
                    @Override
                    protected Resource getResource(String resourcePath, Resource location) throws IOException {
                        Resource requestedResource = location.createRelative(resourcePath);

                        return requestedResource.exists() && requestedResource.isReadable() ? requestedResource
                                : new ClassPathResource("/static/index.html");
                    }
                });
    }
…

If you are building a project on your own, remember to implement this feature. Check out the Make Spring Boot surrender routing control to Angular post to learn more.

Secure the backend module

Check out the Securing your Spring Boot and Angular app with JWT #2 – Backend post to see how to:

  • add Spring Security;
  • handle creating new users with their credentials;
  • create authentication and authorization filters;
  • generate JWT tokens;
  • implement login functionality;
  • configure security.

Secure the frontend module

Check out the Securing your Spring Boot and Angular app with JWT #3 – Frontend post to see how to:

  • handle login form;
  • acquire and store the JWT token from the API;
  • append the token to every API request;
  • handle logout functionality;
  • prevent an unauthorised user from accessing secured paths with AuthGuard.

If you want to see a similar project build with Spring Boot 2.1.2, Angular 7 and Java 11 check out the repository of Scrum_ally  – an app for project management.

Photo by Dhyamis Kleber on StockSnap

little_pinecone

View Comments

Recent Posts

Simplify the management of user roles in Spring Boot

Spring Security allows us to use role-based control to restrict access to API resources. However,…

3 years ago

Create a custom annotation to configure Spring Boot tests

A custom annotation in Spring Boot tests is an easy and flexible way to provide…

3 years ago

Keycloak with Spring Boot #4 – Simple guide for roles and authorities

Delegating user management to Keycloak allows us to better focus on meeting the business needs…

3 years ago

Keycloak with Spring Boot #3 – How to authorize requests in Swagger UI

Swagger offers various methods to authorize requests to our Keycloak secured API. I'll show you…

3 years ago

Keycloak with Spring Boot #2 – Spring Security instead of Keycloak in tests

Configuring our Spring Boot API to use Keycloak as an authentication and authorization server can…

3 years ago

Keycloak with Spring Boot #1 – Configure Spring Security with Keycloak

Keycloak provides simple integration with Spring applications. As a result, we can easily configure our…

3 years ago