Spring Security撤销权限

时间:2011-07-27 22:30:10

标签: java spring java-ee spring-mvc spring-security

我有以下Spring安全配置:

<security:http>
     <security:intercept-url pattern="/**"  access="ROLE_USER"/>
     <security:intercept-url pattern="/auth/**"  access="ROLE_ADMIN"/>
....
</security:http> 

我想在用户导航出“/ auth / **”区域时撤消用户的“ROLE_ADMIN”权限。

我如何实现这样的功能?我可以在除了/ auth / **之外的所有URL上放置某种过滤器,从而撤销用户的权限吗?

我可以“动态”撤销它吗?

2 个答案:

答案 0 :(得分:1)

  

我想在用户导航出“/ auth / **”区域时撤消用户的“ROLE_ADMIN”权限。

     

我如何实现这样的功能?我可以在除了/ auth / **之外的所有URL上放置某种过滤器,从而撤销用户的权限吗?

     

我可以“动态”撤销它吗?

我认为你误解了intercept-url元素的含义:

<security:intercept-url pattern="/auth/**"  access="ROLE_ADMIN"/>

这并不是说“授予 ROLE_ADMIN树中的用户/auth/**”。它说,“拥有 ROLE_ADMIN的用户可以访问/auth/**树中的网页”。

用户的角色根据他/她正在看的内容而改变的想法至少可以说是奇怪的。


  

我想要做的是每次用户点击“/ auth / **”psth时验证用户名和密码。

好的,这种要求是有道理的。 (尽管如此,作为一个假设的用户,我会发现它很神秘和/或令人讨厌,只是在网站上导航导致我被注销。)

但我不认为你应该通过动态改变用户的角色来做到这一点。如果您这样做,您将有可能获得“权限被拒绝”响应,而不是重定向到登录页面。

您真正需要做的是将它们重新置于“未登录”状态。但即使这样也有点棘手。如果/auth/**树中的页面包含指向样式表或脚本文件的链接,那么当浏览器获取这些链接时,安全过滤器可能会认为用户已导航出/auth/**树并将其注销

答案 1 :(得分:0)

您应该进行自定义链配置并在其中插入自定义过滤器。它将是这样的:

Spring安全配置文件:

    <bean id="springSecurityFilterChain" class="org.springframework.security.web.FilterChainProxy">
        <security:filter-chain-map path-type="ant">


        <security:filter-chain pattern="/**" filters="
            securityContextPersistenceFilter,
            revokeAuthRoleFilter,
            .. all the other filters here
            filterSecurityInterceptor"
        />
    </security:filter-chain-map>
    </bean>

     <!--Stores SecurityContext between requests and clears SecutityContextHolder-->
    <bean id="securityContextPersistenceFilter" class="org.springframework.security.web.context.SecurityContextPersistenceFilter"/>

     <bean id="revokeAuthRoleFilter" class="com.package.RevokeAuthRoleFilter">

     <!--This filter is called when user is authenticated. It grants access to resources-->
     <bean id="filterSecurityInterceptor"
      class="org.springframework.security.web.access.intercept.FilterSecurityInterceptor">
           <property name="authenticationManager" ref="authenticationManager"/>
           <property name="accessDecisionManager" ref="accessDecisionManager"/>
           <property name="securityMetadataSource">
              <security:filter-security-metadata-source use-expressions="true">
                 <security:intercept-url pattern='auth/**/' access="hasAnyRole('ROLE_ADMIN')"/>
                 <security:intercept-url pattern='/**' access="hasAnyRole('ROLE_USER')"/>
              </security:filter-security-metadata-source>
          </property>
     </bean>

RevokeAuthRoleFilter更好地定义在填充和清除应用程序上下文的securityContextPersistenceFilter之后。与自定义过滤器相比,您将能够通过SecurityContextHolder访问Authentication对象并更改其权限。

public class RevokeAuthRoleFilter extends GenericFilterBean {

   @Override
   public void doFilter(ServletRequest req, ServletResponse resp, FilterChain filterChain) throws IOException, ServletException {

       HttpServletRequest request = (HttpServletRequest) req;
       HttpServletResponse response = (HttpServletResponse) resp;

       //check current URI or URL for specific conditions (/auth/)
       String uri = reques.getRequestURI();
       if(uri.contains("/auth/"))   {
          //get Authentication object from Security and do something with it
          Authentication authentication =  SecurityContextHolder.getContext().getAuthentication();
       }

       //pass execution to other filters in chain
       filterChain.doFilter(request, response);


  }
}