Search code examples
jerseyjax-rsjava-ee-6security-context

What does the @Secure annotation do and what package is it apart of


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.


Solution

  • 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.