private LdapContext getLdapContext()throws NamingException{
Hashtable<String,String> hashtable = new Hashtable<String,String>();
hashtable.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
hashtable.put(Context.PROVIDER_URL, "ldap://192.168.116.128:389");//服务器地址
hashtable.put(Context.SECURITY_AUTHENTICATION, "simple");
hashtable.put(Context.SECURITY_PRINCIPAL, "Administrator@abc.com");//用户名
hashtable.put(Context.SECURITY_CREDENTIALS, "321%cba");//密码
return new InitialLdapContext(hashtable,null);
}
然后进行相关的搜索设置:
LdapContext ctx = getLdapContext();
//设置分页大小
ctx.setRequestControls(new Control[] { new PagedResultsControl(15, Control.NONCRITICAL) });
SearchControls control = new SearchControls();
//搜索方式
control.setSearchScope(SearchControls.SUBTREE_SCOPE);//Search the entire subtree rooted at the named object.
//control.setSearchScope(SearchControls.ONELEVEL_SCOPE);//Search one level of the named context
//control.setSearchScope(SearchControls.OBJECT_SCOPE);//Search the named object
//搜索字段
String returnedAtts[] = { "displayName", "mail", "telephoneNumber","thumbnailPhoto" };//姓名,邮箱,电话,头像
control.setReturningAttributes(returnedAtts);
//设置ou和filter
String ou = "ou=users,ou=beijing,dc=abc,dc=com";
String filter = "(&(objectClass=user)(objectCategory=person)(!(userAccountControl:1.2.840.113556.1.4.803:=2)))";
NamingEnumeration<SearchResult> results = ctx.search(ou, filter, control);
while (results != null && results.hasMoreElements()) {
SearchResult entry = (SearchResult) results.next();
String empName = getValueFromAttribute(entry.getAttributes().get(returnedAtts[0]));
String mail = getValueFromAttribute(entry.getAttributes().get(returnedAtts[1]));
String telephone = getValueFromAttribute(entry.getAttributes().get(returnedAtts[2]));
byte[] photoBytes = null;
Attribute att = (Attribute) entry.getAttributes().get("thumbnailPhoto");
if(att!=null){
photoBytes = (byte[])(att.get(0));
}
System.out.println(empName+"|"+mail+"|"+telephone+"|"+(photoBytes==null ? 0 : photoBytes.length));
}
private boolean validate(String username,String pwd)throws NamingException{
Hashtable<String,String> hashtable = new Hashtable<String,String>();
hashtable.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
hashtable.put(Context.PROVIDER_URL, "ldap://192.168.116.128:389");//服务器地址
hashtable.put(Context.SECURITY_AUTHENTICATION, "simple");
hashtable.put(Context.SECURITY_PRINCIPAL, username);//用户名
hashtable.put(Context.SECURITY_CREDENTIALS, pwd);//密码
return new InitialLdapContext(hashtable,null)!=null;
}
下载工具后解压,然后:
复制jar包frdoumesspitc7.jar到tomcat的/lib目录下
复制SSPAuthentification.dll和SSPAuthentificationx64.dll到tomcat的/bin目录下
在应用的web.xml中增加如下配置:
<security-constraint>
<display-name>Example Security Constraint</display-name>
<web-resource-collection>
<web-resource-name>Protected Area</web-resource-name>
<!-- Define the context-relative URL(s) to be protected -->
<url-pattern>/auth.do</url-pattern>
<!-- If you list http methods, only those methods are protected -->
<http-method>DELETE</http-method>
<http-method>GET</http-method>
<http-method>POST</http-method>
<http-method>PUT</http-method>
</web-resource-collection>
<auth-constraint>
<!-- Anyone with one of the listed roles may access this area
<role-name>utilisateurs</role-name>
<role-name>users</role-name>
<role-name>everyone</role-name>-->
<role-name>everyone</role-name>
</auth-constraint>
</security-constraint>
<!-- Default login configuration -->
<login-config>
<auth-method>BASIC</auth-method>
<realm-name>Example Spnego</realm-name>
</login-config>
就这样,tomcatspnego就能使用了。这里使用到了Tomcat的目录保护功能,而tomcatspnego应该是对tomcat的验证功能做了修改,增加了域信息的检查。这里连没有配置域服务器ip地址都没有配置,tomcatspnego具体如何实现域信息监测就不太清楚了。
接下来,在我们自己的应用身份验证中需要用到tomcatspnego留给我们的标记:
@RequestMapping(value = "/auth")
public String ntlmAuth(HttpServletRequest request,HttpServletResponse response,HttpSession session){
Principal princ = request.getUserPrincipal();
if (isLogined()) {
return "redirect:index.do";
}
if(princ!=null){
session.setAttribute("princpalNameInSession", princ.getName());
}
return "redirect:index.do";
}
@RequestMapping("/login")
public ModelAndView login(String loginName,String password,HttpServletResponse response,HttpSession session,HttpServletRequest request) {
if(!response.isCommitted()){
ModelAndView mav = new ModelAndView();
mav.setViewName("login");
User user = null;
Config config = Config.getInstance(true);
if(notEmpty(loginName) && notEmpty(password)){//如果用户名和密码都存在,普通登录,或域账号登录
user = userService.getEntityByProperty(User.class, "userName", loginName);
if(user==null || user.getStatus()!=UserStatus.Active ){
mav.addObject("noUserError", "用户名不存在!");
}else{
if(user.getType()==UserType.Domain && config.isUseLdapValidate()){//域用户
if(domainLoginValidate(loginName,password,request,config)){
mav.setViewName("redirect:index.do");//域登录成功
}
}else{
if(localLoginValidate(user,password)){
mav.setViewName("redirect:index.do");//本地登录成功
}else{
mav.addObject("passwordError", "密码输入错误!");
}
}
}
}else if(domainLoginValidateByNtlm(request)){//存在域Ntlm变量,尝试域登录
//则根据域变量获取到用户名
String princpalName = getPrincpalUserName(request);
user = userService.getEntityByProperty(User.class, "userName", princpalName);
if(user!=null){
log.info("用户:"+loginName+",通过获取到本机域信息直接登录成功!");
}else{
mav.addObject("error","已经检测到您为域用户,但是在系统中没有查询到您的用户信息");
}
}else{
//用户名和密码以及域变量都不存在,重定向到登录页面
mav.setViewName("redirect:loginUI.do");
}
//然后获取到user信息,并加载权限信息,设置“已登录”标志
if(user!=null){
prepareFunctionPoint(session,user);
}
return mav;
}
return null;
}
@RequestMapping("/index")
public String index(HttpServletRequest request,HttpServletResponse response,HttpSession session){
if(!response.isCommitted()){
if (isLogined()) {
return "main";
}
Config config = Config.getInstance(true);
if(!config.isUseLdapValidate()){
return "redirect:loginUI.do";
}
// 则尝试根据域变量获取到用户信息;
User user = getUserFromDbByDomainUserName(request);
if (user != null) {
prepareFunctionPoint(session, user);
return "main";
}
return "redirect:loginUI.do";
}
return null;
}
说明:
这里把应用的首页设置为/auth.do,以便于当用户直接访问/的时候直接跳转到/auth.do;
在进入ntlmAuth方法之前,系统已经利用tomcatspnego来尝试域验证;
在auth方法中尝试获取tomcatspnego给我们留下来的变量,并保存起来;
从定向到index.do,index中尝试通过域变量来获取用户信息(获取成功表示域登陆成功);
login方法正常接收用户名和密码,可以进行本地账号验证和域账号验证。
相关推荐
LDAP实现AD域账号验证
Springboot-LDAP针对AD域控做用户和组织进行同步
centos6.x下使用yum安装gitlab,使用ldap认证登陆,ldap数据同步,gitlab脚本备份还原
实现ldap身份验证功能.windows域服务器验证该用户是否是合法用户。
confluence的安装过程(附图),confluence与ldap的集成过程还有集成以后的部分权限设置过程,以便LDAP用户直接登录
Python和LDAP域认证,python-LDAP软件,以及python-LDAP资料,还包含有在python中的cookie处理。
ad域,如何自动配置outlook账号和服务器地址,ldap通信目录
泛微协同管理ecology系统与LDAP集成手册
LDAP账号一体化管理的详细说明文档,具体包括LDAP的概念及使用,redmine、svn集成LDAP账号登陆,及LDAP的安全性控制及备份等。
使用JAVA创建AD/LDAP账号
H3C CAS LDAP帐号同步特性说明.pdf
自用LDAP同步
项目中使用spring boot框架集成了ldap协议的方法,调用了增删改查的API,基本实现了spring boot对于ldap的所有方法,只要搭建好了ldap服务器,改一下配置文件即可运行。
java域账号登录-java访问ldap; 有详细的注释说明,只有一个java文件,不是整个项目
利用UUP实现Portal和LDAP同步用户信息
实战从ldap老机器迁移账号数据到新机器,并有安装ldap流程,条理清楚,实战案例。
java使用ldap修改ad域用户密码
用于数据同步,将实现与企业LDAP或微软AD系统目录同步功能.
java连接和验证的ldap学习文档,密码的校验,通过jndi连接ldap服务
完整的LDAP同步组织机构用户模块,可通用