Java程序通过LDAP对用户进行登陆验证

来源:互联网 发布:环球天下期货软件 编辑:程序博客网 时间:2024/06/05 23:50

       在去年南京项目中,客户方要求用户登陆需要在其他平台下进行认证,当时客户用的LDAP“数据库”管理方式,后来查阅Java已经对LDAP进行了封装,不需要下载其他jar包就可以实现。

       补脑:【LDAP】是"Lightweight Directory Access Protocol"的缩写,中文翻译过来就叫“轻量目录访问协议”,看字面大概能猜出应该是以树状形存储数据的数据库,后来翻阅资料确实如此。其中包含几个重要的参数:CN,DN,DC,OU。至于这个缩写单词的含义,有兴趣可以去百科或者官网脑补一下,下面程序中将会引用这几个才参数,也会进行简单的描述。

package com.angma.mes.zbe.moudle.service.util;import com.angma.mes.jagybarcode.manager.controller.plan.machine.MachineShopTaskCreateController;import com.sun.org.apache.xerces.internal.impl.dv.util.Base64;import java.security.MessageDigest;import java.security.NoSuchAlgorithmException;import java.util.Hashtable;import java.util.logging.Level;import java.util.logging.Logger;import javax.naming.Context;import javax.naming.NamingException;import javax.naming.directory.DirContext;import javax.naming.directory.InitialDirContext;/** * 用户登陆认证,LDAP跨域认证,通过LDAP对用户进行更新 *  * @author xlj * @date 2015.07.10 */public class LdapUtil {private static DirContext ctx;// LDAP服务器端口默认为389private static final String LDAP_URL = "ldap://127.0.0.1:389";// ROOT根据此参数确认用户组织所在位置private static final String LDAP_PRINCIPAL = "OU=CMA Users,DC=changan-mazda,DC=com,DC=cn";// LDAP驱动private static final String LDAP_FACTORY = "com.sun.jndi.ldap.LdapCtxFactory";private static Logger logger = Logger.getLogger(LdapUtil.class);/**** 测试 ****/public static void main(String[] args) {LdapUtil.getLoginContext();LdapUtil.addUserLdap("10000", "123456");LdapUtil.updatePasswordLdap("10000", "1234567");LdapUtil.deleteUserLdap("10000");}// 通过连接LDAP服务器对用户进行认证,返回LDAP对象public static DirContext getLoginContext() {String account = "zhangsan"; // 模拟用户名String password = "123456"; // 模拟密码for (int i = 0; i < 5; i++) { // 验证次数Hashtable env = new Hashtable();env.put(Context.SECURITY_AUTHENTICATION, "simple");env.put(Context.SECURITY_CREDENTIALS, password);// cn=属于哪个组织结构名称,ou=某个组织结构名称下等级位置编号env.put(Context.SECURITY_PRINCIPAL, "cn=" + account + ", ou=Level0" + i + "00," + LDAP_URL);env.put(Context.INITIAL_CONTEXT_FACTORY, LDAP_PRINCIPAL);env.put(Context.PROVIDER_URL, LDAP_FACTORY);try {// 连接LDAP进行认证ctx = new InitialDirContext(env);System.out.println("认证成功");logger.info("【" + account + "】用户于【" + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()) + "】登陆系统成功");} catch (javax.naming.AuthenticationException e) {System.out.println("认证失败");} catch (NamingException err) {logger.info("--------->>【" + account + "】用户验证失败【" + i + "】次");} catch (Exception e) {System.out.println("认证出错:");e.printStackTrace();}}return ctx;}// 将输入用户和密码进行加密算法后验证public static boolean verifySHA(String ldappw, String inputpw) {// MessageDigest 提供了消息摘要算法,如 MD5 或 SHA,的功能,这里LDAP使用的是SHA-1MessageDigest md = MessageDigest.getInstance("SHA-1");// 取出加密字符if (ldappw.startsWith("{SSHA}")) {ldappw = ldappw.substring(6);} else if (ldappw.startsWith("{SHA}")) {ldappw = ldappw.substring(5);}// 解码BASE64byte[] ldappwbyte = Base64.decode(ldappw);byte[] shacode;byte[] salt;// 前20位是SHA-1加密段,20位后是最初加密时的随机明文if (ldappwbyte.length <= 20) {shacode = ldappwbyte;salt = new byte[0];} else {shacode = new byte[20];salt = new byte[ldappwbyte.length - 20];System.arraycopy(ldappwbyte, 0, shacode, 0, 20);System.arraycopy(ldappwbyte, 20, salt, 0, salt.length);}// 把用户输入的密码添加到摘要计算信息md.update(inputpw.getBytes());// 把随机明文添加到摘要计算信息md.update(salt);// 按SSHA把当前用户密码进行计算byte[] inputpwbyte = md.digest();// 返回校验结果return MessageDigest.isEqual(shacode, inputpwbyte);}// 添加用户public static boolean addUserLdap(String account, String password) {boolean success = false;try {ctx = LdapUtil.getLoginContext();BasicAttributes attrsbu = new BasicAttributes();BasicAttribute objclassSet = new BasicAttribute("objectclass");objclassSet.add("person");objclassSet.add("top");objclassSet.add("organizationalPerson");objclassSet.add("inetOrgPerson");attrsbu.put(objclassSet);attrsbu.put("sn", account);attrsbu.put("uid", account);attrsbu.put("userPassword", password);ctx.createSubcontext("cn=" + account + ",ou=People", attrsbu);ctx.close();return true;} catch (NamingException ex) {try {if (ctx != null) {ctx.close();}} catch (NamingException namingException) {namingException.printStackTrace();}logger.info("--------->>添加用户失败");}return false;}// 修改密码public static boolean updatePasswordLdap(String account, String password) {boolean success = false;try {ctx = LdapUtil.getLoginContext();ModificationItem[] modificationItem = new ModificationItem[1];modificationItem[0] = new ModificationItem(DirContext.REPLACE_ATTRIBUTE, new BasicAttribute("userPassword", password));ctx.modifyAttributes("cn=" + account + ",ou=People", modificationItem);ctx.close();return true;} catch (NamingException ex) {try {if (ctx != null) {ctx.close();}} catch (NamingException namingException) {namingException.printStackTrace();}logger.info("--------->>修改密码失败");}return success;}// 删除用户public static boolean deleteUserLdap(String account) {try {ctx = LdapUtil.getLoginContext();ctx.destroySubcontext("cn=" + account);} catch (Exception ex) {try {if (ctx != null) {ctx.close();}} catch (NamingException namingException) {namingException.printStackTrace();}logger.info("--------->>删除用户失败");return false;}return true;}// 关闭LDAP服务器连接public static void closeCtx() {try {ctx.close();} catch (NamingException ex) {logger.info("--------->> 关闭LDAP连接失败");}}}

声明:以上教程为博主原创,若需转载请注明出处,谢谢。

0 0
原创粉丝点击