我正在尝试使用LDAP访问我的项目。 它成功提示输入用户名和密码,但在其中输入正确的凭据会导致再次弹出提示(似乎凭据错误,但它们不是)。
这是我的security-context.xml:
<?xml version="1.0" encoding="utf-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/security"
xmlns:beans="http://www.springframework.org/schema/beans"
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.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security.xsd">
<ldap-server url="ldap://${ldap.host}:${ldap.port}/${ldap.root}" manager-dn="${ldap.manager.dn}" manager-password="${ldap.manager.password}" />
<authentication-manager>
<ldap-authentication-provider group-search-base="${ldap.group.search.base}" user-search-filter="(uid={0})" user-search-base="${ldap.user.search.base}" />
</authentication-manager>
<http use-expressions="true">
<intercept-url pattern="/**" />
<http-basic />
</http>
</beans:beans>
密码存储为{MD5}哈希... 我正在使用jsr 250 api。
编辑:
@TobyHobson这导致org.xml.sax.SAXParseException; lineNumber: 14; columnNumber: 38; cvc-complex-type.2.4.a: Invalid content was found starting with element 'password-encoder'. One of '{"http://www.springframework.org/schema/security":password-compare}' is expected.
EDIT2:
@TobyHobson将password-compare
放在password-encoder
附近似乎在编译,但它仍然拒绝我的正确凭据。
EDIT3: 这是必要的日志:
DEBUG: org.springframework.beans.factory.support.DefaultListableBeanFactory - Returning cached instance of singleton bean 'sessionFactory'
DEBUG: org.springframework.security.web.FilterChainProxy - /licenses/index.html at position 1 of 8 in additional filter chain; firing Filter: 'SecurityContextPersistenceFilter'
DEBUG: org.springframework.security.web.context.HttpSessionSecurityContextRepository - HttpSession returned null object for SPRING_SECURITY_CONTEXT
DEBUG: org.springframework.security.web.context.HttpSessionSecurityContextRepository - No SecurityContext was available from the HttpSession: org.apache.catalina.session.StandardSessionFacade@397af435. A new one will be created.
DEBUG: org.springframework.security.web.FilterChainProxy - /licenses/index.html at position 2 of 8 in additional filter chain; firing Filter: 'BasicAuthenticationFilter'
DEBUG: org.springframework.security.web.authentication.www.BasicAuthenticationFilter - Basic Authentication Authorization header found for user 'demo_admin'
DEBUG: org.springframework.security.authentication.ProviderManager - Authentication attempt using org.springframework.security.ldap.authentication.LdapAuthenticationProvider
DEBUG: org.springframework.security.ldap.authentication.LdapAuthenticationProvider - Processing authentication request for user: demo_admin
DEBUG: org.springframework.security.ldap.search.FilterBasedLdapUserSearch - Searching for user 'demo_admin', with user search [ searchFilter: '(uid={0})', searchBase: 'ou=people', scope: subtree, searchTimeLimit: 0, derefLinkFlag: false ]
DEBUG: org.springframework.security.ldap.SpringSecurityLdapTemplate - Searching for entry under DN 'dc=ubuntu,dc=local', base = 'ou=people', filter = '(uid={0})'
DEBUG: org.springframework.security.ldap.SpringSecurityLdapTemplate - Found DN: uid=demo_admin,ou=people
DEBUG: org.springframework.security.ldap.authentication.PasswordComparisonAuthenticator - Performing LDAP compare of password attribute 'userPassword' for user 'uid=demo_admin,ou=people'
DEBUG: org.springframework.security.web.authentication.www.BasicAuthenticationFilter - Authentication request for failed: org.springframework.security.authentication.BadCredentialsException: Bad credentials
DEBUG: org.springframework.security.web.context.HttpSessionSecurityContextRepository - SecurityContext is empty or contents are anonymous - context will not be stored in HttpSession.
DEBUG: org.springframework.security.web.context.SecurityContextPersistenceFilter - SecurityContextHolder now cleared, as request processing completed
EDIT4:我想这与jsr 250 api和群组/角色有关。 这是我的ldif:
dn: ou=people,dc=ubuntu,dc=local
objectClass: organizationalUnit
ou: people
dn: uid=demo_admin,ou=people,dc=ubuntu,dc=local
userPassword: {MD5}fe01ce2a7fbac8fafaed7c982a04e229
objectClass: posixAccount
objectClass: account
homeDirectory: null
uid: demo_admin
uidNumber: 1001
gidNumber: 1000
cn: Demo Admin
dn: uid=demo_manager,ou=people,dc=ubuntu,dc=local
userPassword: {MD5}fe01ce2a7fbac8fafaed7c982a04e229
objectClass: posixAccount
objectClass: account
homeDirectory: null
uid: demo_manager
uidNumber: 2001
gidNumber: 2000
cn: Demo Manager
dn: uid=demo_viewer,ou=people,dc=ubuntu,dc=local
userPassword: {MD5}fe01ce2a7fbac8fafaed7c982a04e229
objectClass: posixAccount
objectClass: account
homeDirectory: null
uid: demo_viewer
uidNumber: 3001
gidNumber: 3000
cn: Demo Viewer
dn: ou=groups,dc=ubuntu,dc=local
objectClass: organizationalUnit
ou: groups
dn: cn=Admins,ou=groups,dc=ubuntu,dc=local
objectClass: posixGroup
cn: Admins
gidNumber: 1000
dn: cn=Managers,ou=groups,dc=ubuntu,dc=local
objectClass: posixGroup
cn: Managers
gidNumber: 2000
dn: cn=Viewers,ou=groups,dc=ubuntu,dc=local
objectClass: posixGroup
cn: Viewers
gidNumber: 3000
我在我的控制器中使用@RolesAllowed({ Role.ROLE_ADMIN, Role.ROLE_MANAGER, Role.ROLE_VIEWER })
,这是我的absract角色类:
public abstract class Role
{
public static final String ROLE_ADMIN = "Admins";
public static final String ROLE_MANAGER = "Managers";
public static final String ROLE_VIEWER = "Viewers";
}
答案 0 :(得分:1)
您需要向身份验证提供程序添加password encoder,以告知Spring在绑定LDAP之前散列密码。 e.g。
<authentication-manager>
<ldap-authentication-provider group-search-base="${ldap.group.search.base}" user-search-filter="(uid={0})" user-search-base="${ldap.user.search.base}">
<password-encoder hash="md5"/>
</ldap-authentication-provider>
</authentication-manager>
如果你使用盐,你还需要包括它。例如
<password-encoder hash="md5">
<salt-source user-property="username"/>
</password-encoder>
答案 1 :(得分:1)
不需要在spring安全配置文件中定义散列,散列技术将由ldap本身处理。 您要做的唯一一件事就是将MD5密码存储在像这样的ldap ....
Attributes attrs = new BasicAttributes();
BasicAttribute ocattr = new BasicAttribute("objectclass");
ocattr.add("top");
ocattr.add("person");
ocattr.add("inetorgperson");
ocattr.add("organizationalperson");
attrs.put(ocattr);
attrs.put("sn",user.getName());
attrs.put("userPassword","{MD5}"+user.getPassword());
答案 2 :(得分:0)
密码编码方案在使用绑定身份验证时并不重要,因为密码检查是在目录中执行的,而不是在Spring Security代码中执行,因此Spring Security无需散列密码或了解密码的存储方式。它将作为纯文本发送到目录,因此如果您担心这一点,您应该使用ldaps连接。
如果使用LDAP“比较”操作进行身份验证,则必须将相同的密码字段副本发送到目录。这很容易出错,因为它取决于案例是否正确等等。虽然有LdapShaPasswordEncoder
来处理{SHA}和{SSHA},但目前还没有为{MD5}哈希提供支持。
很可能由于某些其他原因导致您的设置失败,这可以通过更仔细地检查调试日志和LDAP服务器日志来清楚。