Skip to content

Next.js web application that uses JWT issued by Auth0 to access authenticated Spring Boot API

Notifications You must be signed in to change notification settings

itzg/try-nextjs-jwt-boot-api

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

25 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Next.js web application that uses JWT issued by Auth0 to access authenticated Spring Boot API

Setup

In the src/main/app directory create an .env file with the following variables populated from your Auth0 application config:

AUTH0_DOMAIN=...
AUTH0_CLIENT_ID=...
AUTH0_CLIENT_SECRET=...
BASE_URL=http://localhost:3000
AUTH0_COOKIE_SECRET=...

Running

Start the api/backend, replace YOURS with your Auth0 subdomain:

mvn spring-boot:run -Dspring-boot.run.jvmArguments="-Dauth0-subdomain=YOURS"

Start the frontend:

mvn frontend:npm@run-frontend

Implementation Notes

Solving 401 Unauthorized during CORS preflight in Spring Webflux

The CorsConfigurationSource in WebConfig is needed to fully configure CORS support in Spring Webflux. Without it, the fetch initiated from the browser

    const res = await fetch('http://localhost:8080/api/greeting', {
      headers: {
        Authorization: `Bearer ${idToken}`
      }
    });

will fail with this error shown in the browser console:

Access to fetch at 'http://localhost:8080/api/greeting' from origin 'http://localhost:3000' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.

With the Spring property logging.level.web=debug, the application logs provide a clue about why the CORS preflight failed:

o.s.w.s.adapter.HttpWebHandlerAdapter    : [599fe63a] HTTP OPTIONS "/api/greeting"
o.s.w.s.adapter.HttpWebHandlerAdapter    : [599fe63a] Completed 401 UNAUTHORIZED

The reason it results in a 401 is two-fold:

  • The OPTIONS request of the CORS preflight purposely limits the headers included, especially the Authorization header. It is actually the CORS response from the server that will indicate such headers are allowed.
  • So it's a catch-22 at preflight time...without the authorization header, Spring Security will fail the OPTIONS request to a protected path, /api/greeting in this case.

CORS registration via an implementation of addCorsMappings in WebFluxConfigurer doesn't seem to activate the CORS filter creation. Instead, the CorsWebFilter creation within ServerHttpSecurity.CorsSpec.getCorsFilter activates when a CorsConfigurationSource bean is present.

The following is a quick and overly permissive configuration that satisfies the filter creation. It is important to declare Authorization as an allowed header; otherwise, the browser will vaguely report the same CORS preflight failure since it knows the original fetch operation could not be executed without it.

  @Bean
  public CorsConfigurationSource corsConfigurationSource() {
    CorsConfiguration corsConfig = new CorsConfiguration();
    corsConfig.addAllowedOrigin(CorsConfiguration.ALL);
    corsConfig.addAllowedMethod(CorsConfiguration.ALL);
    corsConfig.addAllowedHeader("Authorization");

    final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
    source.registerCorsConfiguration("/api/**", corsConfig);

    return source;
  }

The Network tab of Chrome DevTools doesn't show the preflight details, so for the curious, here are the interesting bits of the CORS preflight for this particular application.

The request:

OPTIONS /api/greeting HTTP/1.1
Host: localhost:8080
Access-Control-Request-Method: GET
Access-Control-Request-Headers: authorization
Origin: http://localhost:3000
Sec-Fetch-Mode: cors
Sec-Fetch-Site: same-site

...and the response from Spring CORS processing:

HTTP/1.1 200 OK
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET
Access-Control-Allow-Headers: authorization

About

Next.js web application that uses JWT issued by Auth0 to access authenticated Spring Boot API

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published