Spring Security 撤销权限

发布于 2024-11-26 14:12:38 字数 388 浏览 1 评论 0原文

我有以下 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 上放置某种过滤器,从而撤销用户的权限吗?

我可以“即时”撤销它吗?

I have the following Spring security configuration:

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

I would like to revoke "ROLE_ADMIN" authority from the user when he navigates out of "/auth/**" zone.

How can I achieve such functionality? Can I put some kind of filter on all URLs except /auth/** which revokes Authority from the user?

Can I revoke it "on the fly"?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

风吹雨成花 2024-12-03 14:12:38

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

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

我可以“即时”撤销它吗?

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

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

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

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


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

好吧,作为一个要求,这是有道理的。 (不过,作为一个假设的用户,我会发现简单地浏览网站就会导致我被注销,这很神秘和/或烦人。)

但我认为您不应该通过更改用户在网站上的角色来做到这一点。飞。如果您这样做,您可能会收到“权限被拒绝”响应,而不是重定向到登录页面。

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

I would like to revoke "ROLE_ADMIN" authority from the user when he navigates out of "/auth/**" zone.

How can I achieve such functionality? Can I put some kind of filter on all URLs except /auth/** which revokes Authority from the user?

Can I revoke it "on the fly"?

I think you are misunderstanding the meaning of the intercept-url element:

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

This does NOT say "grant the user ROLE_ADMIN in the /auth/** tree". It says, "a user who has ROLE_ADMIN is allowed to access pages in the /auth/** tree".

The idea that a user's role changes depending on what he / she is looking at is strange, to say the least.


What I'm trying to do is to validate username and password each time the user hits "/auth/**" psth.

OK, that kind of makes sense as a requirement. (Though, as a hypothetical user I would find it mysterious and/or annoying that simply navigating around the site cause me to be logged out.)

But I don't think you should do that by changing the user's role(s) on the fly. If you do that you are liable to get "Permission denied" responses instead of redirects to the login page.

What you really need to do is to put them back into the "not logged in" state. But even that can be a bit tricky. If pages in the /auth/** tree have links to stylesheets or script files, then when the browser fetches those links the security filters are liable to think that the user has navigated out of the /auth/** tree and log him out.

ゃ人海孤独症 2024-12-03 14:12:38

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

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);


  }
}

You should make custom chain configuration and insert custom filter in it. It will be something like this:

Spring security configuration file:

    <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 better to define after securityContextPersistenceFilter that populates and clears Application context. Than in your custom filter you will be able to get access to Authentication object through SecurityContextHolder and to change its authorities.

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);


  }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文