I'm writing an API using Java EE, JAX-RS, Jersey. In doing this I've implemented my own security context and security filter.
Looking at questions like this one (How to get MIME type of uploaded file in Jersey) I've seen the @Secure annotation but what does it do? My hope was that is was an annotation that queries the isSecure method of the security context in the same way that @RolesAllowed does for checking if a user has the right to access a particular method. If so is there such a way of doing so with annotations or am I stuck to using the @Context to get the security context and just from that.
The @Secure
annotation seems to be a custom one. JAX-RS/Jersey does not support such feature out-of-the-box but it's not that hard to implement. Lets say you have your own @Secure
annotation and you want to do checks whether a communication channel is secure for methods annotated with this annotation. You need to create a custom ResourceFilterFactory in which you'll assign a special filter for such methods:
public class IsSecureResourceFilterFactory implements ResourceFilterFactory {
private class IsSecureFilter implements ResourceFilter, ContainerRequestFilter {
// ResourceFilter
@Override
public ContainerRequestFilter getRequestFilter() {
return this;
}
@Override
public ContainerResponseFilter getResponseFilter() {
return null;
}
// ContainerRequestFilter
@Override
public ContainerRequest filter(final ContainerRequest request) {
// Check whether the channel is secure.
if (request.isSecure()) {
return request;
}
// Throw an exception if it's not.
throw new WebApplicationException(Response.Status.FORBIDDEN);
}
}
@Override
public List<ResourceFilter> create(final AbstractMethod abstractMethod) {
// Add IsSecureFilter for resource methods annotated with @Secure annotation (ignore other resource methods).
return abstractMethod.isAnnotationPresent(Secure.class)
? Collections.<ResourceFilter>singletonList(new IsSecureFilter()): null;
}
}
Now you need to tell Jersey about this ResourceFilterFactory
. There are 2 ways:
via web.xml
<init-param>
<param-name>com.sun.jersey.spi.container.ResourceFilters</param-name>
<param-value>my.package.IsSecureResourceFilterFactory</param-value>
</init-param>
or via META-INF/services
mechanism - you need to create a file called META-INF/services/com.sun.jersey.spi.container.ResourceFilterFactory
which would contain a fully qualified name of your factory (in this case my.package.IsSecureResourceFilterFactory
) and make sure this file is on the class-path of your application.