0

我的 Web 应用程序使用 Spring Security 进行身份验证和授权。身份验证通过公司 SSO 进行预身份验证。但是,作为后备,应用程序使用基于表单的登录进行身份验证。这也是使用 Spring Security 通过在部署描述符中配置的身份验证提供程序列表来实现的。考虑一个由以下序列描述的典型场景。

  1. 如果企业 SSO 预认证失败,则会向用户显示登录页面。
  2. 输入的凭据被提交,由于 SSOPreAuthentication Provider 找不到主体(假设 SSO 失败),请求被转发到下一个身份验证提供程序,即 LdapAuthenticationProvider。

在这里,我偶然遇到的是使用 BindAuthenticator 的 LdapAuthenticationProvider 将用户名绑定到 LDAP,即使密码部分正确(仅匹配密码的前 8 个字符。其余字符被忽略)。

以下是我的部署描述符中的配置,与讨论相关

<?xml version="1.0" encoding="UTF-8"?>
<!-- DO NOT EDIT FILE GENERATED BY BUILD SCRIPT (edit the config template version) -->
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:security="http://www.springframework.org/schema/security"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
        http://www.springframework.org/schema/security
        http://www.springframework.org/schema/security/spring-security-2.0.4.xsd"><security:http auto-config="false" access-denied-page="/accessDenied.htm" access-decision-manager-ref="accessDecisionManager">
    <security:form-login login-page="/login.htm" authentication-failure-url="/login.htm?error=true" />
    <security:logout logout-success-url="/login.htm" />
    <security:intercept-url pattern="/**/*" access="ROLE_DENIED" />
</security:http>

<bean id="preauthSSOFilter" class="MySSOProcessingFilter">
    <security:custom-filter position="PRE_AUTH_FILTER" />
    <property name="principalRequestHeader" value="XX1" />
    <property name="credentialsRequestHeader" value="XX2" />
    <property name="ldapUserIdRequestHeader" value="XX3" />
    <property name="ldapDNRequestHeader" value="XX4" />
    <property name="ldapAuthenticator" ref="ldapBindAuthenticator" />
    <property name="anonymousUserIfPrincipalRequestHeaderMissing" value="[none]" />
    <property name="authenticationManager" ref="authenticationManager" />
</bean>

<bean id="ldapContextValidator" class="org.springframework.ldap.pool.validation.DefaultDirContextValidator" />

<bean id="ldapContextSource" class="org.springframework.security.ldap.DefaultSpringSecurityContextSource">
    <constructor-arg value="ldap://myLDAP.com:983/o=something.com"/>
</bean>

<bean id="ldapAuthenticationProvider" class="org.springframework.security.providers.ldap.LdapAuthenticationProvider">
    <security:custom-authentication-provider />
    <constructor-arg ref="ldapBindAuthenticator" />
    <constructor-arg ref="ldapAuthoritiesPopulator" />
</bean>

<bean id="ldapBindAuthenticator" class="org.springframework.security.providers.ldap.authenticator.BindAuthenticator">
    <constructor-arg ref="ldapContextSource"/>
    <property name="userSearch" ref="ldapUserSearch" />
</bean>


<bean id="ldapUserSearch" class="org.springframework.security.ldap.search.FilterBasedLdapUserSearch">
    <constructor-arg index="0" value=""/>
    <constructor-arg index="1" value="(uid={0})"/>
    <constructor-arg index="2" ref="ldapContextSource" />
</bean>

<bean id="ldapAuthoritiesPopulator" class="org.springframework.security.ldap.populator.UserDetailsServiceLdapAuthoritiesPopulator">
    <constructor-arg ref="userDetailsService" />
</bean>

以下是两种情况的日志跟踪:

  1. 密码完全错误时(所有字符错误)

18:34:13,599 DEBUG [FilterChainProxy] /j_spring_security_check 位于附加过滤器链中第 8 位的第 4 位;触发过滤器:'org.springframework.security.ui.webapp.AuthenticationProcessingFilter[order=700; ]' 18:34:13,599 DEBUG [AuthenticationProcessingFilter] 请求是处理身份验证 18:34:13,599 DEBUG [ProviderManager] 使用 org.springframework.security.providers.ldap.LdapAuthenticationProvider 进行身份验证尝试 18:34:13,599 DEBUG [FilterBasedLdapUserSearch] 正在搜索用户'@username@',用户搜索 [searchFilter:'(uid={0})',searchBase:'',范围:子树,searchTimeLimit:0,d​​erefLinkFlag:false] 18:34:13,599 调试 [AbstractContextSource] 主体: '' 18:34:13,943 DEBUG [AbstractContextSource] 在服务器 'ldap://myLDAP.com: 上获得了 Ldap 上下文:983/o=something.com' 18:34:14,130 调试 [DefaultSpringSecurityContextSource] 使用主体创建上下文:'uid=@username@, ou=people, l=AP, o=somthing.com' 18:34:14,458 调试 [ BindAuthenticator] 无法绑定为 uid=@username@, ou=people, l=AP: org.springframework.ldap.AuthenticationException: [LDAP: error code 49 - Invalid Credentials]; 嵌套异常是 javax.naming.AuthenticationException: [LDAP: error code 49 - Invalid Credentials]

  1. 当密码正确或部分(仅前 8 个字符匹配)正确时

18:30:11,849 DEBUG [FilterChainProxy] /j_spring_security_check 位于附加过滤器链中第 8 位的第 4 位;触发过滤器:'org.springframework.security.ui.webapp.AuthenticationProcessingFilter[order=700; ]' 18:30:11,849 DEBUG [AuthenticationProcessingFilter] 请求是处理身份验证 18:30:11,849 DEBUG [ProviderManager] 使用 org.springframework.security.providers.ldap.LdapAuthenticationProvider 进行身份验证尝试 18:30:11,849 DEBUG [FilterBasedLdapUserSearch] 正在搜索用户'@username@',使用用户搜索 [searchFilter:'(uid={0})',searchBase:'',范围:子树,searchTimeLimit:0,d​​erefLinkFlag:false] 18:30:11,849 调试 [AbstractContextSource] 主体: '' 18:30:12,193 DEBUG [AbstractContextSource] 在服务器 'ldap://myLDAP.com:

有人可以解释这种神秘的行为吗?

4

0 回答 0