使用活动目录的 Spring 安全认证失败
Posted
技术标签:
【中文标题】使用活动目录的 Spring 安全认证失败【英文标题】:Spring security authentication using active directory failed 【发布时间】:2015-11-16 22:51:42 【问题描述】:我一直在我们公司从事一个 Spring Web 应用程序项目。它曾经使用数据库对用户进行身份验证,但最近我们决定使用我们的活动目录服务器作为身份验证方的手段。因此,我们将 spring-security.xml 更改为以下代码:
<http auto-config="true" entry-point-ref="loginUrlAuthenticationEntryPoint">
<intercept-url pattern="/Content/**" access="IS_AUTHENTICATED_ANONYMOUSLY" />
<intercept-url pattern="/Desktop/New_Them/**" access="IS_AUTHENTICATED_ANONYMOUSLY" />
<intercept-url pattern="/App/Index" access="ROLE_USER" />
<intercept-url pattern="/App/**" access="IS_AUTHENTICATED_ANONYMOUSLY" />
<intercept-url pattern="/rest/clc/ClcLogPhon/**" access="IS_AUTHENTICATED_ANONYMOUSLY" />
<intercept-url pattern="/**" access="ROLE_USER" />
<custom-filter ref="concurrencyFilter" position="CONCURRENT_SESSION_FILTER" />
<logout logout-success-url="/App/Login" />
<remember-me key="myAppKey" />
<session-management
session-authentication-strategy-ref="sas">
</session-management>
<csrf />
<headers>
<xss-protection />
</headers>
</http>
<beans:bean id="contextSource"
class="org.springframework.security.ldap.DefaultSpringSecurityContextSource">
<beans:constructor-arg
value="ldap://192.168.1.199:389/DC=myDomain,DC=org" />
<beans:property name="userDn"
value="CN=myUsername,CN=Users,DC=myDomain,DC=org" />
<beans:property name="password" value="myPassword" />
</beans:bean>
<beans:bean id="ldapAuthProvider"
class="org.springframework.security.ldap.authentication.LdapAuthenticationProvider">
<beans:constructor-arg>
<beans:bean
class="org.springframework.security.ldap.authentication.BindAuthenticator">
<beans:constructor-arg ref="contextSource" />
<beans:property name="userDnPatterns">
<beans:list>
<beans:value>uid=0,ou=users</beans:value>
</beans:list>
</beans:property>
</beans:bean>
</beans:constructor-arg>
<beans:constructor-arg>
<beans:bean
class="org.springframework.security.ldap.userdetails.DefaultLdapAuthoritiesPopulator">
<beans:constructor-arg ref="contextSource" />
<beans:constructor-arg value="ou=groups" />
<beans:property name="groupRoleAttribute" value="ou" />
</beans:bean>
</beans:constructor-arg>
</beans:bean>
<authentication-manager>
<authentication-provider ref="ldapAuthProvider"/>
</authentication-manager>
Web 应用程序启动良好。但是当我想用之前在活动目录中声明的用户登录时,就会出现以下错误:
DEBUG UsernamePasswordAuthenticationFilter - Request is to process authentication
DEBUG ProviderManager - Authentication attempt using org.springframework.security.ldap.authentication.LdapAuthenticationProvider
DEBUG LdapAuthenticationProvider - Processing authentication request for user: m.fazel
DEBUG BindAuthenticator - Attempting to bind as uid=m.fazel,ou=users,dc=myDomain,dc=org
DEBUG DefaultSpringSecurityContextSource - Removing pooling flag for user uid=m.fazel,ou=users,dc=myDomain,dc=org
DEBUG BindAuthenticator - Failed to bind as uid=m.fazel,ou=users: org.springframework.ldap.AuthenticationException: [LDAP: error code 49 - 80090308: LdapErr: DSID-0C0903A9, comment: AcceptSecurityContext error, data 52e, v1db1]; nested exception is javax.naming.AuthenticationException: [LDAP: error code 49 - 80090308: LdapErr: DSID-0C0903A9, comment: AcceptSecurityContext error, data 52e, v1db1];
DEBUG DefaultListableBeanFactory - Returning cached instance of singleton bean 'sessionRegistry'
DEBUG DefaultListableBeanFactory - Returning cached instance of singleton bean 'logoutSuccessHandler'
DEBUG UsernamePasswordAuthenticationFilter - Authentication request failed: org.springframework.security.authentication.BadCredentialsException: Bad credentials
DEBUG UsernamePasswordAuthenticationFilter - Updated SecurityContextHolder to contain null Authentication
DEBUG UsernamePasswordAuthenticationFilter - Delegating to authentication failure handler org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler@560d9ba6
DEBUG TokenBasedRememberMeServices - Interactive login attempt was unsuccessful.
DEBUG TokenBasedRememberMeServices - Cancelling cookie
DEBUG SimpleUrlAuthenticationFailureHandler - Redirecting to /spring_security_login?login_error
DEBUG DefaultRedirectStrategy - Redirecting to '/hafizApps/spring_security_login?login_error'
从上面的调试结果可以看出,这是由于 Ldap 错误引起的:
LDAP: error code 49 - 80090308: LdapErr: DSID-0C0903A9, comment: AcceptSecurityContext error, data 52e, v1db1
但是,我已经使用JXplorer 连接到服务器。 ldap 连接设置中没有替代错误。我尝试连接的测试用户(即 m.fazel)也已在 ldap 中声明,如下图所示:
@jeemster 编辑后:
但是,uid 正是spring security ldap authentication 中写的内容。我改变了 spring-security.xml 就像 jeemster 说的那样,把 cn=0,ou=test 而不是 uid=0,ou=users .将 id="ldapAuthProvider" 的 bean 更改为如下所示的 bean:
<beans:bean id="ldapAuthProvider"
class="org.springframework.security.ldap.authentication.LdapAuthenticationProvider">
<beans:constructor-arg>
<beans:bean
class="org.springframework.security.ldap.authentication.BindAuthenticator">
<beans:constructor-arg ref="contextSource" />
<beans:property name="userDnPatterns">
<beans:list>
<beans:value>CN=0,OU=test</beans:value>
</beans:list>
</beans:property>
</beans:bean>
</beans:constructor-arg>
<beans:constructor-arg>
<beans:bean
class="org.springframework.security.ldap.userdetails.DefaultLdapAuthoritiesPopulator">
<beans:constructor-arg ref="contextSource" />
<beans:constructor-arg value="ou=groups" />
<beans:property name="groupRoleAttribute" value="ou" />
</beans:bean>
</beans:constructor-arg>
</beans:bean>
另外,我在测试组中创建了一个新用户并将其命名为 alialavi。在ldap中创建的新用户如下图所示。
如上图所示,从 JXplorer 捕获,新用户的可分辨名称是:
cn=alialavi,ou=test,dc=hafiz-co,dc=org
但是网页应用启动后,我在登录页面又看到了这个错误:
DEBUG UsernamePasswordAuthenticationFilter - Request is to process authentication
DEBUG ProviderManager - Authentication attempt using org.springframework.security.ldap.authentication.LdapAuthenticationProvider
DEBUG LdapAuthenticationProvider - Processing authentication request for user: alialavi
DEBUG BindAuthenticator - Attempting to bind as cn=alialavi,ou=test,dc=hafiz-co,dc=org
DEBUG DefaultSpringSecurityContextSource - Removing pooling flag for user cn=alialavi,ou=test,dc=hafiz-co,dc=org
DEBUG BindAuthenticator - Failed to bind as CN=alialavi,OU=test: org.springframework.ldap.AuthenticationException: [LDAP: error code 49 - 80090308: LdapErr: DSID-0C0903A9, comment: AcceptSecurityContext error, data 52e, v1db1]; nested exception is javax.naming.AuthenticationException: [LDAP: error code 49 - 80090308: LdapErr: DSID-0C0903A9, comment: AcceptSecurityContext error, data 52e, v1db1]
DEBUG UsernamePasswordAuthenticationFilter - Authentication request failed: org.springframework.security.authentication.BadCredentialsException: Bad credentials
DEBUG UsernamePasswordAuthenticationFilter - Updated SecurityContextHolder to contain null Authentication
DEBUG UsernamePasswordAuthenticationFilter - Delegating to authentication failure handler org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler@4481f947
DEBUG TokenBasedRememberMeServices - Interactive login attempt was unsuccessful.
再次导致新的 distinctName 出错:
cn=alialavi,ou=test,dc=hafiz-co,dc=org
虽然两个distinguishedName相同,但还是发生了错误。
【问题讨论】:
【参考方案1】:我会先尝试改变:
uid=0,ou=users
到
cn=0,ou=users
通常,uid 不是 Microsoft Active Directory 中的值。
但是,错误:
data 52e
当用户名有效但密码/凭据无效时返回 AFIK。
最后,从发布的内容来看,
m.fazel
是 samAccountName 而不是用户的 cn 或 uid。用于绑定的 LDAP DN 似乎是:
uid=m.fazel,ou=users,dc=myDomain,dc=org
此用户是否出现在目录中?
-吉姆
【讨论】:
提前感谢您的回复,我按照您在回复中所说的做了,然后编辑了问题。您可以在新的更新中看到结果。我完全同意你关于cn而不是uid的看法。但是,正如我在编辑版本中所说,这正是 spring 安全参考中所写的内容。我想知道您是否在我的问题中看到了新的更新。以上是关于使用活动目录的 Spring 安全认证失败的主要内容,如果未能解决你的问题,请参考以下文章
Grails - Spring 安全 ldap 活动目录身份验证 - 凭据错误错误