Issue
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.
Answered By - Airy
Answer Checked By - David Goodson (JavaFixing Volunteer)