【问题标题】:Spring Security intercept url appears to be skipped/ignoredSpring Security 拦截 url 似乎被跳过/忽略
【发布时间】:2013-08-23 23:33:00
【问题描述】:

我想配置 spring 安全性,以便将一个特定资源锁定到一个组,其余资源可供任何登录用户使用。我的 security.xml 看起来像这样

<http auto-config="true" create-session="stateless" use-expressions="true">
    <intercept-url pattern="/server/**" access="hasRole('ROLE_DEV-USER')" method="POST" requires-channel="https"/>

    <intercept-url pattern="/**" access="isFullyAuthenticated()" method="POST" requires-channel="https"/>
    <intercept-url pattern="/**" access="isFullyAuthenticated()" method="PUT" requires-channel="https"/>
    <intercept-url pattern="/**" access="isFullyAuthenticated()" method="DELETE" requires-channel="https"/>

    <intercept-url pattern="/**" access="permitAll" method="GET" requires-channel="any"/>
    <intercept-url pattern="/**" access="permitAll" method="HEAD" requires-channel="any"/>
    <http-basic />
    <logout />
</http>

<authentication-manager>
    <authentication-provider>
        <user-service>
            <user name="admin" password="admin" authorities="ROLE_NOT-DEV-USER" />
            <user name="admin2" password="admin2" authorities="ROLE_DEV-USER" />
        </user-service>
    </authentication-provider>
</authentication-manager>

我希望唯一的管理员能够发布到服务器/启用和服务器/禁用。我实际看到的是 admin 和 admin2 都可以 POST 到服务器/启用资源。好像 /server/** 被忽略了,下一个更通用的拦截 URL 正在取而代之。启动日志显示正在加载的所有行

2013-08-21 15:07:42,124  INFO FilterInvocationSecurityMetadataSourceParser:134 - Creating access control expression attribute 'hasRole('ROLE_DEV-USER')' for /server/**
2013-08-21 15:07:42,125  INFO FilterInvocationSecurityMetadataSourceParser:134 - Creating access control expression attribute 'isFullyAuthenticated()' for /**
2013-08-21 15:07:42,125  INFO FilterInvocationSecurityMetadataSourceParser:134 - Creating access control expression attribute 'isFullyAuthenticated()' for /**
2013-08-21 15:07:42,126  INFO FilterInvocationSecurityMetadataSourceParser:134 - Creating access control expression attribute 'isFullyAuthenticated()' for /**
2013-08-21 15:07:42,126  INFO FilterInvocationSecurityMetadataSourceParser:134 - Creating access control expression attribute 'permitAll' for /**
2013-08-21 15:07:42,127  INFO FilterInvocationSecurityMetadataSourceParser:134 - Creating access control expression attribute 'permitAll' for /**

目前使用的是spring v3.1.2

【问题讨论】:

  • 您在测试期间使用 HTTPS 吗?
  • 问题是用户错误,下面回答我做错了什么!

标签: java spring spring-security roles


【解决方案1】:

拦截 URL 按照它们出现的顺序进行评估。来自http://static.springsource.org/spring-security/site/docs/3.0.x/reference/core-web-filters.html的文档

模式总是按照它们定义的顺序进行评估。因此它 重要的是,更具体的模式在更高的定义 列出比不太具体的模式。这反映在我们的示例中 上面,更具体的 /secure/super/ 模式看起来更高 比不太具体的 /secure/ 模式。如果它们颠倒过来,则 /secure/ 模式将始终匹配并且 /secure/super/ 模式 永远不会被评估。

..所以只要您的更具体的 URL 位于顶部,它应该可以工作。看看 spring security 如何评估并尝试匹配您的 URL 可能值得调试。抱歉,这不是一个真正的答案,但评论太大了。

【讨论】:

  • 不幸的是,文档是导致我在这里提出问题的原因。我们没有看到这种行为并且有点难过,希望缺少一个可以启用排序的设置
  • 这个答案是正确的。我的用法是错误的。我已将我的错误作为未接受的答案包含在下面以供参考
【解决方案2】:

模式需要扩展以包含用于匹配 servlet 的 url 模式

web.xml

<filter>
    <filter-name>springSecurityFilterChain</filter-name>
    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
    <filter-name>springSecurityFilterChain</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>
<servlet>
    <servlet-name>restServlet</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:applicationContext-dispatchservlet.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
    <servlet-name>restServlet</servlet-name>
    <url-pattern>/rest/*</url-pattern>
</servlet-mapping>

所以spring security需要servlet映射,加上请求映射来获取url并应用拦截

<http auto-config="true" create-session="stateless" use-expressions="true">
    <intercept-url pattern="/rest/server/**" access="hasRole('ROLE_DEV-USER')" method="POST" requires-channel="https"/>

    <intercept-url pattern="/**" access="isFullyAuthenticated()" method="POST" requires-channel="https"/>
    <intercept-url pattern="/**" access="isFullyAuthenticated()" method="PUT" requires-channel="https"/>
    <intercept-url pattern="/**" access="isFullyAuthenticated()" method="DELETE" requires-channel="https"/>

    <intercept-url pattern="/**" access="permitAll" method="GET" requires-channel="any"/>
    <intercept-url pattern="/**" access="permitAll" method="HEAD" requires-channel="any"/>
    <http-basic />
    <logout />
</http>

一旦缺少的 /rest 添加到模式中,它就会按预期工作

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-09-16
    • 2016-10-13
    • 2012-08-15
    • 2013-06-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-28
    相关资源
    最近更新 更多