一、用户认证
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 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 m = new HashMap();
//校验两次输入的密码是否一致
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 = "p@ssword";
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();
}
}
}
代码写的非常的烂,只是简单的实现了功能,希望大家多拍砖。
有问题可以留言。