【问题标题】:Spring Security hasRole('ROLE_ADMIN') in config and @PreAuthorize("permitAll") not working?配置中的 Spring Security hasRole('ROLE_ADMIN') 和 @PreAuthorize("permitAll") 不起作用?
【发布时间】:2011-07-10 16:42:31
【问题描述】:

我正在尝试锁定我的整个应用程序,但特定的 URL/方法除外。

这是我的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(),它会按预期工作 - 但我正在尝试实现相反的效果。

任何建议将不胜感激!

【问题讨论】:

  • 我在同一个地方。你有没有找到解决办法?你是怎么做到的?
  • (>..如果我交换条件并拥有...) 这是因为/** 是“高于”(优先级高于)/products。如果您在 security-context.xml 中完成(全部),那么您必须 /products/** permitAll before /** "restrict"。

标签: spring annotations spring-security


【解决方案1】:

来自@PreAuthorize and intercept-url priority

&lt;intercept-url&gt; ... 优先于 (@PreAuthorize) 注释。 [,因为]&lt;intercept-url&gt; 在 URL 级别工作,在方法级别工作。


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

你必须用permitAll(或匿名..)声明/prodcuts/json拦截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

当将指定模式与传入请求匹配时,匹配按 元素声明的顺序进行。所以最具体的模式应该在前,最一般的模式应该在最后

【讨论】:

  • ..正如引用的答案所示:@PreAuthorize 可以限制/缩小&lt;intercept-url/&gt; 规则,但不能扩展/扩大/停用它。
【解决方案2】:

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

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

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

       @EnableGlobalMethodSecurity(prePostEnabled = true)

【讨论】:

    【解决方案3】:

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

    【讨论】:

    • 您提到的问题没有使用@PreAuthorize 注释来“解锁”登录控制器。我假设注释会覆盖全局配置,因为范围更具体。可能对方法调用更宽松的权限不会覆盖全局级别更严格的条件。
    • @Ben 它是另一种方式 - XML 配置覆盖注释(限制或扩展权限在这里无关紧要)。想象一个场景,您想在生产中运行的系统中调整授权。如果 Spring 设计者允许注解覆盖 XML,那么您将不得不编译代码,进行回归测试,然后部署它。
    猜你喜欢
    • 2015-12-09
    • 2020-07-25
    • 1970-01-01
    • 2020-06-24
    • 2021-11-17
    • 2020-06-15
    • 2016-02-16
    • 2015-08-27
    • 2013-10-19
    相关资源
    最近更新 更多