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

问题描述 投票:2回答:1

我在Spring安全性中遇到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");

当我转到网址“/ impersonate”时,用户可以正确地进行模拟。然而,当重定向被发送到目标URL,即“/”时,用户再次使用基本认证进行认证。

我查看了SwitchUserFilter和BasicAuthenticationFilter的代码,看起来SU不能用于基本身份验证。

这是发生的事情:

  1. 当调用/ impersonate?username = xyz url时,它会转到SwitchUserFilter,它从ldap获取xyz用户的详细信息,然后在会话中设置securitycontext。代码段如下: if(requiresSwitchUser(request)){//如果设置,则尝试切换并存储原始try {Authentication targetUser = attemptSwitchUser(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;
  2. 因此,在SecurityContext中,您可以获得有关xyz用户的信息。
  3. 然后当它重定向到目标URL时,即调用“/”basicAuthenticationFilter,它检查用户是否被认证。代码段:

身份验证existingAuth = 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;
  1. 你可以看到它检查existingAuth.getName().equals(username)),在这种情况下它是xyz。但是,登录用户不同,因此过滤器再次对用户进行身份验证,并重写SwitchUserFilter完成的所有工作。

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

java spring spring-security
1个回答
1
投票

这个问题很老了,但是如果有人遇到它,答案今天仍然有效。您没有为Spring Security显示<http />节,但是您需要确保模仿授予的角色与绕过authority身份验证所需的角色(/*)相同。如果不是,那么您将被要求进行身份验证。

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

© www.soinside.com 2019 - 2024. All rights reserved.