Ste*_*eve 7 java spring-security spring-ldap
Spring 3.1 Tomcat 6.*
我正在制作一个Spring 3.1 webapp,用LDAP进行身份验证.
我使用我编写的JNDI样式的Java程序测试了LDAP凭据(用户名,密码,ldap URL,搜索模式)(引用如下).该程序工作,转储所有用户属性,包括密码,似乎在LDAP服务器上加密.
当我尝试在Spring 3.1中使用相同的凭据登录时,我收到错误消息"Bad Credentials".
我在日志中收到此消息:
DEBUG [org.springframework.security.authentication.ProviderManager:authenticate] (ProviderManager.java:152) - Authentication attempt using org.springframework.security.ldap.authentication.LdapAuthenticationProvider
DEBUG [org.springframework.security.ldap.authentication.AbstractLdapAuthenticationProvider:authenticate] (AbstractLdapAuthenticationProvider.java:51) - Processing authentication request for user: John.A.Smith
DEBUG [org.springframework.security.ldap.authentication.BindAuthenticator:bindWithDn] (BindAuthenticator.java:108) - Attempting to bind as uid=John.A.Smith,ou=People,o=acme.com,o=acme.com
DEBUG [org.springframework.security.ldap.DefaultSpringSecurityContextSource$1:setupEnvironment] (DefaultSpringSecurityContextSource.java:76) - Removing pooling flag for user uid=John.A.Smith,ou=People,o=acme.com,o=acme.com
DEBUG [org.springframework.security.ldap.authentication.BindAuthenticator:handleBindException] (BindAuthenticator.java:152) - Failed to bind as uid=John.A.Smith,ou=People,o=acme.gov: org.springframework.ldap.AuthenticationException: [LDAP: error code 32 - No Such Object]; nested exception is javax.naming.AuthenticationException: [LDAP: error code 32 - No Such Object]
DEBUG [org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter:unsuccessfulAuthentication] (AbstractAuthenticationProcessingFilter.java:340) - Authentication request failed: org.springframework.security.authentication.BadCredentialsException: Bad credentials
Run Code Online (Sandbox Code Playgroud)
在我的*-security.xml中,我尝试使用标签进行密码比较和编码,但它没有帮助.我尝试使用md4,md5,plaintext,sha,sha-256,{ssha},{sha}无济于事.
<s:authentication-manager>
<s:ldap-authentication-provider user-dn-pattern="uid={0},ou=People,o=noaa.gov" >
<s:password-compare hash="md5">
<s:password-encoder hash="md5"/>
</s:password-compare>
</s:ldap-authentication-provider>
</s:authentication-manager>
Run Code Online (Sandbox Code Playgroud)
我的网络组织是一个庞大,缓慢,官僚组织.我有没有办法告诉他们使用什么编码,如果有的话,不联系他们?
我可以查看的任何想法吗?
这是我上次尝试的*-security.xml以及我能够连接的Java LDAP演示
谢谢.
我的*-security.xml文件:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:s="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-3.0.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-3.1.xsd">
<s:http auto-config="true" use-expressions="true">
**<s:intercept-url pattern="/welcome*" access="isAuthenticated()" />**
<s:form-login login-page="/login" default-target-url="/welcome"
authentication-failure-url="/loginfailed" />
<s:logout logout-success-url="/logout" />
</s:http>
<s:ldap-server url = "ldap://ldap-itc.sam.acme.com:636/o=acme.com"/>
<s:authentication-manager>
<s:ldap-authentication-provider user-dn-pattern="uid={0},ou=People,o=noaa.gov" />
</s:authentication-manager>
</beans>
Run Code Online (Sandbox Code Playgroud)
以下是使用相同凭据的JNDI样式LDAP Java程序:
import javax.naming.*;
import javax.naming.directory.*;
import java.util.*;
import java.sql.*;
public class LDAPDEMO {
public static void main(String args[]) {
String lcf = "com.sun.jndi.ldap.LdapCtxFactory";
String ldapurl = "ldap://ldap-itc.sam.acme.com:636/o=acme.com";
String loginid = "John.A.Smith";
String password = "passowordforjohn";
DirContext ctx = null;
Hashtable env = new Hashtable();
Attributes attr = null;
Attributes resultsAttrs = null;
SearchResult result = null;
NamingEnumeration results = null;
int iResults = 0;
env.put(Context.INITIAL_CONTEXT_FACTORY, lcf);
env.put(Context.PROVIDER_URL, ldapurl);
env.put(Context.SECURITY_PROTOCOL, "ssl");
env.put(Context.SECURITY_AUTHENTICATION, "simple");
env.put(Context.SECURITY_PRINCIPAL, "uid=" + loginid + ",ou=People,o=acme.com");
env.put(Context.SECURITY_CREDENTIALS, password);
try {
ctx = new InitialDirContext(env);
attr = new BasicAttributes(true);
attr.put(new BasicAttribute("uid",loginid));
results = ctx.search("ou=People",attr);
while (results.hasMore()) {
result = (SearchResult)results.next();
resultsAttrs = result.getAttributes();
for (NamingEnumeration enumAttributes = resultsAttrs.getAll(); enumAttributes.hasMore();) {
Attribute a = (Attribute)enumAttributes.next();
System.out.println("attribute: " + a.getID() + " : " + a.get().toString());
}// end for loop
iResults++;
}// end while loop
System.out.println("iResults == " + iResults);
}// end try
catch (Exception e) {
e.printStackTrace();
}
}// end function main()
}// end class LDAPDEMO
Run Code Online (Sandbox Code Playgroud)
解
Luke Taylor的评论帮助我完成了配置工作:
您的配置错误,因为您在LDAP服务器URL中有"o = acme.com",并且在用户DN模式中也使用"o = acme.com".
我从DN模式中取出了"o = acme.com"并且LDAP工作了.我最初将"o = acme.com"放在LDAP URL和DN模式中,因为我是Spring 3.1和LDAP的新手,这类似于它在LDAP的JNDI版本中的实现方式.我根据我要替换的遗留代码编写的演示.
这是我的*-security.xml的最终工作版本
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:s="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-3.0.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-3.1.xsd">
<s:http auto-config="true" use-expressions="true">
**<s:intercept-url pattern="/welcome*" access="isAuthenticated()" />**
<s:form-login login-page="/login" default-target-url="/welcome"
authentication-failure-url="/loginfailed" />
<s:logout logout-success-url="/logout" />
</s:http>
<s:ldap-server url = "ldap://ldap-itc.sam.acme.com:636/o=acme.com"/>
<s:authentication-manager>
<s:ldap-authentication-provider user-dn-pattern="uid={0},ou=People" />
</s:authentication-manager>
</beans>
Run Code Online (Sandbox Code Playgroud)
我将探讨他的其他评论,看看我是否可以重新输入密码或者是否需要.
您的 Java 示例使用标准绑定身份验证,但您已将 Spring Security 配置设置为对用户密码执行LDAP 比较操作。这将失败,因为 LDAP 服务器没有使用与 Spring Security 的 MD5 编码器相同的密码编码格式。为了使比较操作成功,存储的值必须与发送到目录的字符串匹配。在大多数情况下,您希望使用标准 LDAP(绑定)身份验证。您可能需要为身份验证提供程序使用 bean 配置。尝试使用:
<s:ldap-server id="contextSource" url="ldap://ldap-itc.sam.acme.com:636/o=acme.com"/>
<bean id="ldapAuthProvider" class="org.springframework.security.ldap.authentication.LdapAuthenticationProvider">
<constructor-arg>
<bean class="org.springframework.security.ldap.authentication.BindAuthenticator">
<constructor-arg ref="contextSource"/>
<property name="userDnPatterns">
<list><value>uid={0},ou=People</value></list>
</property>
</bean>
</constructor-arg>
<constructor-arg>
<bean class="org.springframework.security.ldap.authentication.NullLdapAuthoritiesPopulator"/>
</constructor-arg>
<property name="authoritiesMapper">
<bean class="class="org.springframework.security.core.authority.mapping">
<property name="defaultAuthority" value="ROLE_USER" />
</bean>
</property>
</bean>
<s:authentication-manager>
<s:authentication-manager ref="ldapAuthProvider" />
</s:authentication-manager>
Run Code Online (Sandbox Code Playgroud)
我建议您还阅读参考手册的 LDAP 章节。
此外,如果您想了解身份验证失败的原因,最好的查找位置是 LDAP 服务器本身的日志。如果您没有完全访问权限,请了解其设置方式并使用您拥有完全控制权的本地服务器(例如 OpenLDAP)。
归档时间: |
|
查看次数: |
20871 次 |
最近记录: |