编程开源技术交流,分享技术与知识

网站首页 > 开源技术 正文

Java,UnboundID,内存LDAP服务支持,客户认证

wxchong 2024-08-23 00:02:07 开源技术 19 ℃ 0 评论

LDAP(Lightweight Directory Access Protocol):

轻量目录访问协议,一般都简称为LDAP。它是基于X.500标准的,可根据需要定制。与X.500不同,LDAP支持TCP/IP,这对访问Internet是必须的。LDAP的核心规范在RFC中都有定义,所有与LDAP相关的RFC都可以在LDAPman RFC网页中找到。

LDAP的主要应用场景:

1、网络服务:DNS服务;2、统一认证服务;3、Linux PAM (ssh, login, cvs. . . );4、Apache访问控制5、各种服务登录(ftpd, php based, perl based, python based. . . );6、个人信息类,如地址簿;7、服务器信息,如帐号管理、邮件服务等;

UnboundID LDAP SDK:

提供了一套快速、强大、用户友好并且开源的Java API来与LDAP目录服务器交互,与其它基于Java的LDAP APIs相比,它具有更好的性能、更易于使用,功能更多,而且还是唯一个不断有活跃开发和增强的SDK。官网地址:https://www.ldap.com/unboundid-ldap-sdk-for-java

代码案例:

pom.xml

<!--使用unboundid嵌入式LDAP-->
<dependency>
    <groupId>com.unboundid</groupId>
    <artifactId>unboundid-ldapsdk</artifactId>
    <version>3.2.0</version>
</dependency>
package com.what21.ldap.server;

import com.unboundid.ldap.listener.InMemoryDirectoryServerConfig;
import com.unboundid.ldap.sdk.LDAPException;
import org.springframework.util.StringUtils;


public class LdapServerConfig {

    private InMemoryDirectoryServerConfig serverConfig;

    private String userBaseDN;

    private String userDN;

    public LdapServerConfig(String baseDn,String userBaseDN,String userId){
        if(!StringUtils.isEmpty(userBaseDN) && userBaseDN.endsWith(",")){
            userDN = "uid=" + userId + userBaseDN;
        }else{
            userDN = "uid=" + userId + "," + userBaseDN;
        }
        String[] ldapDnArray = { baseDn, userBaseDN, userDN };
        try {
            serverConfig = new InMemoryDirectoryServerConfig(ldapDnArray);
        } catch (LDAPException e) {
            e.printStackTrace();
        }
    }

    /**
     * @return
     */
    public InMemoryDirectoryServerConfig getLdapServerConfig(){
        return serverConfig;
    }

    public String getUserBaseDN() {
        return userBaseDN;
    }

    public String getUserDN() {
        return userDN;
    }

    public void setUserDN(String userDN) {
        this.userDN = userDN;
    }

}
package com.what21.ldap.server;

import com.unboundid.ldap.listener.InMemoryListenerConfig;
import com.unboundid.ldap.sdk.LDAPException;

public class LdapListenerConfig{

    private InMemoryListenerConfig config;

    /**
     * @param port
     */
    public LdapListenerConfig(int port){
        this("default",port);
    }

    /**
     * @param name
     * @param port
     */
    public LdapListenerConfig(String name,int port){
        try {
            this.config = new InMemoryListenerConfig(name,null,port,null,null,null);
        } catch (LDAPException e) {
            e.printStackTrace();
        }
    }

    /**
     * @return
     */
    public InMemoryListenerConfig getInMemoryListenerConfig(){
        return config;
    }

}
package com.what21.ldap.server;

import lombok.extern.slf4j.Slf4j;

import com.unboundid.ldap.listener.interceptor.InMemoryInterceptedSimpleBindRequest;
import com.unboundid.ldap.listener.interceptor.InMemoryOperationInterceptor;
import com.unboundid.ldap.sdk.LDAPException;
import com.unboundid.ldap.sdk.ResultCode;
import com.unboundid.ldap.sdk.SimpleBindRequest;

@Slf4j
public class LdapOptInterceptor extends InMemoryOperationInterceptor {

    String userBaseDN;
    String userDN;
    String userId;
    String passwd;

    public LdapOptInterceptor(String userBaseDN, String userDN, String userId,
                              String passwd) {
        this.userBaseDN = userBaseDN;
        this.userDN = userDN;
        this.userId = userId;
        this.passwd = passwd;
    }

