Search code examples
javagoogle-app-engineweb.xmljersey-2.0

How do I configure my entity-filtering scope for security annotations in the web.xml?


Reading the jersey doc : https://jersey.java.net/documentation/latest/entity-filtering.html I was able to activate the SecurityEntityFilteringFeature by adding it to my web.xml along with other activated features.

So my web.xml's features part looks like that :

    ...
    <init-param>
        <param-name>jersey.config.server.provider.classnames</param-name>
        <param-value>
            org.glassfish.jersey.server.gae.GaeFeature;
            org.glassfish.jersey.server.mvc.jsp.JspMvcFeature;
            org.glassfish.jersey.media.multipart.MultiPartFeature;
            org.glassfish.jersey.server.filter.RolesAllowedDynamicFeature;
            org.glassfish.jersey.message.filtering.SecurityEntityFilteringFeature;
        </param-value>
    </init-param>
    ...

The annotations @PermitAll (which changes nothing) and @DenyAll (which always remove entity from json) work great.

The question is : to use the annotation @RolesAllowed I also need to register the roles in the entity-filtering scope as said in the documentation

EntityFilteringFeature.ENTITY_FILTERING_SCOPE - "jersey.config.entityFiltering.scope"

Defines one or more annotations that should be used as entity-filtering scope when reading/writing an entity.

But I can only configure it through my web.xml and I have nowhere to do the following :

new ResourceConfig()
// Set entity-filtering scope via configuration.
.property(EntityFilteringFeature.ENTITY_FILTERING_SCOPE, new Annotation[] {SecurityAnnotations.rolesAllowed("manager")})
// Register the SecurityEntityFilteringFeature.
.register(SecurityEntityFilteringFeature.class)
// Further configuration of ResourceConfig.
.register( ... );

Any guess ?


Solution

  • You can use a ResourceConfig and a web.xml together. It is not "either one or the other". For example

    <servlet>
        <servlet-name>MyApplication</servlet-name>
        <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
        <init-param>
            <param-name>javax.ws.rs.Application</param-name>
            <param-value>org.foo.JerseyConfig</param-value>
        </init-param>
    </servlet>
    
    package org.foo;
    
    public class JerseyConfig extends ResourceConfig {
        public JerseyConfig() {
            register(...);
            property(...);
        }
    }
    

    Both the web.xml and the ResourceConfig registrations/configuration/properties, etc will be used. You can see some other deployment options, here.

    If you really must stay away from the ResourceConfig (not sure why it would be such a problem), you can always create a Feature.

    @Provider
    public class MyFilteringFeature implements Feature {
    
        @Override
        public boolean configure(FeatureContext context) {
            context.property(...);
            context.register(...);
            return true;
        }
    }
    

    Then just register the feature (unless you are scanning packages, then it should be picked up with the @Provider annotation).