java - Spring Security SwitchUserFilter exitUserUrl 被忽略?

标签 java spring security spring-security

我在使用 spring security 的 SwitchUserFilter 时遇到问题。当我使用 ADMIN 角色登录时,我可以切换用户并再次切换回来。问题是,当第二次切换用户时,我似乎无法切换回来。当我直接在浏览器中转到/secured/switch/back 时,这会显示在我的日志中。

[FilterChainProxy] : /secured/admin at position 1 of 10 in additional filter chain; firing Filter: 'SecurityContextPersistenceFilter'
...
[AbstractSecurityInterceptor] : Secure object: FilterInvocation: URL: /secured/admin; Attributes: [hasRole('ADMIN')]
[AbstractSecurityInterceptor] : Previously Authenticated: org.springframework.security.authentication.UsernamePasswordAuthenticationToken@99f3cebe: Principal: harry [OTHER]; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@2cd90: RemoteIpAddress: 0:0:0:0:0:0:0:1; SessionId: 756CEC9064C2B1B4D788624786F26137; Granted Authorities: OTHER, Switch User Authority [ROLE_PREVIOUS_ADMINISTRATOR,org.springframework.security.authentication.UsernamePasswordAuthenticationToken@6b846d6c: Principal: max [ADMIN]; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@fffe9938: RemoteIpAddress: 0:0:0:0:0:0:0:1; SessionId: 26B09EEF635C1758BE96B86AB6354434; Granted Authorities: ADMIN]
[AffirmativeBased] : Voter: org.springframework.security.web.access.expression.WebExpressionVoter@3e35ec54, returned: -1
[ExceptionTranslationFilter] : Access is denied (user is not anonymous); delegating to AccessDeniedHandler

通常,当用户使用配置的 /secured/switch/back url 切换回来时,FilterChainProxy 开始过滤 URL /secured/switch/的请求回来。但是,第二次 URL 更改为 /secured/admin 并且权限被拒绝。

有人知道这里可能发生什么吗?

我有以下配置。

<beans:bean id="switchUserProcessingFilter" 
    class="org.springframework.security.web.authentication.switchuser.SwitchUserFilter">

    <beans:property name="userDetailsService" ref="org.example.CustomUserDetailsService"/>
    <beans:property name="switchUserUrl" value="/secured/admin/switch/user" />
    <beans:property name="exitUserUrl" value="/secured/switch/back" />
    <beans:property name="usernameParameter" value="username" />
    <beans:property name="successHandler" ref="RedirectingAuthenticationSuccessHandler" />
</beans:bean>

<beans:bean id="authenticationSuccessHandler" class="org.example.RedirectingAuthenticationSuccessHandler" />

<http use-expressions="true" access-denied-page="/secured/access/denied" >
    <custom-filter ref="switchUserProcessingFilter" position="SWITCH_USER_FILTER" />

    <intercept-url pattern="/secured/login" access="permitAll()" />
    <intercept-url pattern="/secured/login/auth" access="permitAll()" />
    <intercept-url pattern="/secured/switch/back" access="hasAnyRole('ADMIN', 'OTHER')" />
    <intercept-url pattern="/secured/admin/**" access="hasRole('ADMIN')" />
    <intercept-url pattern="/secured/other/**" access="hasRole('OTHER')" />

    <form-login
            login-page='/secured/login'
            login-processing-url="/secured/login/auth"
            authentication-success-handler-ref="authenticationSuccessHandler"
            username-parameter="username"
            password-parameter="password"
            />

    <logout logout-url="/secured/logout" logout-success-url="/secured/login" />

和成功处理程序

public class RedirectingAuthenticationSuccessHandler implements AuthenticationSuccessHandler {

    private static final Logger logger = LoggerFactory.getLogger(RedirectingAuthenticationSuccessHandler.class);

    private static final RoleBasedRedirectStrategy redirectHandler = new RoleBasedRedirectStrategy();

    /*
     *  Redirect request based on user role.
     *
     *  For example:
     *      Role ADMIN redirects to /secured/admin
     *      Role OTHER redirects to /secured/other
     */
    @Override
    public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws ServletException, IOException {
        User user = (User) authentication.getPrincipal();
        logger.info("Authentication successful for {}", user);
        redirectHandler.handleRedirect(request, response, user);
    }
}

最佳答案

摘自问题评论:

Are you sure your redirectHandler is not sending permanent redirects (301)?

客户端可以缓存永久重定向。因此,可能不会有对 /secured/switch/back 的实际第二个请求,它会直接转到之前解析的成功 URL /secured/admin (这会导致访问被拒绝 (403),因为您仍以 OTHER 身份登录)。

顺便说一下,有method for sending temporary (302) redirects (Spring 的 DefaultRedirectStrategy 也使用):

response.sendRedirect(targetUrl);

关于java - Spring Security SwitchUserFilter exitUserUrl 被忽略?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19201549/

相关文章:

java - 使用maven的spring hibernate集成中的org.springframework.beans.factory.BeanCreationException

java - Spring Security Acl级别类权限

java - 如何创建使用 SAX 解析 xml 的处理程序?

python - 使用 ast 和白名单使 python 的 eval() 安全?

java - SVNKit : list of updated/added files in a working copy after update operation

java - 在这种情况下如何使用 DISTINCT 创建 hibernate 条件

java - hibernate 拦截器

spring - HazelCast IMap.values() 在 Tomcat 上给出 OutofMemory

C#应用程序破解

windows - Windows 批处理文件末尾的简单插入符 (^) 占用所有内存