Spring Security intercept url似乎被跳过/忽略

时间:2013-08-21 14:23:23

标签: java spring spring-security roles

我希望配置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>

我希望唯一的管理员能够POST到服务器/启用和服务器/禁用。我实际看到的是admin和admin2都可以POST到服务器/启用资源。好像忽略了/ server / **,下一个更通用的intercept-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

2 个答案:

答案 0 :(得分:3)

拦截网址按其出现的顺序进行评估。来自http://static.springsource.org/spring-security/site/docs/3.0.x/reference/core-web-filters.html

的文档
  

模式总是按照定义的顺序进行评估。就这样吧   重要的是,更具体的模式定义更高   列表比不太具体的模式。这反映在我们的例子中   上面,更具体/安全/超级/模式显得更高   而不是特定/安全/模式。如果他们被逆转了   / secure / pattern总是匹配/ secure / super / pattern   永远不会被评估。

..所以只要您的更具体的网址位于顶部,它就应该有效。可能需要调试以查看Spring安全性如何评估并尝试匹配您的URL。对不起,不是一个真正的答案,但对于评论来说太大了。

答案 1 :(得分:1)

需要扩展模式以包含用于匹配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安全性需要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>

将缺失/休息添加到模式后,它按预期工作