如何选择使用自定义 Dropwizard 过滤器保护资源
我正在使用 Dropwizard 0.9.2,我想创建一个不需要对 GET 进行身份验证并且需要对 POST 进行基本身份验证的资源.
I'm using Dropwizard 0.9.2 and I want to create a resource that requires no authentication for GET and requires basic authentication for POST.
我试过了
@Path("/protectedPing")
@Produces(MediaType.TEXT_PLAIN)
public class ProtectedPing {
@GET
public String everybody() {
return "pingpong";
}
@PermitAll
@POST
public String authenticated(){
return "secret pingpong";
}
与
CachingAuthenticator<BasicCredentials, User> ca = new CachingAuthenticator<>(environment.metrics(), ldapAuthenticator, cbSpec);
AdminAuthorizer authorizer = new AdminAuthorizer();
BasicCredentialAuthFilter<User> bcaf = new BasicCredentialAuthFilter.Builder<User>().setAuthenticator(ca).setRealm("test-oauth").setAuthorizer(authorizer).buildAuthFilter();
environment.jersey().register(bcaf);
environment.jersey().register(RolesAllowedDynamicFeature.class);
environment.jersey().register(new AuthValueFactoryProvider.Binder<>(User.class));
environment.jersey().register(new ProtectedPing());
这似乎导致对/protectedPing"的所有请求都需要基本身份验证.
This seems to result in all requests to "/protectedPing" requiring basic auth.
在 Dropwizard 0.9.2 中,文档说如果我有一个可选保护的资源,则创建一个自定义过滤器.我假设我需要这样做,但我不知道从哪里开始,或者我是否真的需要这样做.
In Dropwizard 0.9.2 the documentation says to create a custom filter if I have a resource that is optionally protected. I'm assuming I need to do that, but I don't know where to start, or if that I what I actually need to do.
推荐答案
这更像是球衣问题而不是 dropwizard 问题.您可以在这里查看:https://jersey.java.net/文档/最新/filters-and-interceptors.html
this is more of a jersey problem than a dropwizard problem. You can have a look here: https://jersey.java.net/documentation/latest/filters-and-interceptors.html
基本上你想要的是:
创建一个注释,表明您要测试身份验证(例如@AuthenticatePost)
Create an annotation that indicates that you want to test for authentication (e.g. @AuthenticatePost)
创建资源并使用@AuthenticatePost 注释正确的方法
Create the resource and annotate the correct method with @AuthenticatePost
创建您的身份验证过滤器(可能有点像您在上面所做的).
Create your authentication filter (probably kind of like what you did above).
在动态特性中,测试注解是否存在于传入的资源上.这对于 post 是 true,对于 get 是 false.然后直接在资源方法上注册AuthenticationFilter,而不是在资源上全局注册.
In the dynamic feature, test for the annotation to be present on the passed in resource. This will hold true for post, false for get. Then register the AuthenticationFilter directly on the resource method instead of globally on the resource.
这将是我如何解决这个问题的半完整示例:
This would be a semi-complete example of how I would solve this:
public class MyDynamicFeature implements DynamicFeature {
@Override
public void configure(ResourceInfo resourceInfo, FeatureContext context) {
if(resourceInfo.getResourceMethod().getAnnotation(AuthenticateMe.class) != null ) {
context.register(MyAuthFilter.class);
}
}
public class MyAuthFilter implements ContainerRequestFilter {
@Override
public void filter(ContainerRequestContext requestContext) throws IOException {
// do authentication here
}
}
public @interface AuthenticateMe {
}
@Path("myPath")
public class MyResource {
@GET
public String get() {
return "get-method";
}
@POST
@AuthenticateMe
public String post() {
return "post-method";
}
}
}
注意,DynamicFeature 会在向功能上下文注册身份验证之前检查是否存在 Authenticate Annotation.
Note, the DynamicFeature checks that the Authenticate Annotation is present, before registering the authentication with the feature context.
希望对你有帮助
如果您有任何问题,请告诉我.
let me know if you have any questions.
相关文章