Search code examples
javajava-11micronaut

Equivalent of javax.ws.rs NameBinding in Micronaut?


I am working on porting an old HTTP server to Micronaut and I am stuck trying to port an authorization filter that used the javax.ws.rs NameBinding annotation to a Micronaut HTTP server filter. 90% of my endpoints/controllers use the NameBinding annotation I have so using the standard Micronaut HTTP server filter would be difficult.

One code smelly thought was to create a filter accepting all api endpoints (ie. @Filter("/**")) and then maybe storing a list of all the paths that don't require authorization and comparing that against the requested path.

Another hack I attempted to was to try and derive the target method with reflections through the request/chain but it seems that target method is held in an @Internal class which leads me to believe I should not be reflecting on the method from a filter. If I was able to reflect on the target method from a filter I could look for my old annotation and filter on that.

In general are there any guiding principles for providing filters to a large subset of controllers/methods excluding a handful, for example an inverse filter pattern (although this would also not be ideal)?

Is there any way in micronaut to manually control the injection of filters?


Solution

  • If you need a fine grained control over your endpoints, I'll go for micronaut AOP

    @Documented
    @Retention(RUNTIME)
    @Target(ElementType.METHOD)
    @Around
    @Type(AuthenticatedInterceptor.class)
    public @interface Authenticated {
    }
    

    and the interceptor coresponding

    @Singleton
    public class AuthenticatedInterceptor implements MethodInterceptor<Object, Object> {
    
        @Override
        public Object intercept(MethodInvocationContext<Object, Object> context) {
            final var authHeader = ServerRequestContext.currentRequest()
                    .map(HttpMessage::getHeaders)
                    .flatMap(HttpHeaders::getAuthorization)
                    .orElseThrow(() -> new RuntimeException("no header"));
    
            validate(authHeader);
    
            return context.proceed();
        }
    }
    

    then you'll have to add @Authenticated on each methods that need to be authenticated.

    UPDATE

    Micronaut security provides it's own @Secured annotation.