java通过ldap做登录验证

需求需要在登录时连接Windows AD域控进行登录验证,结合前人代码整理改造为项目可用的状态,仅做记录

package com.sinosoft.microservice.product.manage.config.security.impl;

import com.sinosoft.microservice.product.manage.config.utils.ConfigStaticConstant;
import com.sinosoft.microservice.product.manage.config.utils.EscapeUtil;
import lombok.extern.slf4j.Slf4j;

import javax.naming.Context;
import javax.naming.NamingEnumeration;
import javax.naming.NamingException;
import javax.naming.directory.SearchControls;
import javax.naming.ldap.InitialLdapContext;
import javax.naming.ldap.LdapContext;
import java.util.Hashtable;

/**
 * @Author hsp
 * @Date 2023-05-29
 * @Company 
 * @Description
 * @Param
 * @return
 */
@Slf4j
public class ADAccountAuthority {

    private int connectADDomain(Hashtable<String, String> HashEnv, String host) {
        // 初始化用户结果集
        // StringBuffer userPrincipalName = new StringBuffer();
        // 初始化搜索结果数为0
        int rows = 0;
        try {
            LdapContext ctx = new InitialLdapContext(HashEnv, null);
            // 域节点
            String searchBase = "DC=test,DC=com";
            // LDAP搜索过滤器类
            // String searchFilter = "objectClass=*";
            String searchFilter = "objectClass=User";
            // 创建搜索控制器
            SearchControls searchCtls = new SearchControls();
            // 设置搜索范围
            searchCtls.setSearchScope(SearchControls.SUBTREE_SCOPE);
            // 定制返回属性 按需选择
            //String[] returnedAtts = {"memberOf", "distinguishedName", "Pwd-Last-Set", "User-Password", "cn"};
            //String[] returnedAtts = { "url", "whenChanged", "employeeID","name", "userPrincipalName", "physicalDeliveryOfficeName","departmentNumber", "telephoneNumber", "homePhone","mobile", "department", "sAMAccountName", "whenChanged","mail","objectClass" }; // 定制返回属性
            String[] returnedAtts = {"name", "userPrincipalName", "distinguishedName"};
            // 设置返回属性集
            searchCtls.setReturningAttributes(returnedAtts);
            EscapeUtil.safeLog(log, "******************* ADAccountCheck: AD配置设置完毕,尝试连接AD域控 ***********************");

            // 根据设置的域节点、过滤器类和搜索控制器搜索LDAP得到结果
            NamingEnumeration answer = ctx.search(searchBase, searchFilter, searchCtls);

            //整个while遍历结果注释掉,直接看能不能联通,联通rows+1,判断时如果rows>1就返回true
            if (answer.hasMoreElements()) {
                rows++;
            }
            EscapeUtil.safeLog(log, "******************* ADAccountCheck: 当前host " + host + "登录通过,rows值为: " + rows + " ***********************");

            /*while (answer.hasMoreElements()) {// 遍历结果集
                SearchResult sr = (SearchResult) answer.next();// 得到符合搜索条件的DN
                //System.out.println(sr.toString());
                //System.out.println("Attributes:   "+sr.getAttributes());
                //System.out.println("userPrincipalName:   "+sr.getAttributes().get("userPrincipalName"));
                Attributes Attrs = sr.getAttributes();// 得到符合条件的属性集
                if (Attrs != null && Attrs.get("userPrincipalName") != null) {
                    System.out.println(++rows + "************************************************");
                    System.out.println("Name:   " + sr.getName());
                    try {
                        for (NamingEnumeration ne = Attrs.getAll(); ne.hasMore(); ) {
                            Attribute Attr = (Attribute) ne.next();// 得到下一个属性
                            System.out.println(" AttributeID=属性名:" + Attr.getID());
                            // 读取属性值
                            for (NamingEnumeration e = Attr.getAll(); e.hasMore(); ) {
                                String value = e.next().toString();
                                System.out.println("    AttributeValues=属性值:" + value);
                                // 使用堡垒机登陆成功了114,但是没有拿到登录账号的数据,排查下是不是这里的问题
                                if ("userPrincipalName".equals(Attr.getID())) {
                                    userPrincipalName.append(value);
                                    userPrincipalName.append(",");
                                }
                            }

                            System.out.println("    ---------------");
                            // 读取属性值
                            // Enumeration values = Attr.getAll();
                            // if (values != null) { // 迭代
                            // while (values.hasMoreElements()) {
                            // System.out.println("    AttributeValues=属性值:"+
                            // values.nextElement());
                            // }
                            // }
                            // System.out.println("    ---------------");
                        }
                    } catch (NamingException e) {
                        System.err.println("Throw Exception : " + e);
                    }
                }
            }*/

            //System.out.println("************************************************");
            //System.out.println("TotalResults: " + rows);
            //EscapeUtil.safeLog(log, "******************* ADAccountCheck: 当前host " + host + "所有结果数 " + rows + " ***********************");
            //EscapeUtil.safeLog(log, "******************* ADAccountCheck: All ADAccount at host " + host + userPrincipalName.toString() + " ***********************");
            //System.out.println("域控所有账户: " + userPrincipalName.toString());
            ctx.close();
        } catch (NamingException e) {
            e.printStackTrace();
            //System.err.println("Throw Exception : " + e);
            EscapeUtil.safeError(log, "**************************ADAccountCheck: NamingException at host " + host + " **************************");
        }
        return rows;
    }


