Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to intercept requests by handler method in Spring WebFlux

I've got following interceptor in Spring MVC that checks if user can access handler method:

class AccessInterceptor : HandlerInterceptorAdapter() {

override fun preHandle(request: HttpServletRequest, response: HttpServletResponse, handler: Any?): Boolean {
    val auth: Auth =
        (if (method.getAnnotation(Auth::class.java) != null) {
            method.getAnnotation(Auth::class.java)
        } else {
            method.declaringClass.getAnnotation(Auth::class.java)
        }) ?: return true
    if (auth.value == AuthType.ALLOW) {
        return true
    }

    val user = getUserFromRequest(request) // checks request for auth token
    // and checking auth for out user in future.
    return renderError(403, response)

In my Controller I do annotate methods, like this:

@GetMapping("/foo")
@Auth(AuthType.ALLOW)
fun doesntNeedAuth(...) { ... }

@GetMapping("/bar")
@Auth(AuthType.ADMIN)
fun adminMethod(...) { ... }

In case if user has wrong token or no permissions, error is being returned.
Is it possible to do this in Spring WebFlux with annotation-style controllers?

like image 813
NikichXP Avatar asked Nov 17 '22 11:11

NikichXP


2 Answers

To solve that problem I would most probably use:

  • A Spring Reactive Web WebFilter from the WebHandler API to intercept the incoming request

  • The RequestMappingHandlerMapping to retrieve the method which handles the current request

@Autowired
RequestMappingHandlerMapping requestMappingHandlerMapping;

...
@Override
public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
    ...
    HandlerMethod handler = (HandlerMethod) requestMappingHandlerMapping.getHandler(exchange).toProcessor().peek();
    //your logic
}
like image 79
Rozart Avatar answered Mar 14 '23 22:03

Rozart


     @Component
     class AuditWebFilter(
          private val requestMapping: RequestMappingHandlerMapping
     ): WebFilter {

          override fun filter(exchange: ServerWebExchange, chain: WebFilterChain): Mono<Void> {
               // if not to call - then exchange.attributes will be empty
               // so little early initializate exchange.attributes by calling next line
               requestMapping.getHandler(exchange)

               val handlerFunction = exchange.attributes.get(HandlerMapping.BEST_MATCHING_HANDLER_ATTRIBUTE) as HandlerMethod
               val annotationMethod = handlerFunction.method.getAnnotation(MyAnnotation::class.java)

               // annotationMethod  proccesing here
          }
     }
like image 43
Ivan Avatar answered Mar 14 '23 23:03

Ivan