Michael Piefel
Michael Piefel

Reputation: 19998

Unit Tests for Authenticated Resources in Dropwizard 0.8.0

I want to test my Jersey resources in a Dropwizard 0.8.0-rc2 application. An additional obstacle is that I use TestNG instead of JUnit, so I have to do some things by hand that I copied from DropwizardClientRule.

Now I have some resources that are secured by @Auth. In Dropwizard 0.7.1 I added the authenticator to the test application as follows:

DropwizardResourceConfig resourceConfig = DropwizardResourceConfig.forTesting(…);        
Authenticator<BasicCredentials, Identity> authenticator =
        credentials -> getAuthorizedIdentity();
resourceConfig.getSingletons().add(
        new BasicAuthProvider<>(authenticator, "TEST"));

Here, getAuthorizedIdentity() would fetch some test authorization. This would be passed to the @Auth annotated injected parameter. Now, of course, with Jersey 2 things have changed a bit. I tried:

DropwizardResourceConfig resourceConfig = DropwizardResourceConfig.forTesting(…);
Authenticator<BasicCredentials, Identity> authenticator =
        credentials -> getAuthorizedIdentity();
resourceConfig.register(AuthFactory.binder(
        new BasicAuthFactory<>(authenticator, "TEST", Identity.class)));

The effect is that I get 401 on all secured resources. Debugging shows that my authenticate function is never called at all! If I remove the registration, then I will not get 401s anymore (so the registration is not without effect), but now the secured resources are unsecured and get null for the @Auth annotated parameter.

So, how do I add the authenticator to the test context so it will work? The production code works fine with almost the same line.

Upvotes: 0

Views: 1697

Answers (2)

Matthias Wiedemann
Matthias Wiedemann

Reputation: 1609

This issue was fixed recently.

See https://github.com/dropwizard/dropwizard/pull/966

Upvotes: 1

ianastacio
ianastacio

Reputation: 125

I just had the same problem, after looking at the tests in the dropwizard-auth project I came to this solution, hope it helps.

public class ExamplesResourceTest extends JerseyTest
{
    @Override
    protected TestContainerFactory getTestContainerFactory()
        throws TestContainerException {
        return new GrizzlyWebTestContainerFactory();
    }

    @Override
    protected DeploymentContext configureDeployment() {
        return ServletDeploymentContext.builder(new ExampleTestResourceConfig())
            .initParam( ServletProperties.JAXRS_APPLICATION_CLASS, ExampleTestResourceConfig.class.getName() )
            .initParam( ServerProperties.PROVIDER_CLASSNAMES, ExampleResource.class.getName() )
            .build();
    }


    public static class ExampleTestResourceConfig extends DropwizardResourceConfig {

        private ObjectMapper mapper = Jackson.newObjectMapper();
        private Validator validator = Validation.buildDefaultValidatorFactory().getValidator();

        public ExampleTestResourceConfig() {
            super(true, new MetricRegistry());
            register( new JacksonMessageBodyProvider( mapper, validator ) );
            register( AuthFactory.binder( new BasicAuthFactory<>( new ExampleAuthenticator(), "realm", String.class ) ) );
        }
    }

    @Test
    public void exampleTest() throws AuthenticationException
    {
        Response response = target( "/api/example" )
            .request( MediaType.APPLICATION_JSON )
            .header( HttpHeaders.AUTHORIZATION, "Basic QmlsYm86VGhlU2hpcmU=" )
            .get();

        assertThat( response.getStatus() ).isEqualTo( 200 );
    }
}

Upvotes: 0

Related Questions