Skip to content

Commit

Permalink
Register auth filter when @Auth is present
Browse files Browse the repository at this point in the history
  • Loading branch information
carlo-rtr committed Jul 14, 2015
1 parent ef71612 commit 2c3cca9
Show file tree
Hide file tree
Showing 8 changed files with 55 additions and 14 deletions.
21 changes: 12 additions & 9 deletions docs/source/manual/auth.rst
Expand Up @@ -176,36 +176,39 @@ For this to work properly, all chained factories must produce the same type of p
Protecting Resources
====================

To protect a resource, you need to mark your resource methods with one of the following annotations:
There are two ways to protect a resource. You can mark your resource method with one of the following annotations:

* ``@PermitAll``. All authenticated users will have access to the method.
* ``@RolesAllowed``. Access will be granted for the users with the specified roles.
* ``@DenyAll``. No access will be granted to anyone.

If you need access to the Principal, you need to add a parameter to your method ``@Context SecurityContext context``
Alternatively, you can annotate the parameter representing your principal with ``@Auth``. Note you must register a
jersey provider to make this work.

.. code-block:: java
environment.jersey().register(new AuthValueFactoryProvider.Binder<>(User.class));
@RolesAllowed("ADMIN")
@GET
public SecretPlan getSecretPlan(@Context SecurityContext context) {
User userPrincipal = (User) context.getUserPrincipal();
public SecretPlan getSecretPlan(@Auth User user) {
return dao.findPlanForUser(user);
}
or you can add register the following with jersey
You can also access the Principal by adding a parameter to your method ``@Context SecurityContext context``. Note this
will not automatically register the servlet filter which performs authentication. You will still need to add one of
``@PermitAll``, ``@RolesAllowed``, or ``@DenyAll``. This is not the case with ``@Auth``. When that is present, the auth
filter is automatically registered to facilitate users upgrading from older versions of Dropwizard

.. code-block:: java
environment.jersey().register(new AuthValueFactoryProvider.Binder<>(User.class));
@RolesAllowed("ADMIN")
@GET
public SecretPlan getSecretPlan(@Auth User user) {
public SecretPlan getSecretPlan(@Context SecurityContext context) {
User userPrincipal = (User) context.getUserPrincipal();
return dao.findPlanForUser(user);
}
If there are no provided credentials for the request, or if the credentials are invalid, the
provider will return a scheme-appropriate ``401 Unauthorized`` response without calling your
resource method.
Expand Down
Expand Up @@ -12,6 +12,7 @@
import javax.ws.rs.container.DynamicFeature;
import javax.ws.rs.container.ResourceInfo;
import javax.ws.rs.core.FeatureContext;
import java.lang.annotation.Annotation;

/**
* A {@link DynamicFeature} that registers the provided auth filter
Expand All @@ -34,9 +35,19 @@ public AuthDynamicFeature(ContainerRequestFilter authFilter) {
@Override
public void configure(ResourceInfo resourceInfo, FeatureContext context) {
final AnnotatedMethod am = new AnnotatedMethod(resourceInfo.getResourceMethod());
final Annotation[][] parameterAnnotations = am.getParameterAnnotations();
if (am.isAnnotationPresent(RolesAllowed.class) || am.isAnnotationPresent(DenyAll.class) ||
am.isAnnotationPresent(PermitAll.class)) {
am.isAnnotationPresent(PermitAll.class)) {
context.register(authFilter);
} else {
for (Annotation[] annotations : parameterAnnotations) {
for (Annotation annotation : annotations) {
if (annotation instanceof Auth) {
context.register(authFilter);
return;
}
}
}
}
}
}
15 changes: 11 additions & 4 deletions dropwizard-auth/src/test/java/io/dropwizard/auth/AuthResource.java
Expand Up @@ -10,6 +10,7 @@
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.SecurityContext;
import java.security.Principal;

@Path("/test/")
@Produces(MediaType.TEXT_PLAIN)
Expand All @@ -18,15 +19,21 @@ public class AuthResource {
@RolesAllowed({"ADMIN"})
@GET
@Path("admin")
public String show(@Context SecurityContext securityContext) {
return "'" + securityContext.getUserPrincipal().getName() + "' has admin privileges";
public String show(@Auth Principal principal) {
return "'" + principal.getName() + "' has admin privileges";
}

@PermitAll
@GET
@Path("profile")
public String showForEveryUser(@Context SecurityContext securityContext) {
return "'" + securityContext.getUserPrincipal().getName() + "' has user privileges";
public String showForEveryUser(@Auth Principal principal) {
return "'" + principal.getName() + "' has user privileges";
}

@GET
@Path("implicit-permitall")
public String implicitPermitAllAuthorization(@Auth Principal principal) {
return "'" + principal.getName() + "' has user privileges";
}

@GET
Expand Down
Expand Up @@ -4,6 +4,8 @@
import com.google.common.collect.ImmutableList;
import io.dropwizard.auth.AuthDynamicFeature;
import io.dropwizard.auth.AuthResource;
import io.dropwizard.auth.AuthValueFactoryProvider;
import io.dropwizard.auth.PrincipalImpl;
import io.dropwizard.auth.util.AuthUtil;
import io.dropwizard.jersey.DropwizardResourceConfig;
import io.dropwizard.logging.BootstrapLogging;
Expand Down Expand Up @@ -128,6 +130,14 @@ public void transformsCredentialsToPrincipals() throws Exception {
.isEqualTo("'good-guy' has admin privileges");
}

@Test
public void transformsCredentialsToPrincipalsWhenAuthAnnotationExistsWithoutMethodAnnotation() throws Exception {
assertThat(target("/test/implicit-permitall").request()
.header(HttpHeaders.AUTHORIZATION, "Basic Z29vZC1ndXk6c2VjcmV0")
.get(String.class))
.isEqualTo("'good-guy' has user privileges");
}

@Test
public void respondsToNonBasicCredentialsWith401() throws Exception {
try {
Expand Down Expand Up @@ -159,6 +169,7 @@ public BasicAuthTestResourceConfig() {
super(true, new MetricRegistry());

register(new AuthDynamicFeature(getAuthFilter()));
register(new AuthValueFactoryProvider.Binder(Principal.class));
register(RolesAllowedDynamicFeature.class);
register(AuthResource.class);
}
Expand Down
Expand Up @@ -151,6 +151,7 @@ public static class BasicAuthTestResourceConfig extends DropwizardResourceConfig
public BasicAuthTestResourceConfig() {
super(true, new MetricRegistry());

register(new AuthValueFactoryProvider.Binder(Principal.class));
register(new AuthDynamicFeature(getAuthFilter()));
register(RolesAllowedDynamicFeature.class);
register(AuthResource.class);
Expand Down
Expand Up @@ -150,6 +150,7 @@ public ChainedAuthTestResourceConfig() {
.setAuthorizer(authorizer)
.buildAuthFilter();

register(new AuthValueFactoryProvider.Binder(Principal.class));
register(new AuthDynamicFeature(new ChainedAuthFilter<>(buildHandlerList(basicAuthFilter, oAuthFilter ))));
register(RolesAllowedDynamicFeature.class);
register(AuthResource.class);
Expand Down
Expand Up @@ -20,6 +20,8 @@
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.HttpHeaders;

import java.security.Principal;

import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.failBecauseExceptionWasNotThrown;

Expand Down Expand Up @@ -149,6 +151,7 @@ public static class BasicAuthTestResourceConfig extends DropwizardResourceConfig
public BasicAuthTestResourceConfig() {
super(true, new MetricRegistry());

register(new AuthValueFactoryProvider.Binder(Principal.class));
register(new AuthDynamicFeature(getAuthFilter()));
register(RolesAllowedDynamicFeature.class);
register(AuthResource.class);
Expand Down
Expand Up @@ -5,6 +5,7 @@
import io.dropwizard.auth.AuthDynamicFeature;
import io.dropwizard.auth.AuthFilter;
import io.dropwizard.auth.AuthResource;
import io.dropwizard.auth.AuthValueFactoryProvider;
import io.dropwizard.auth.util.AuthUtil;
import io.dropwizard.jersey.DropwizardResourceConfig;
import io.dropwizard.logging.BootstrapLogging;
Expand All @@ -21,6 +22,8 @@
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.HttpHeaders;

import java.security.Principal;

import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.failBecauseExceptionWasNotThrown;

Expand Down Expand Up @@ -143,6 +146,7 @@ public static class BasicAuthTestResourceConfig extends DropwizardResourceConfig
public BasicAuthTestResourceConfig() {
super(true, new MetricRegistry());

register(new AuthValueFactoryProvider.Binder(Principal.class));
register(new AuthDynamicFeature(getAuthFilter()));
register(RolesAllowedDynamicFeature.class);
register(AuthResource.class);
Expand Down

0 comments on commit 2c3cca9

Please sign in to comment.