使用 Spring Security 3.2、Spring Ldap 2.0 和 JavaConfig 的 Active Directory 身份验证
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/23295616/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Active Directory Authentication using Spring Security 3.2, Spring Ldap 2.0 and JavaConfig
提问by user3572914
I'm writing a web application that requires users to login. My company has an Active Directory server that I'd like to make use of for this purpose. However, I'm having trouble using Spring to authenticate the users credentials.
我正在编写一个需要用户登录的 Web 应用程序。我的公司有一台 Active Directory 服务器,我想将其用于此目的。但是,我在使用 Spring 对用户凭据进行身份验证时遇到了问题。
I'm using Spring Security 3.2.2, Spring Ldap 2.0.1 and Java 1.7.
我使用的是 Spring Security 3.2.2、Spring Ldap 2.0.1 和 Java 1.7。
The Web Application starts well, authentication against InMemory-Authentication works well, too, so the rest of my application seems to be configured correctly.
Web 应用程序启动良好,针对 InMemory-Authentication 的身份验证也运行良好,因此我的应用程序的其余部分似乎配置正确。
Here is my Config:
这是我的配置:
@Configuration
@EnableWebSecurity
public class LdapConfig extends WebSecurityConfigurerAdapter {
@Bean
public ActiveDirectoryLdapAuthenticationProvider activeDirectoryLdapAuthenticationProvider() {
val provider = new ActiveDirectoryLdapAuthenticationProvider("my.domain", "ldap://LDAP_ID:389/OU=A_GROUP,DC=domain,DC=tld");
provider.setConvertSubErrorCodesToExceptions(true);
provider.setUseAuthenticationRequestCredentials(true);
provider.setUseAuthenticationRequestCredentials(true);
return provider;
}
@Bean
public LoggerListener loggerListener() {
return new LoggerListener();
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(activeDirectoryLdapAuthenticationProvider());
}
@Override
protected void configure(HttpSecurity http) throws Exception {
// Configuration for Redirects, Login-Page and stuff
}
}
When I try to login using MY_USERNAME and MY_PASSWORD I get a Authentication request failed: org.springframework.security.authentication.BadCredentialsException: Bad credentials
当我尝试使用 MY_USERNAME 和 MY_PASSWORD 登录时,我得到一个 Authentication request failed: org.springframework.security.authentication.BadCredentialsException: Bad credentials
Full Stacktrace:
完整的堆栈跟踪:
14:59:00,508 DEBUG UsernamePasswordAuthenticationFilter:205 - Request is to process authentication
14:59:00,509 DEBUG ProviderManager:152 - Authentication attempt using org.springframework.security.ldap.authentication.ad.ActiveDirectoryLdapAuthenticationProvider
14:59:00,509 DEBUG ActiveDirectoryLdapAuthenticationProvider:65 - Processing authentication request for user: USERNAME
14:59:00,563 ERROR ActiveDirectoryLdapAuthenticationProvider:133 - Failed to locate directory entry for authenticated user: USERNAME
javax.naming.NameNotFoundException: [LDAP: error code 32 - 0000208D: NameErr: DSID-0310020A, problem 2001 (NO_OBJECT), data 0, best match of:
'OU=A_GROUP,DC=domain,DC=tld'
at com.sun.jndi.ldap.LdapCtx.mapErrorCode(Unknown Source)
at com.sun.jndi.ldap.LdapCtx.processReturnCode(Unknown Source)
at com.sun.jndi.ldap.LdapCtx.processReturnCode(Unknown Source)
at com.sun.jndi.ldap.LdapCtx.searchAux(Unknown Source)
at com.sun.jndi.ldap.LdapCtx.c_search(Unknown Source)
at com.sun.jndi.ldap.LdapCtx.c_search(Unknown Source)
at com.sun.jndi.toolkit.ctx.ComponentDirContext.p_search(Unknown Source)
at com.sun.jndi.toolkit.ctx.PartialCompositeDirContext.search(Unknown Source)
at javax.naming.directory.InitialDirContext.search(Unknown Source)
at org.springframework.security.ldap.SpringSecurityLdapTemplate.searchForSingleEntryInternal(SpringSecurityLdapTemplate.java:208)
at org.springframework.security.ldap.authentication.ad.ActiveDirectoryLdapAuthenticationProvider.searchForUser(ActiveDirectoryLdapAuthenticationProvider.java:285)
at org.springframework.security.ldap.authentication.ad.ActiveDirectoryLdapAuthenticationProvider.doAuthentication(ActiveDirectoryLdapAuthenticationProvider.java:130)
at org.springframework.security.ldap.authentication.AbstractLdapAuthenticationProvider.authenticate(AbstractLdapAuthenticationProvider.java:80)
at org.springframework.security.authentication.ProviderManager.authenticate(ProviderManager.java:156)
at org.springframework.security.authentication.ProviderManager.authenticate(ProviderManager.java:177)
at org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter.attemptAuthentication(UsernamePasswordAuthenticationFilter.java:94)
at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:211)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:110)
... a few more
14:59:00,597 WARN LoggerListener:60 - Authentication event AuthenticationFailureBadCredentialsEvent: USERNAME; details: org.springframework.security.web.authentication.WebAuthenticationDetails@0: RemoteIpAddUSERNAME: 0:0:0:0:0:0:0:1; SessionId: 1E9401031886F0155F0ACE881CC50A4B; exception: Bad credentials
14:59:00,597 DEBUG UsernamePasswordAuthenticationFilter:348 - Authentication request failed: org.springframework.security.authentication.BadCredentialsException: Bad credentials
14:59:00,597 DEBUG UsernamePasswordAuthenticationFilter:349 - Updated SecurityContextHolder to contain null Authentication
14:59:00,597 DEBUG UsernamePasswordAuthenticationFilter:350 - Delegating to authentication failure handler org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler@3d876453
When I browse the AD using a Ldap-Explorer and search for (&(objectClass=user)(userPrincipalName=MY_USERNAME))
, which Spring does in ActiveDirectoryLdapAuthenticationProvider:searchForUser(...), it returns the correct user.
当我使用 Ldap-Explorer 浏览 AD 并搜索(&(objectClass=user)(userPrincipalName=MY_USERNAME))
Spring 在 ActiveDirectoryLdapAuthenticationProvider:searchForUser(...) 中所做的搜索时,它返回正确的用户。
When entering an invalid Password, Spring returns ActiveDirectoryLdapAuthenticationProvider:200 - Active Directory authentication failed: Supplied password was invalid
. This seems to be OK.
当输入无效密码时,Spring 返回ActiveDirectoryLdapAuthenticationProvider:200 - Active Directory authentication failed: Supplied password was invalid
。这似乎没问题。
Is a part for the configuration missing?
是否缺少配置的一部分?
Are there any working examples of how to configure Spring Ldap for an AD using JavaConfig? The official Spring Guide just describes the XML-Way http://docs.spring.io/spring-security/site/docs/3.1.5.RELEASE/reference/ldap.html#ldap-active-directory
是否有任何关于如何使用 JavaConfig 为 AD 配置 Spring Ldap 的工作示例?官方 Spring Guide 只是描述了 XML-Way http://docs.spring.io/spring-security/site/docs/3.1.5.RELEASE/reference/ldap.html#ldap-active-directory
Update:Just updated my AuthenticationProvider to the following:
更新:刚刚将我的 AuthenticationProvider 更新为以下内容:
@Bean
public ActiveDirectoryLdapAuthenticationProvider activeDirectoryLdapAuthenticationProvider() {
val provider = new ActiveDirectoryLdapAuthenticationProvider("company.tld", "ldap://LDAP_URL:389");
provider.setConvertSubErrorCodesToExceptions(true);
provider.setUseAuthenticationRequestCredentials(true);
provider.setAuthoritiesMapper(myAuthoritiesMapper()); // see http://comdynamics.net/blog/544/spring-security-3-integration-with-active-directory-ldap/
provider.setUseAuthenticationRequestCredentials(true);
return provider;
}
It works fine, thanks guido!
它工作正常,谢谢guido!
Note: Spring states, that a PartialResultException is ignored. The Docs say
注意:Spring 声明会忽略 PartialResultException。文档说
Some Active Directory (AD) servers are unable to automatically following referrals, which often leads to a PartialResultException being thrown in searches. You can specify that PartialResultException is to be ignored by setting the ignorePartialResultException property to true.
某些 Active Directory (AD) 服务器无法自动跟踪引用,这通常会导致在搜索中抛出 PartialResultException。您可以通过将 ignorePartialResultException 属性设置为 true 来指定要忽略 PartialResultException。
Maybe there is a way to set this property vie JavaConfig, too. I just ignored it.
也许也有一种方法可以通过 JavaConfig 设置此属性。我只是忽略了它。
回答by Maciej Czarnecki
- For PartialResultException You should set parameter referral to "follow" on Your context source.
- 对于 PartialResultException 您应该在您的上下文源上将参数引用设置为“跟随”。