提问者:小点点

SwitchUserFilter与基本身份验证一起使用时在Spring Security性中不起作用


我在Spring Security中遇到SwitchUserFilter问题。我有以下配置:

<bean id="ldapUserSearch" class="org.springframework.security.ldap.search.FilterBasedLdapUserSearch">
    <constructor-arg name="searchBase" value=""/>
    <constructor-arg name="searchFilter" value="(uid={0})"/>
    <constructor-arg name="contextSource" ref="ldapContext"/>
</bean>

<security:ldap-server id="ldapContext" url="ldap://xxxxxxx"/>

<bean id="ldapAuthProvider" class="org.springframework.security.ldap.authentication.LdapAuthenticationProvider">
    <constructor-arg name="authenticator">
        <bean
            class="org.springframework.security.ldap.authentication.BindAuthenticator">
            <constructor-arg ref="ldapContext" />
            <property name="userSearch" ref="ldapUserSearch" />
        </bean>
    </constructor-arg>
    <constructor-arg name="authoritiesPopulator" ref="dbLDAPAuthPopulator" />
</bean>
<security:authentication-manager>
    <security:authentication-provider ref="ldapAuthProvider"/>
</security:authentication-manager>

并将相应的SwitchUserFilter bean创建为:

SwitchUserFilter switchUserFilter = new SwitchUserFilter();
switchUserFilter.setUserDetailsService(ldapUserDetailsService);
switchUserFilter.setTargetUrl("/");
switchUserFilter.setSwitchUserUrl("/impersonate");
switchUserFilter.setUsernameParameter("username");
switchUserFilter.setExitUserUrl("/unimpersonate");

当我转到url“/模拟”时,用户被正确模拟。但是,当重定向发送到目标url即“/”时,用户再次使用基本身份验证进行身份验证。

我看了一下SwitchUserFilter和BasicAuthenticationFilter的代码,似乎SU无法使用基本身份验证。

这就是发生的事情:

>

  • 当调用 /impersonate? username=xyz url时,它会转到SwitchUserFilter,它从ldap获取xyz用户的详细信息,然后在会话中设置安全上下文。代码片段如下:

    如果设置了,则尝试切换并存储原始的try{Authentication target etUser=尝试切换用户(request);

            // update the current context to the new target user
            SecurityContextHolder.getContext().setAuthentication(targetUser);
    
            // redirect to target url
            successHandler.onAuthenticationSuccess(request, response, targetUser);
        } catch (AuthenticationException e) {
            logger.debug("Switch User failed", e);
            failureHandler.onAuthenticationFailure(request, response, e);
        }
    
        return;
    

    因此,在SecurityContext中,您有关于xyz用户的信息。

    然后当它重定向到目标网址时,即. "/" basicAuthenticationFilter被调用,它检查用户是否经过身份验证。代码片段:

    身份验证存在Auth=SecurityContextHolder. getContext().getAuthentication();

        if(existingAuth == null || !existingAuth.isAuthenticated()) {
            return true;
        }
    
        // Limit username comparison to providers which use usernames (ie UsernamePasswordAuthenticationToken)
        // (see SEC-348)
    
        if (existingAuth instanceof UsernamePasswordAuthenticationToken && !existingAuth.getName().equals(username)) {
            return true;
        }
    
        // Handle unusual condition where an AnonymousAuthenticationToken is already present
        // This shouldn't happen very often, as BasicProcessingFitler is meant to be earlier in the filter
        // chain than AnonymousAuthenticationFilter. Nevertheless, presence of both an AnonymousAuthenticationToken
        // together with a BASIC authentication request header should indicate reauthentication using the
        // BASIC protocol is desirable. This behaviour is also consistent with that provided by form and digest,
        // both of which force re-authentication if the respective header is detected (and in doing so replace
        // any existing AnonymousAuthenticationToken). See SEC-610.
        if (existingAuth instanceof AnonymousAuthenticationToken) {
            return true;
        }
    
        return false;
    

    他们有办法解决这个问题吗?我可以覆盖BasicAuthenticationFilter吗?


  • 共1个答案

    匿名用户

    这个问题很老,但是如果有人遇到它,答案今天仍然有效。你没有显示你的

    您可以通过实现SwitchUserAuthorityChanger的扩展并将其引用传递给SwitchUserFilter来指定要在模拟时授予的自定义权限。