在Micronaut中的javax.ws.rs NameBinding的等效方式是什么?

huangapple go评论77阅读模式
英文:

Equivalent of javax.ws.rs NameBinding in Micronaut?

问题

我正在将一个旧的HTTP服务器迁移到Micronaut,目前在尝试将使用javax.ws.rsNameBinding注解的授权过滤器迁移到Micronaut的HTTP服务器过滤器时遇到了困难。我的90%的端点/控制器使用了NameBinding注解,因此使用标准的Micronaut HTTP服务器过滤器可能会很困难。

一个可能的解决方案是创建一个接受所有API端点的过滤器(例如@Filter("/**")),然后可能存储一个不需要授权的所有路径列表,并将其与请求的路径进行比较。

我尝试过的另一个方法是通过请求/链路反射来推导目标方法,但似乎目标方法位于一个@Internal类中,这使我认为不应该从过滤器中反射该方法。如果我能够从过滤器中反射目标方法,我可以查找我的旧注解并进行过滤。

总体上,是否有任何指导原则,可以为大量控制器/方法提供过滤器,但排除其中少数几个?例如,是否有一种反向过滤器模式(尽管这也可能不是理想的解决方案)?

在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?

答案1

得分: 2

如果您需要对终端进行精细控制,我会选择 micronaut AOP

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

以及相应的拦截器

@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();
    }
}

然后您需要在每个需要进行身份验证的方法上添加 @Authenticated

更新

Micronaut 安全性提供了自己的 注解 @Secured

英文:

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.

huangapple
  • 本文由 发表于 2020年9月11日 12:42:45
  • 转载请务必保留本文链接:https://go.coder-hub.com/63840896.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定