http://blog.csdn.net/peterwanghao/article/details/7458618
Apache Shiro 支持LDAP做为数据源进行身份认证。我做了一个简单的实验来说明Shiro是如何支持LDAP的。
在本机安装了OpenLDAP,版本为2.4.23。手动建了一个用户,结构如下:
在Shiro.ini文件中配置LDAP:
- [main]
- ldapRealm = org.apache.shiro.realm.ldap.JndiLdapRealm
- ldapRealm.userDnTemplate = cn={0},ou=产品研发部,ou=研发中心,dc=example,dc=com
- ldapRealm.contextFactory.url = ldap://localhost:389
这样就可实现通过LDAP进行身份认证。
在Shiro中具体实现验证过程的是org.apache.shiro.realm.ldap.JndiLdapRealm类和org.apache.shiro.realm.ldap.JndiLdapContextFactory类。
- protected AuthenticationInfo queryForAuthenticationInfo(AuthenticationToken token,
- LdapContextFactory ldapContextFactory)
- throws NamingException {
- //从页面提交的用户名“lisi”
- Object principal = token.getPrincipal();
- //从页面提交的口令“123456”
- Object credentials = token.getCredentials();
- log.debug("Authenticating user '{}' through LDAP", principal);
- //将用户名拼成DN“cn=lisi,ou=产品研发部,ou=研发中心,dc=example,dc=com”
- principal = getLdapPrincipal(token);
- LdapContext ctx = null;
- try {
- //进行认证
- ctx = ldapContextFactory.getLdapContext(principal, credentials);
- //context was opened successfully, which means their credentials were valid. Return the AuthenticationInfo:
- return createAuthenticationInfo(token, principal, credentials, ctx);
- } finally {
- LdapUtils.closeContext(ctx);
- }
- }
注,这里存在一个问题。如果输入不存在的用户或是错误的口令后currentUser.login(token);方法返回的异常是AuthenticationException,代表不确定的异常。
而不是UnknownAccountException或IncorrectCredentialsException。这样在前台表述时就不够准确。
原因应该是在做LDAP认证时没有区分错误情况,如果取不到context会抛出相同异常 throw new AuthenticationException("LDAP authentication failed.", e);