title: Spring Boot Reactive OAuth2 with JWT
body: <p>I am currently developing an application with SpringBoot 2.0.0.M7 and spring-boot-starter-webflux. It also use Spring Boot WebFlux Functional Rest API and Spring Boot Actuator. </p>
  
  <p>Application itself is very simple and it works as expected. I can POST book (/api/v1/book) to the ArrayList and GET all books (/api/v1/book) from ArrayList. Rest API Documentation is available on (/) URL and Actuator endpoint is available on (/actuator) URL. </p>
  
  <p>Problem is that how can I secure my WebFlux Functional Rest API with OAuth2 and JWT? I can find many examples OAuth2 with JWT but they are for older Spring Boot. Here is one example <a href="https://dzone.com/articles/spring-oauth2-with-jwt-sample" rel="nofollow noreferrer">https://dzone.com/articles/spring-oauth2-with-jwt-sample</a>  SpringBoot 2.0.0.M7 has a support on OAuth2 Login but this example <a href="https://spring.io/blog/2017/09/15/spring-security-5-0-0-m4-released" rel="nofollow noreferrer">https://spring.io/blog/2017/09/15/spring-security-5-0-0-m4-released</a> does not tell how to use OAuth2 with JWT in a Rest API. I did not even find a full source code of that example. This video <a href="https://www.youtube.com/watch?v=LzNhedHo7pM" rel="nofollow noreferrer">https://www.youtube.com/watch?v=LzNhedHo7pM</a> and this example <a href="https://medium.com/@mohitsinha.it/spring-boot-reactive-tutorial-ffab309b2dcd" rel="nofollow noreferrer">https://medium.com/@mohitsinha.it/spring-boot-reactive-tutorial-ffab309b2dcd</a> will only use a basic authentication. </p>
  
  <p>Does anyone know how I can secure my (/api/v1/book) endpoint using @EnableWebFluxSecurity annotation and OAuth2 with JWT?</p>
  
  <p>Below has example on my <strong>RoutingConfiguration</strong> class. </p>
  
  <pre><code>@Configuration
  @EnableWebFlux
  public class RoutingConfiguration implements WebFluxConfigurer {
  
      private final static String API_URL = "api";
      private final MeterRegistry registry;
  
      public RoutingConfiguration(MeterRegistry registry) {
          this.registry = registry;
      }
  
      @Override
      public void addCorsMappings(CorsRegistry corsRegistry) {
          corsRegistry.addMapping(API_URL + "/**").allowedMethods("GET", "POST");
      }
  
      @Bean
      public RouterFunction&lt;?&gt; indexRouter(final IndexHandler indexHandler, final ErrorHandler errorHandler) {
          RouterFunctionMetrics metrics = new RouterFunctionMetrics(this.registry);
          return route(GET("/"), indexHandler::getRestApiDocs).filter(metrics.timer("http.request.index.page"));      
      }
  
      @Bean
      public RouterFunction&lt;?&gt; bookRouter(final BookHandler handler, final ErrorHandler errorHandler) {
          return 
                  nest(path(API_URL + "/v1/book"), 
                      nest(accept(MediaType.APPLICATION_JSON), 
                          route(GET("/"), handler::getAllBooks)
                          .andRoute(POST("/"), handler::saveBook)
                      ).andOther(route(RequestPredicates.all(), errorHandler::notFound))
                  );
      }
  }
  </code></pre>