    @Override
    public void processSimpleBindRequest(InMemoryInterceptedSimpleBindRequest request)
            throws LDAPException {
        String bindDN = request.getRequest().getBindDN();
        String passwd = request.getRequest().getPassword().stringValue();
        log.debug("request bindDN ->" + bindDN);
        log.debug("request passwd ->" + passwd);
        if (bindDN.contains(userBaseDN)) {
            bindDN = bindDN.replace("," + userBaseDN, "");
        }
        if (bindDN.contains("=")) {
            try {
                bindDN = bindDN.substring(bindDN.indexOf("="), bindDN.length());
            } catch (Exception e) {
            }
        }
        log.debug("do treatment bindDN ->" + bindDN);
        String result = "-1";
        // 假设认证成功
        result = "1000";
        // 认证逻辑
        if ("1000".equals(result)) {
            request.setRequest(new SimpleBindRequest(this.userDN, this.passwd));
        } else if ("1001".equals(result)) {
            throw new LDAPException(ResultCode.AUTH_UNKNOWN, "Unable to bind user,because the provided password was incorrect.");
        } else if ("1002".equals(result)) {
            throw new LDAPException(ResultCode.AUTH_UNKNOWN, "Unable to bind user,because user is not authorized.");
        } else {
            throw new LDAPException(ResultCode.AUTH_UNKNOWN, "Unable to bind user,because unknown error.");
        }
        super.processSimpleBindRequest(request);
    }

}
package com.what21.ldap.server;

import com.unboundid.ldap.listener.InMemoryDirectoryServer;
import com.unboundid.ldap.listener.InMemoryDirectoryServerConfig;
import com.unboundid.ldap.sdk.Attribute;
import com.unboundid.ldap.sdk.LDAPException;

public class LdapMemoryServer {

    private int port;
    private String baseDN;
    private String userBaseDN;

    private final String userId = "default";
    private final String passwd = "default";

    private InMemoryDirectoryServer dirServer;

    /**
     * @param port
     * @param baseDN
     * @param userBaseDN
     */
    public LdapMemoryServer(int port, String baseDN, String userBaseDN) {
        this.port = port;
        this.baseDN = baseDN;
        this.userBaseDN = userBaseDN;
    }

    public void startServer() {
        // LDAPServer配置
        LdapServerConfig serverConfig = new LdapServerConfig(baseDN, userBaseDN, userId);
        // 监听配置
        LdapListenerConfig listenerConfig = new LdapListenerConfig(port);
        String userDN = serverConfig.getUserDN();
        // 监听
        LdapOptInterceptor interceptor = new LdapOptInterceptor(userBaseDN, userDN,
                userId, passwd);
        // LDAP
        try {
            InMemoryDirectoryServerConfig config = serverConfig.getLdapServerConfig();
            config.addInMemoryOperationInterceptor(interceptor);
            config.setListenerConfigs(listenerConfig.getInMemoryListenerConfig());
            config.setSchema(null);
            dirServer = new InMemoryDirectoryServer(config);
            // 添加属性
            dirServer.add(userDN, getUidAttr(), getPasswdAttr());
            dirServer.startListening();
        } catch (LDAPException e) {
            e.printStackTrace();
        }
    }

    /**
     * @return
     */
    private Attribute getUidAttr() {
        return new Attribute("uid", passwd);
    }

    /**
     * @return
     */
    private Attribute getPasswdAttr() {
        return new Attribute("userPassword", userId);
    }

    /**
     * 停止服务
     */
    public void stopServer() {
        if (dirServer != null) {
            dirServer.shutDown(true);
        }
    }

    public static void main(String[] args) {
        int port = 1389;
        String baseDN = "dc=what21,dc=com";
        String userBaseDN = "ou=users" + "," + baseDN;
        LdapMemoryServer server = new LdapMemoryServer(port, baseDN, userBaseDN);
        server.startServer();
        try {
            Thread.sleep(10000000L);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

}

客户端认证实现:

package com.what21.ldap.client;

import java.util.Properties;

import javax.naming.NamingException;
import javax.naming.ldap.InitialLdapContext;

public class LdapClientAuthen {

    /**
     * @param url
     * @param name
     * @param domain
     * @param passwd
     * @return
     */
    public static InitialLdapContext auth(String url, String domain, String name, String passwd) {
        Properties mEnv = new Properties();
        mEnv.put(InitialLdapContext.AUTHORITATIVE, "true");
        mEnv.put(InitialLdapContext.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
        mEnv.put(InitialLdapContext.PROVIDER_URL, url);
        mEnv.put(InitialLdapContext.SECURITY_AUTHENTICATION, "simple");
        mEnv.put(InitialLdapContext.SECURITY_PRINCIPAL, name);
        mEnv.put(InitialLdapContext.SECURITY_CREDENTIALS, passwd);
        try {
            return new InitialLdapContext(mEnv, null);
        } catch (NamingException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * @param args
     */
    public static void main(String[] args) {
        String url = "ldap://127.0.0.1:1389";
        String domain = "what21.com";
        String username = "uid=account,ou=users,dc=what21,dc=com";
        String passwd = "password";
        InitialLdapContext content = auth(url, domain, username, passwd);
        if(content!=null){
            System.out.println("认证成功:" + content);
        }else{
            System.out.println("认证失败:" + content);
        }
        try {
            content.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}

Tags:

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表