Spring Security hasRole('ROLE_ADMIN')在config和@PreAuthorize(“permitAll”)不起作用?

时间:2011-03-07 22:05:54

标签: spring annotations spring-security

我正在尝试锁定整个应用,除了特定的网址/方法。

这是我的applicationContext-security.xml

<global-method-security pre-post-annotations="enabled"/>
<http use-expressions="true">
    <http-basic/>
    <intercept-url pattern="/**" access="hasRole('ROLE_ADMIN')" />
    <logout logout-success-url="/products" />
</http>

这是带有注释的类:

@RooWebScaffold(path = "products", formBackingObject = Product.class)
@RequestMapping("/products")
@Controller

public class ProductController {

    @RequestMapping(value="/json", headers = "Accept=application/json")
    @ResponseBody
    @PreAuthorize("permitAll")
    public String listJson() {
        return Product.toJsonArray(Product.findAllProducts());
    }

}

然而,它没有按预期工作。

如果我交换了条件并在配置中有permitAll而注释中的hasRole()它按预期工作 - 但我正在尝试实现相反的步骤。

非常感谢任何建议!

3 个答案:

答案 0 :(得分:0)

如果您使用的是XML配置,请不要忘记添加以下属性:

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

如果您使用的是Java配置,请不要忘记添加以下注释:

       @EnableGlobalMethodSecurity(prePostEnabled = true)

答案 1 :(得分:-1)

这与问题spring security 3 - Setting up a customized login几乎相似,如果您将所有访问权限(模式/ **)限制为role_admin,那么permitAll on / product将如何工作?解决方案是在/ product。

上提供IS_AUTHENTICATED_ANONYMOUSLY访问权限

答案 2 :(得分:-1)

来自@PreAuthorize and intercept-url priority

<intercept-url> ...优先于(@PreAuthorize)注释。 [,因为] <intercept-url>在URL级别起作用,而注释在方法级别起作用。


因此,必须在安全性配置中解决问题的解决方案(除@PreAuthorize注释之外)。

您必须使用/prodcuts/json(或匿名。)声明permitAll拦截URL。 /**之前的拦截URL模式如下:

...
<intercept-url pattern="/products/json" access="permitAll" />
<intercept-url pattern="/**" access="hasRole('ROLE_ADMIN')" />
...

来自https://docs.spring.io/spring-security/site/docs/current/reference/htmlsingle/#nsa-intercept-url

当将指定的模式与传入的请求进行匹配时,匹配将以顺序进行,其中元素将被声明 。因此,最具体的模式应该排在第一位,而最一般的模式应该排在最后