SecurityContext doesn't work with @RolesAllowed

匿名 (未验证) 提交于 2019-12-03 03:08:02

问题:

I'm currently creating a backend server using Jersey 2.5.1 in a Tomcat 7. For the security I'm using the @RolesAllowed, @PermitAll etc. annotations, and I have created my custom ContainerRequestFilter and SecurityContext.

My problem is that when my @RolesAllowed annotated resource is requested it always denies permission, even if I force my isUserInRole(role) method to return true. However, my filter method gets called. Do you have any suggestions? I'll paste some relevant code below.

My ContainerRequestFilter implementation:

public class AuthorizationFilter implements ContainerRequestFilter {     @Override     public void filter(ContainerRequestContext request) throws IOException     {         request.setSecurityContext(new Authorizer());     } } 

My SecurityContext implementation:

public class Authorizer implements SecurityContext {      @Override     public String getAuthenticationScheme() {         return null;     }      @Override     public Principal getUserPrincipal() {         return null;     }      @Override     public boolean isSecure() {         return false;     }      @Override     public boolean isUserInRole(String role) {         return true;     }  } 

My resource:

@Path("/secure") public class TestSecureResource {      @GET     @PermitAll     @Path("/nonsec_test/{text}")     public Response nonSecureTest(             @PathParam("text") String text){          return Response.status(200).entity(text).build();     }      @GET     @RolesAllowed("admin")     @Path("/sec_test/{text}")     public Response secureTest(             @PathParam("text") String text){          return Response.status(200).entity(text).build();     } } 

My ResourceConfig:

@ApplicationPath("/") public class MyApplication extends ResourceConfig {      public MyApplication() {         super(TestSecureResource.class);         register(RolesAllowedDynamicFeature.class);         register(AuthorizationFilter.class);     } } 

Relevant parts of my web.xml:

<servlet-name>Jersey Web Application</servlet-name>         <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>          <init-param>             <param-name>jersey.config.server.provider.packages</param-name>             <param-value>pkg.backend</param-value>         </init-param>          <init-param>             <param-name>javax.ws.rs.Application</param-name>             <param-value>pkg.backend.MyApplication</param-value>         </init-param>          <load-on-startup>1</load-on-startup>     </servlet> 

In this specific case, my access to secureTest is always denied. To clarify things; I'm getting HTTP status code 403 - Forbidden.

Thank you guys in advance

回答1:

Make sure you have your AuthorizationFilter either registered in your MyApplication (see Registering Resources and Providers in Jersey 2) or annotated with @Provider (to make it discoverable by package scanning).

In order to use security annotations (package javax.annotation.security) to restrict access to your resources you need to register RolesAllowedDynamicFeature.

EDIT 1

Your AuthorizationFilter has to be also annotated with @PreMatching which means that the filter is invoked before matching phase (uri -> resource). Otherwise filters registered by RolesAllowedDynamicFeature (invoked during this phase) won't see the custom SecurityContext.

EDIT 2

Jersey User Guide - Authorization - securing resources



回答2:

In a real application, defining your own ResourceConfig means you have to edit it every time you add a new resource (class).

A nice way to avoid that problem is to register the RolesAllowedDynamicFeature class in an <init-param> to the <servlet> in your web.xml like this:

<servlet>     <servlet-name>your_servelet_name</servlet-name>     <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>     <init-param>         <param-name>jersey.config.server.provider.classnames</param-name>         <param-value>org.glassfish.jersey.server.filter.RolesAllowedDynamicFeature</param-value>     </init-param> 

If you do that then you can put this in to dynamically register all resources in particular packages:

    <init-param>         <param-name>jersey.config.server.provider.packages</param-name>         <param-value>com.your-domain.your-packages-1,com.your-domain.your-packages-2</param-value>     </init-param> 


易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!