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.
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.
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 https://dzone.com/articles/spring-oauth2-with-jwt-sample SpringBoot 2.0.0.M7 has a support on OAuth2 Login but this example https://spring.io/blog/2017/09/15/spring-security-5-0-0-m4-released 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 https://www.youtube.com/watch?v=LzNhedHo7pM and this example https://medium.com/@mohitsinha.it/spring-boot-reactive-tutorial-ffab309b2dcd will only use a basic authentication.
Does anyone know how I can secure my (/api/v1/book) endpoint using @EnableWebFluxSecurity annotation and OAuth2 with JWT?
Below has example on my RoutingConfiguration class.
@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<?> 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<?> 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))
);
}
}