jakarta-eejax-rsjakarta-ee-security-api

How do I restrict acces to all my APIs to one user role and only allow other on a few of them in JAX-RS?


This is my Jersey Application Config:

@ApplicationPath("/ui/v1.0")
@RolesAllowed("admin")
public class AppConfig extends ResourceConfig {
    public AppConfig() {
        System.out.println("!!!!!! Insights v10 UI starts !!!!!....");
        packages("com.test.app.ws.v10.ui");
        register(SecurityFilter.class);
        register(AuthenticationExceptionMapper.class);
        register(RolesAllowedDynamicFeature.class);
    }
}

My authentication and authorization are working properly. I want all my APIs to have restricted access for one role only and only a few exceptions for other role types. Writing @RolesAllowed("admin") in all my web services is quite a tedious task as there are hundreds of them.

Is there a way to specify @RolesAllowed("admin") in such a way that all the web services take this by default and I can use @PermitAll only on the few exceptions?


Solution

  • You need to Override the RolesAllowedDynamicFeature and add a default role to every endpoint at the end of the configure method if there are no other role based annotations for that endpoint.

    @Override
    public void configure(final ResourceInfo resourceInfo, final FeatureContext configuration) {
        final AnnotatedMethod am = new AnnotatedMethod(resourceInfo.getResourceMethod());
    
        // DenyAll on the method take precedence over RolesAllowed and PermitAll
        if (am.isAnnotationPresent(DenyAll.class)) {
            configuration.register(new RolesAllowedDynamicFeature.RolesAllowedRequestFilter());
            return;
        }
    
        // RolesAllowed on the method takes precedence over PermitAll
        RolesAllowed ra = am.getAnnotation(RolesAllowed.class);
        if (ra != null) {
            System.out.println(Arrays.toString(ra.value()));
            configuration.register(new RolesAllowedDynamicFeature.RolesAllowedRequestFilter(ra.value()));
            return;
        }
    
        // PermitAll takes precedence over RolesAllowed on the class
        if (am.isAnnotationPresent(PermitAll.class)) {
            // Do nothing.
            return;
        }
    
        // DenyAll can't be attached to classes
    
        // RolesAllowed on the class takes precedence over PermitAll
        ra = resourceInfo.getResourceClass().getAnnotation(RolesAllowed.class);
        if (ra != null) {
            configuration.register(new RolesAllowedDynamicFeature.RolesAllowedRequestFilter(ra.value()));
        }
    
        // If no other role is assigned, assign a default role "admin"
        if (!am.isAnnotationPresent(DenyAll.class) && !am.isAnnotationPresent(PermitAll.class)
                && !am.isAnnotationPresent(RolesAllowed.class)) {
            configuration.register(new RolesAllowedDynamicFeature.RolesAllowedRequestFilter(new String[] {"admin"}));
        }
    }