    public boolean checkAD(String userName, String password) {
        EscapeUtil.safeLog(log, "******************* Start ADAccountCheck v3 ***********************");
        EscapeUtil.safeLog(log, "******************* ADAccountCheck: AD域账户: " + userName + "" + " AD域密码: " + password + " ***********************");
        //初始化host列表
        String[] hosts = new String[]{ConfigStaticConstant.ADHOST_HKHKG1_DC01, ConfigStaticConstant.ADHOST_HKHKG1_DC02, ConfigStaticConstant.ADHOST_HKHKG2_DC01, ConfigStaticConstant.ADHOST_SGSIN1_DC01};
        for (String host : hosts) {
            EscapeUtil.safeLog(log, "******************* ADAccountCheck: Try to connect host " + host + " ***********************");
            String port = ConfigStaticConstant.LDAP_PORT; // 端口
            String domain = ConfigStaticConstant.DOMAIN; // 域名
            String url = "ldap://" + host + ":" + port;
            String user = userName + domain;
            Hashtable<String, String> hashEnv = new Hashtable<>();
            hashEnv.put(Context.SECURITY_AUTHENTICATION, "simple"); // LDAP访问安全级别
            hashEnv.put(Context.SECURITY_PRINCIPAL, user); // AD User
            hashEnv.put(Context.SECURITY_CREDENTIALS, password); // AD Password
            hashEnv.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory"); // LDAP工厂类
            hashEnv.put(Context.PROVIDER_URL, url);
            if (connectADDomain(hashEnv, host) > 0) {
                return true;
            }
            //下面这个是添加所有结果的,现在只测试连通性
//            result.append(connectADDomain(hashEnv, host));
//            if (result.length() != 0) {
//                EscapeUtil.safeLog(log, "******************* ADAccountCheck: All ADAccount at host " + host + result + " ***********************");
//                return result;
//            }
        }
        EscapeUtil.safeLog(log, "******************* ADAccountCheck: AD域账户 :"+userName+" 登陆失败***********************");
        return false;
    }

}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Java中进行LDAP认证时,禁用的用户认证通过的可能有以下原因: 1. 未及时同步禁用状态:LDAP服务器可能具有某种缓存机制,这可能导致禁用状态的用户信息在Java应用程序中没有及时更新。因此,如果禁用状态在LDAP服务器上被更新,但Java应用程序仍使用了之前缓存的用户信息,那么禁用的用户可能会通过认证。 2. 认证过程中的异常:在Java应用程序中,可能存在一些错误或异常情况,导致禁用用户仍然通过认证。例如,在ldap认证过程中可能发生连接超时、网络问题、LDAP服务器故障等情况,这些异常可能会导致禁用的用户通过认证。 为了解决这个问题,可以考虑以下措施: 1. 及时同步禁用状态:确保在LDAP服务器上禁用用户的操作能够及时更新到Java应用程序中。可以通过在Java应用程序中设置合适的缓存策略,或者手动刷新缓存来保证用户状态的及时同步。 2. 异常处理机制:在Java应用程序中,实施良好的异常处理机制是非常重要的。可以通过捕获和处理与LDAP认证相关的异常,来防止禁用用户通过认证。如果发生异常,可以返回相应的错误信息,明确告知用户认证失败的原因。 3. 定期监控LDAP服务器:定期监控LDAP服务器的运行状态和性能,确保其正常运行。同时,及时处理LDAP服务器中的故障,避免导致禁用用户通过认证的异常情况发生。 总结而言,JavaLDAP认证时禁用的用户通过认证的问题可能包含缓存同步、认证过程中的异常等原因。为了解决这个问题,应该及时同步禁用状态、加强异常处理机制以及定期监控LDAP服务器的运行状态。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值