需求:根据配置文件配置,设置是否开启AD域验证。
第一步:修改jeesite.properties配置文件
ldap.url = ldap://ip地址:端口/
ldap.org = ou=XXXXXXXX,dc=XXXXX,dc=com
ldap.user = username
ldap.password = password
ldap.ldapfactory = com.sun.jndi.ldap.LdapCtxFactory
ldap.authentication = simple
#AD域登录验证是否开启,true:开启;false:关闭
ldap.adopen = true
第二步:自定义shiro密码验证方法。
1. 修改spring-context-shiro.xml
//注释掉
//自己定义
2. 新增自定义密码匹配类
public class CustomCredentialsMatcher extends SimpleCredentialsMatcher {
@Override
public boolean doCredentialsMatch(AuthenticationToken authcToken, AuthenticationInfo info) {
return true;
}
}
3. 修改SystemAuthorizingRealm.java文件initCredentialsMatcher方法
这个类在项目启动时自动注入,这个方法在注入时自动调用,根据配置文件选择加载匹配器。
/**
*设定密码校验的Hash算法与迭代次数
*/@PostConstruct
public voidinitCredentialsMatcher() {
//根据配置文件,在项目加载时加载密码匹配方式
if("true".equals(openADFlag)){//openADFlag为配置文件中AD域是否开启标志
setCredentialsMatcher(newCustomCredentialsMatcher());
}else{
HashedCredentialsMatcher matcher = newHashedCredentialsMatcher(SystemService.HASH_ALGORITHM);
matcher.setHashIterations(SystemService.HASH_INTERATIONS);
setCredentialsMatcher(matcher);
}
}
第三步:修改SystemAuthorizingRealm.java中doGetAuthenticationInfo
该方法:认证回调函数, 登录时调用
protectedAuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authcToken) {
UsernamePasswordToken token = (UsernamePasswordToken) authcToken;
//校验登录验证码if(LoginController.isValidateCodeLogin(token.getUsername(), false, false)){
Session session = UserUtils.getSession();
String code = (String)session.getAttribute(ValidateCodeServlet.VALIDATE_CODE);
if(token.getCaptcha() == null|| !token.getCaptcha().toUpperCase().equals(code)){
throw newAuthenticationException("msg:验证码错误, 请重试.");
}
}
/*
1.读取配置文件,是否进行AD域验证
2.如果否,则继续往下走,使用原来的流程
3.如果是,获取到用户后就不需要进行密码验证了。
*/if("true".equals(openADFlag)){
openAD(token.getUsername(),String.valueOf(token.getPassword()));
}
//校验用户名密码User user = getSystemService().getUserByLoginName(token.getUsername());
if(user != null) {
if(Global.NO.equals(user.getLoginFlag())){
throw newAuthenticationException("msg:该已帐号禁止登录.");
}
byte[] salt = Encodes.decodeHex(user.getPassword().substring(0,16));
SimpleAuthenticationInfo info = newSimpleAuthenticationInfo(newPrincipal(user, token.isMobileLogin()),
user.getPassword().substring(16), ByteSource.Util.bytes(salt), getName());
returninfo;
} else{
if("true".equals(openADFlag)){
throw newAuthenticationException("msg:请联系系统管理员.");
}
return null;
}
}
第四步:添加AD域验证方法
//判断是否需要AD域验证protectedBoolean openAD(String username, String password){
DirContext ctx = null;
AdConfig adf = AdConfig.getAdConfig();
Hashtable env = newHashtable();
try{
env.put(Context.PROVIDER_URL, adf.getUrl() + URLEncoder.encode(adf.getOrg(), "utf-8"));
} catch(UnsupportedEncodingException e) {
e.printStackTrace();
}
String org=adf.getOrg();
String dc=org.replaceFirst(",dc=","@");
dc=dc.substring(dc.indexOf("@"));
dc=dc.replaceFirst(",dc=",".");
env.put(Context.SECURITY_PRINCIPAL, username+dc);
env.put(Context.SECURITY_CREDENTIALS,password);
env.put(Context.INITIAL_CONTEXT_FACTORY,adf.getLdapfactory());
env.put(Context.SECURITY_AUTHENTICATION, adf.getAuthentication());
try{
ctx = newInitialDirContext(env);//初始化上下文System.out.println("身份验证成功!");
return true;
} catch(javax.naming.AuthenticationException e) {
e.printStackTrace();
throw newAuthenticationException("msg:AD域身份验证失败.");
} catch(javax.naming.CommunicationException e) {
e.printStackTrace();
throw newAuthenticationException("msg:AD域连接失败!");
} catch(Exception e) {
e.printStackTrace();
throw newAuthenticationException("msg:AD域身份验证未知异常!");
} finally{
if(null!=ctx){
try{
ctx.close();
ctx=null;
} catch(Exception e) {
e.printStackTrace();
}
}
}
}