How to Optionally Protect a Resource with Custom Dropwizard Filter

旧巷老猫 提交于 2020-01-11 05:34:09

问题


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.

I have tried

@Path("/protectedPing")
@Produces(MediaType.TEXT_PLAIN)
public class ProtectedPing {

@GET
public String everybody() {

    return "pingpong";
}

@PermitAll
@POST
public String authenticated(){
    return "secret pingpong";
}

with

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

This seems to result in all requests to "/protectedPing" requiring basic auth.

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.


回答1:


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

Essentially what you want is:

  1. Create an annotation that indicates that you want to test for authentication (e.g. @AuthenticatePost)

  2. Create the resource and annotate the correct method with @AuthenticatePost

  3. Create your authentication filter (probably kind of like what you did above).

  4. 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";
        }
    }
}

Note, the DynamicFeature checks that the Authenticate Annotation is present, before registering the authentication with the feature context.

I hope that helps,

let me know if you have any questions.



来源:https://stackoverflow.com/questions/35732360/how-to-optionally-protect-a-resource-with-custom-dropwizard-filter

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!