我有以下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上放置某种过滤器,从而撤销用户的权限吗?
我可以“动态”撤销它吗?
答案 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);
}
}