一、用户认证
public String execute(){ Hashtable env = new Hashtable(); String LDAP_URL = "ldap://8.8.8.8:389"; // LDAP访问地址 env.put(Context.INITIAL_CONTEXT_FACTORY,"com.sun.jndi.ldap.LdapCtxFactory"); env.put(Context.PROVIDER_URL, LDAP_URL); env.put(Context.SECURITY_AUTHENTICATION, "simple"); env.put(Context.SECURITY_PRINCIPAL, username); env.put(Context.SECURITY_CREDENTIALS, password); try { dc = new InitialDirContext(env);// 初始化上下文 // 域节点 String searchBase = "DC=abc,DC=com"; String searchFilter = "cn="+username; SearchControls searchCtls = new SearchControls(); // Create the searchCtls.setSearchScope(SearchControls.SUBTREE_SCOPE); // Specify //设置查询的属性,根据登陆用户姓名获取ou String returnedAtts[] = {"distinguishedName"};// 定制返回属性 searchCtls.setReturningAttributes(returnedAtts); // 设置返回属性集 // 根据设置的域节点、过滤器类和搜索控制器搜索LDAP得到结果 NamingEnumeration<SearchResult> entries = dc.search(searchBase, searchFilter,searchCtls); SearchResult entry = entries.next(); Attributes attrs = entry.getAttributes(); String disName = attrs.get("distinguishedname").toString(); String[] disNameArray = disName.split(":"); String distinguishedname = disNameArray[1].trim(); //设置session session.put("distinguishedname", distinguishedname); //认证成功,返回success System.out.println("认证成功");//这里可以改成异常抛出。 return "success"; } catch (javax.naming.AuthenticationException e) { System.out.println("认证失败"); return "fail"; } catch (Exception e) { System.out.println("认证出错:" + e); return "fail"; } }
二、修改用户密码
用户认证是相对比较简单的,简单几行代码即可,微软是不允许直接通过java修改密码(C#除外),我们就需要用到证书。
1、在AD域服务器上,添加角色 证书服务器,点这里。
2、在IE中,Internate选项->内容->证书->找到自己的证书然后导出。
3、导出的证书,需要导入到一个文件里,这个文件叫cacerts.这个文件在,还需要一个工具keytools.exe。位置:
cacerts : D:\soft\myeclipse2013\binary\com.sun.java.jdk.win32.x86_64_1.6.0.u43\jre\lib\security
keytools : D:\soft\myeclipse2013\binary\com.sun.java.jdk.win32.x86_64_1.6.0.u43\bin
我们需要通过keytools工具,把导出的证书导入到cacerts里,导入的方法是在DOS命令里输入:
D:\soft\myeclipse2013\binary\com.sun.java.jdk.win32.x86_64_1.6.0.u43\bin\keytool -import -keystore D:\soft\myeclipse2013\binary\com.sun.java.jdk.win32.x86_64_1.6.0.u43\jre\lib\security\cacerts -storepass changeit -keypass changeit -alias ca -file D:\ca\ca.cer
复制到dos,回车后提示是否导入,输入“y”即可。这些都做完就该我们的编码了:
public void editPwd() throws NamingException { this.setNewPwd(new String(decode(newPwd))); this.setConfirmPwd(new String(decode(confirmPwd))); //ajax请求的一些代码 HttpServletResponse response=ServletActionContext.getResponse(); response.setContentType("text/html; charset=utf-8"); Map<String, Object> m = new HashMap<String, Object>(); //校验两次输入的密码是否一致 if(!newPwd.equals(confirmPwd)){ m.put("success", false); m.put("msg", "两次密码输入不一致,请重新输入。"); JSONArray jsonArray = JSONArray.fromObject(m); try { PrintWriter out = response.getWriter(); out.print(jsonArray.toString()); } catch (IOException e) { e.printStackTrace(); } } //ladp的一些配置 Hashtable env = new Hashtable(); String adminName = "sja\\administrator"; String adminPassword = "[email protected]"; String userName = session.get("distinguishedname").toString().replace("%20", " "); String newPassword = newPwd; String keystore = this.getClass().getResource("").toString().substring(6).replace("%20", " ").replace("/", "\\")+"cacerts"; System.setProperty("javax.net.ssl.trustStore",keystore); env.put(Context.INITIAL_CONTEXT_FACTORY,"com.sun.jndi.ldap.LdapCtxFactory"); env.put(Context.SECURITY_AUTHENTICATION,"simple"); env.put(Context.SECURITY_PRINCIPAL,adminName); env.put(Context.SECURITY_CREDENTIALS,adminPassword); env.put(Context.SECURITY_PROTOCOL,"ssl"); String ldapURL = "ldap://8.8.8.8:636"; env.put(Context.PROVIDER_URL,ldapURL); try { PrintWriter out = response.getWriter(); //初始化ldapcontext LdapContext ctx = new InitialLdapContext(env,null); ModificationItem[] mods = new ModificationItem[1]; String newQuotedPassword = "\"" + newPassword + "\""; byte[] newUnicodePassword = newQuotedPassword.getBytes("UTF-16LE"); mods[0] = new ModificationItem(DirContext.REPLACE_ATTRIBUTE, new BasicAttribute("unicodePwd", newUnicodePassword)); // 修改密码 ctx.modifyAttributes(userName, mods); System.out.println("Reset Password for: " + userName); ctx.close(); m.put("success", true); JSONArray jsonArray = JSONArray.fromObject(m); out.print(jsonArray.toString()); } catch (NamingException e) { System.out.println("Problem resetting password: " + e); m.put("success", false); m.put("msg", "密码不符合要求或网络连接错误,请尝试重新输入密码或联系管理员。"); JSONArray jsonArray = JSONArray.fromObject(m); PrintWriter out; e.printStackTrace(); try { out = response.getWriter(); out.print(jsonArray.toString()); } catch (IOException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } } }
代码写的非常的烂,只是简单的实现了功能,希望大家多拍砖。