使用Apache Shiro进行身份认证-LDAP认证

时间:2021-12-07 07:05:30

http://blog.csdn.net/peterwanghao/article/details/7458618


Apache Shiro 支持LDAP做为数据源进行身份认证。我做了一个简单的实验来说明Shiro是如何支持LDAP的。

在本机安装了OpenLDAP,版本为2.4.23。手动建了一个用户,结构如下:

使用Apache Shiro进行身份认证-LDAP认证

在Shiro.ini文件中配置LDAP:

[plain] view plain copy
  1. [main]  
  2. ldapRealm = org.apache.shiro.realm.ldap.JndiLdapRealm  
  3. ldapRealm.userDnTemplate = cn={0},ou=产品研发部,ou=研发中心,dc=example,dc=com  
  4. ldapRealm.contextFactory.url = ldap://localhost:389  

这样就可实现通过LDAP进行身份认证。


在Shiro中具体实现验证过程的是org.apache.shiro.realm.ldap.JndiLdapRealm类和org.apache.shiro.realm.ldap.JndiLdapContextFactory类。

[java] view plain copy
  1. protected AuthenticationInfo queryForAuthenticationInfo(AuthenticationToken token,  
  2.                                                             LdapContextFactory ldapContextFactory)  
  3.             throws NamingException {  
  4.   
  5.         //从页面提交的用户名“lisi”  
  6.         Object principal = token.getPrincipal();  
  7.         //从页面提交的口令“123456”  
  8.         Object credentials = token.getCredentials();  
  9.   
  10.         log.debug("Authenticating user '{}' through LDAP", principal);  
  11.   
  12.         //将用户名拼成DN“cn=lisi,ou=产品研发部,ou=研发中心,dc=example,dc=com”  
  13.         principal = getLdapPrincipal(token);  
  14.   
  15.         LdapContext ctx = null;  
  16.         try {  
  17.             //进行认证  
  18.             ctx = ldapContextFactory.getLdapContext(principal, credentials);  
  19.             //context was opened successfully, which means their credentials were valid.  Return the AuthenticationInfo:  
  20.             return createAuthenticationInfo(token, principal, credentials, ctx);  
  21.         } finally {  
  22.             LdapUtils.closeContext(ctx);  
  23.         }  
  24.     }  

注,这里存在一个问题。如果输入不存在的用户或是错误的口令后currentUser.login(token);方法返回的异常是AuthenticationException,代表不确定的异常。

而不是UnknownAccountException或IncorrectCredentialsException。这样在前台表述时就不够准确。

原因应该是在做LDAP认证时没有区分错误情况,如果取不到context会抛出相同异常 throw new AuthenticationException("LDAP authentication failed.", e);