因为公司内部系统多,账号体系多,现需要实现统一账号账号登录不同系统,现采用LDAP来管理账号。
刚好shiro也提供LDAP的支持,结合网上资料写下如下内容。
总体方案
- jeesite现有账号体系用户自己维护email地址与LDAP中存储的email地址一一对应
- 自定义LdapAuthorizingRealm继承JndiLdapRealm类,重写里面方法。
- 在spring-context-shiro.xml添加自定义realm
代码实现
package com.xxx.modules.sys.security;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.naming.AuthenticationNotSupportedException;
import javax.naming.NamingEnumeration;
import javax.naming.NamingException;
import javax.naming.directory.SearchControls;
import javax.naming.directory.SearchResult;
import javax.naming.ldap.LdapContext;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.ldap.UnsupportedAuthenticationMechanismException;
import org.apache.shiro.realm.ldap.JndiLdapRealm;
import org.apache.shiro.realm.ldap.LdapContextFactory;
import org.apache.shiro.realm.ldap.LdapUtils;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* LdapRealm
* @author huangkai
*
*/
public class LdapAuthorizingRealm extends JndiLdapRealm{
private Logger logger = LoggerFactory.getLogger(getClass());
private SystemService systemService;
private String rootDN;
public String getRootDN() {
return rootDN;
}
public void setRootDN(String rootDN) {
this.rootDN = rootDN;
}
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authcToken){
UsernamePasswordToken token = (UsernamePasswordToken) authcToken;
// 校验登录验证码
if (LoginController.isValidateCodeLogin(token.getUsername