SecurityContext不适用于@RolesAllowed

时间:2014-02-03 19:46:11

标签: java-ee jersey tomcat7 jax-rs

我目前正在Tomcat 7中使用Jersey 2.5.1创建后端服务器。为了安全起见,我正在使用@RolesAllowed@PermitAll等注释,并且我创建了自定义ContainerRequestFilterSecurityContext

我的问题是,当我的@RolesAllowed注释资源被请求时,即使我强制isUserInRole(role)方法返回true,它也会拒绝权限。但是,我的filter方法被调用。你有什么建议吗?我将在下面粘贴一些相关代码。

我的ContainerRequestFilter实施:

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

我的SecurityContext实施:

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;
    }

}

我的资源:

@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();
    }
}

我的ResourceConfig

@ApplicationPath("/")
public class MyApplication extends ResourceConfig {

    public MyApplication() {
        super(TestSecureResource.class);
        register(RolesAllowedDynamicFeature.class);
        register(AuthorizationFilter.class);
    }
}

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>

在这种特定情况下,我始终拒绝访问secureTest。澄清事情;我收到HTTP状态码403 - 禁止。

提前谢谢你们

2 个答案:

答案 0 :(得分:8)

确保您的AuthorizationFilter已在MyApplication注册(请参阅Registering Resources and Providers in Jersey 2)或注明@Provider(以便通过打包扫描将其发现)。

要使用安全注释(包javax.annotation.security)来限制对资源的访问,您需要注册RolesAllowedDynamicFeature

编辑1

您的AuthorizationFilter也必须注明@PreMatching,这意味着在匹配阶段(uri - &gt;资源)之前调用过滤器。否则,RolesAllowedDynamicFeature注册的过滤器(在此阶段调用)将无法看到自定义SecurityContext

编辑2

泽西岛用户指南 - Authorization - securing resources

答案 1 :(得分:0)

在实际应用程序中,定义自己的ResourceConfig意味着每次添加新资源(类)时都必须对其进行编辑。

避免这个问题的一个好方法是在RolesAllowedDynamicFeature中将<init-param>类注册到<servlet>中的web.xml,如下所示:

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

如果您这样做,那么您可以将其放入以动态注册特定包中的所有资源:

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