如何使用自定义Dropwizard过滤器可选地保护资源

时间:2016-03-01 20:02:52

标签: java authentication jersey authorization dropwizard

我正在使用Dropwizard 0.9.2并且我想创建一个不需要GET身份验证的资源,并且需要对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());

这似乎导致了对&#34; / protectedPing&#34;的所有请求。要求基本认证。

在Dropwizard 0.9.2中,文档说如果我有一个可选的受保护资源,则创建一个自定义过滤器。我假设我需要这样做,但我不知道从哪里开始,或者我知道我真正需要做什么。

1 个答案:

答案 0 :(得分:5)

这更像是一个球衣问题,而不是一个投球问题。您可以在这里查看:https://jersey.java.net/documentation/latest/filters-and-interceptors.html

基本上你想要的是:

  1. 创建一个注释,指示您要测试身份验证(例如@AuthenticatePost)

  2. 使用@AuthenticatePost创建资源并注释正确的方法

  3. 创建您的身份验证过滤器(可能与您上面所做的类似)。

  4. 在动态功能中,测试传入资源中存在的注释。这将适用于post,false适用于get。然后直接在资源方法上注册AuthenticationFilter,而不是在资源上全局注册。

  5. 这将是我如何解决这个问题的半完整示例:

    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。

    我希望有所帮助,

    如果您有任何问题,请与我们联系。