Skip to content

Instantly share code, notes, and snippets.

@psamsotha
Last active March 1, 2017 16:53
Show Gist options
  • Select an option

  • Save psamsotha/52bfc93a364c4920bf37d8c54630842b to your computer and use it in GitHub Desktop.

Select an option

Save psamsotha/52bfc93a364c4920bf37d8c54630842b to your computer and use it in GitHub Desktop.
Jersey Entity Filtering with Security Annotations.
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import org.glassfish.jersey.logging.LoggingFeature;
import org.glassfish.jersey.message.filtering.SecurityEntityFilteringFeature;
import org.glassfish.jersey.server.ResourceConfig;
import org.glassfish.jersey.test.JerseyTest;
import org.glassfish.jersey.test.TestProperties;
import org.junit.Test;
import javax.annotation.security.RolesAllowed;
import javax.ws.rs.GET;
import javax.ws.rs.NotAuthorizedException;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.container.ContainerRequestContext;
import javax.ws.rs.container.ContainerRequestFilter;
import javax.ws.rs.container.PreMatching;
import javax.ws.rs.core.SecurityContext;
import javax.ws.rs.ext.Provider;
import java.io.IOException;
import java.security.Principal;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.core.IsNull.nullValue;
/**
* Run like any other unit test. Only two required dependencies
*
* See Stack Overflow http://stackoverflow.com/q/42519571/2587435
*
* <dependency>
* <groupId>org.glassfish.jersey.test-framework.providers</groupId>
* <artifactId>jersey-test-framework-provider-grizzly2</artifactId>
* <version>${jersey2.version}</version>
* </dependency>
* <dependency>
* <groupId>org.glassfish.jersey.media</groupId>
* <artifactId>jersey-media-json-jackson</artifactId>
* <version>${jersey2.version}</version>
* </dependency>
*
* @author Paul Samsotha.
*/
public class SecurityFilteringTest extends JerseyTest {
@JsonSerialize(include = JsonSerialize.Inclusion.NON_NULL)
public static class Model {
private String global;
private String secured;
public Model() {}
public Model(String global, String secured) {
this.global = global;
this.secured = secured;
}
public String getGlobal() { return this.global; }
public void setGlobal(String global) { this.global = global; }
@RolesAllowed({"ADMIN"})
public String getSecured() { return this.secured; }
public void setSecured(String secured) {this.secured = secured; }
}
@Path("resource")
public static class Resource {
@GET
@Produces("application/json")
public Model get() {
return new Model("global", "secured");
}
}
@Provider
@PreMatching
public static class SimpleAuthFilter implements ContainerRequestFilter {
private static final Map<String, User> userStore = new ConcurrentHashMap<>();
static {
userStore.put("peeskillet", new User("peeskillet", Arrays.asList("ADMIN", "USER")));
userStore.put("paulski", new User("paulski", Arrays.asList("USER")));
}
@Override
public void filter(ContainerRequestContext request) throws IOException {
final String authHeader = request.getHeaderString("Authorization");
final String username = authHeader.split("=")[1];
final User user = userStore.get(username);
if (user == null) {
throw new NotAuthorizedException("No good.");
}
request.setSecurityContext(new SimpleSecurityContext(user));
}
private static class SimpleSecurityContext implements SecurityContext {
private final User user;
SimpleSecurityContext(User user) {
this.user = user;
}
@Override
public Principal getUserPrincipal() {
return new Principal() {
@Override
public String getName() {
return user.getUsername();
}
};
}
@Override
public boolean isUserInRole(String role) {
return user.getRoles().contains(role);
}
@Override
public boolean isSecure() {
return false;
}
@Override
public String getAuthenticationScheme() {
return "simple";
}
}
private static class User {
private String username;
private List<String> roles;
User(String username, List<String> roles) {
this.username = username;
this.roles = roles;
}
public String getUsername() { return this.username; }
public List<String> getRoles() { return this.roles; }
}
}
@Override
public ResourceConfig configure() {
enable(TestProperties.DUMP_ENTITY);
enable(TestProperties.LOG_TRAFFIC);
return new ResourceConfig()
.register(SecurityEntityFilteringFeature.class)
.register(SimpleAuthFilter.class)
.register(Resource.class);
}
@Test
public void getGlobalPropertiesOnly() {
final Model model = target("resource")
.request()
.header("Authorization", "username=paulski")
.get()
.readEntity(Model.class);
assertThat(model.getGlobal(), is("global"));
assertThat(model.getSecured(), is(nullValue()));
}
@Test
public void getGlobalWithAdminProperties() {
final Model model = target("resource")
.request()
.header("Authorization", "username=peeskillet")
.get()
.readEntity(Model.class);
assertThat(model.getGlobal(), is("global"));
assertThat(model.getSecured(), is("secured"));
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment