LDAP SSL 連接

使用SSL來連接LDAP server有多種方法(http://yagodnoe.ifmo.ru/~ad/Documentation/jndi-1_4_2-tutorial/ldap/security/ssl.html#SERVER),但大都需要client端指定keystore和password,其實對於大部分應用,client會接受server端的證書,所以更通用的方法是應用前面鏈接中提到的Custom Socket Factory.下面給出示例:

--------------------------DummyTrustManager------------------------------

package com.auth.ldaps;

import java.security.cert.*;
import javax.net.ssl.*;
import java.security.cert.X509Certificate;
public class DummyTrustManager implements X509TrustManager {
    public void checkClientTrusted( X509Certificate[] cert, String authType) {
        return;
    }
   
    public void checkServerTrusted( X509Certificate[] cert, String authType) {
        return;
    }
   
    public X509Certificate[] getAcceptedIssuers() {
        return new X509Certificate[0];
    }
}

---------------------------DummySSLSocketFactory---------------------------

package com.auth.ldaps;

import java.security.cert.X509Certificate;
import java.io.IOException;
import java.net.InetAddress;
import java.net.Socket;
import javax.net.ssl.*;
import javax.net.SocketFactory;

public class DummySSLSocketFactory extends SSLSocketFactory {

    private SSLSocketFactory factory;
   
    public DummySSLSocketFactory() {
   
        try {
       
        SSLContext sslcontext = SSLContext.getInstance("TLS");
       
        sslcontext.init( null, // No KeyManager required
       
        new TrustManager[] { new DummyTrustManager()},
       
        new java.security.SecureRandom());
       
        factory = ( SSLSocketFactory) sslcontext.getSocketFactory();
       
        } catch( Exception ex) { ex.printStackTrace(); }
   
    }
   
    public static SocketFactory getDefault() {
   
    return new DummySSLSocketFactory();
   
    }
   
    public Socket createSocket( Socket socket, String s, int i, boolean flag) throws IOException {
   
    return factory.createSocket( socket, s, i, flag);
   
    }
   
    public Socket createSocket( InetAddress inaddr, int i, InetAddress inaddr1, int j) throws IOException {
   
    return factory.createSocket( inaddr, i, inaddr1, j);
   
    }
   
    public Socket createSocket( InetAddress inaddr, int i) throws IOException {
   
    return factory.createSocket( inaddr, i);
   
    }
   
    public Socket createSocket( String s, int i, InetAddress inaddr, int j) throws IOException {
   
    return factory.createSocket( s, i, inaddr, j);
   
    }
   
    public Socket createSocket( String s, int i) throws IOException {
   
    return factory.createSocket( s, i);
   
    }
   
    public String[] getDefaultCipherSuites() {
   
    return factory.getSupportedCipherSuites();
   
    }
   
    public String[] getSupportedCipherSuites() {
   
    return factory.getSupportedCipherSuites();
   
    }

}
--------------------------LdapsAuthn test-------------------

package com.auth.ldaps;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Properties;

import javax.naming.Context;
import javax.naming.NamingEnumeration;
import javax.naming.NamingException;
import javax.naming.directory.Attributes;
import javax.naming.directory.DirContext;
import javax.naming.directory.InitialDirContext;
import javax.naming.directory.SearchControls;
import javax.naming.directory.SearchResult;

import com.sun.org.apache.xml.internal.security.exceptions.Base64DecodingException;
import com.sun.org.apache.xml.internal.security.utils.Base64;

public class LdapsAuthn {
    public static void main(String args[]) {
        String server = "hpt087-win32";
        String port = "11636";
        String admin = "uid=admin,ou=system";
        String adminPass = "secret";
        String testUser = "abc";
        String baseDN = "ou=users,ou=system";
        if (connect(server, port, admin, adminPass, testUser, baseDN)) {
            System.out.println("Successful");
        } else {
            System.out.println("Fail");
        }
    }
   
    public static boolean connect(String server, String port, String user, String passwd, String testUser, String baseDN) {
        boolean result = false;
        Properties env = new Properties();
        String ldapURL = "ldap://" + server + ":" + port;
       
        env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");  
        env.put(Context.SECURITY_AUTHENTICATION, "simple");  
        env.put(Context.SECURITY_PRINCIPAL, user);  
        env.put(Context.SECURITY_CREDENTIALS, passwd);  
        env.put(Context.PROVIDER_URL, ldapURL);
        env.put(Context.REFERRAL,"ignore");
        env.put(Context.SECURITY_PROTOCOL,"ssl");
       
        env.put("java.naming.ldap.factory.socket", "com.auth.ldaps.DummySSLSocketFactory");
        try {
            DirContext ctx = new InitialDirContext(env);
            SearchControls searchCtls = new SearchControls();  
            searchCtls.setSearchScope(SearchControls.SUBTREE_SCOPE);  
            NamingEnumeration<?> results = ctx.search(baseDN, "uid=" + testUser, searchCtls);  
            while (results.hasMoreElements()) {  
                SearchResult sr = (SearchResult) results.next();     
                Attributes attributes = sr.getAttributes();
                System.out.println(attributes);
            }  
            ctx.close();  
            result = true;
        } catch (NamingException e) {
            e.printStackTrace();
        }

        return result;
    }
}

 

參考資料:

http://java.itags.org/java-core-apis/49920/

http://yagodnoe.ifmo.ru/~ad/Documentation/jndi-1_4_2-tutorial/ldap/security/ssl.html#SERVER

http://blogs.sun.com/andreas/entry/no_more_unable_to_find


 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章