Spring Security @PreAuthorize打破Jersey @Context UriInfo注入

时间:2014-02-05 18:56:59

标签: java groovy spring-security jersey jersey-2.0

我正在构建一个Jersey / Spring RESTful Web应用程序的问题。我想使用@PreAuthorize注释来保护我的端点。但是,我需要访问UriInfo,因为我使用查询参数。

一切正常,直到我保护方法,然后突然我的UriInfo为空。我很确定这与@PreAuthorize如何导致事物的范围有关 - 不再是在请求级别。

@Component
@Path("/equipment")
public class Equipment
{
    @Context 
    UriInfo ui;

    @PreAuthorize("hasAnyRole('ROLE_ANALYST', 'ROLE_DEVELOPER')")
    @GET
    @Produces(MediaType.APPLICATION_JSON)
    public def list() {
        println ui
        return [:]
    }

}

下面的简单类将打印“null”。

如果删除@PreAuthorize注释,则会得到预期结果 - org.glassfish.jersey.internal.inject.UriInfoInjectee@23b21e3

基于我在其他问题中看到的事情,让我提前说我的应用程序上下文已经有了这一行:

<security:global-method-security pre-post-annotations="enabled"/>

并且授权部分工作正常。这只是注入UriInfo失败了。

我使用的是Spring 3.1.4和Jersey 2.3。提供的代码是在Groovy中,但这不是问题。

感谢您的帮助。

2 个答案:

答案 0 :(得分:2)

所以,我提出了一个解决方案,让我解决我的问题,我将它留在这里为后代。答案并不能满足这一切的“原因”,但它确实让我的应用程序正常工作,而且它并不是真正的噱头。

我没有在类级别注入UriInfo,而是在方法级别注入它。我从here得到了这个想法。他们的解释是,如果方法签名可能会被修改,请将其注入其中。我猜Spring Security正在这样做,但我不明白为什么会破坏在类级注入的东西。

后人的工作代码:

@PreAuthorize("hasAnyRole('ROLE_ANALYST', 'ROLE_DEVELOPER')")
@GET
@Produces(MediaType.APPLICATION_JSON)
public def list(@Context UriInfo ui) {
    ...
}

答案 1 :(得分:1)

我遇到了同样的问题,并且已经与它斗争了几个星期了。建议的工作对我的用途来说并不实用。

我建议的另一种解决方法是将@PreAuthorize注释向下移动到服务层(或其他一些应用层),而不是直接在其余资源上使用它。这个解决方案对我来说也不实用,但我认为我将其添加为另一种可能性。