Spring Active Directory身份验证问题

时间:2016-11-23 06:10:45

标签: java spring spring-mvc active-directory ldap

我正在尝试更改活动目录中用户的密码。首先,我尝试了独立的java应用程序,我可以从中更改用户的密码。

工作代码:

    import javax.naming.*;
    import javax.naming.directory.*;
    import javax.naming.ldap.*;
    import java.util.*;
    import java.security.*;

    public class ChangePassword {
        DirContext ldapContext;
        String baseName = ",OU=Crowd,DC=Domain,DC=local";
        String serverIP = "xxx.xxx.xx.xxx";

        public ChangePassword() {
            try {
                Hashtable ldapEnv = new Hashtable(11);
                ldapEnv.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
                ldapEnv.put(Context.PROVIDER_URL, "ldaps://" + serverIP + ":636");
                ldapEnv.put(Context.SECURITY_AUTHENTICATION, "simple");
                ldapEnv.put(Context.SECURITY_PRINCIPAL, "cn=adminUser" + baseName);
                ldapEnv.put(Context.SECURITY_CREDENTIALS, "Password1234!!");

                //ldapEnv.put(Context.SECURITY_PROTOCOL, "ssl");
                ldapContext = new InitialDirContext(ldapEnv);

            } catch (Exception e) {
                System.out.println(" bind error: " + e);
                e.printStackTrace();
                System.exit(-1);
            }
        }

        public void updatePassword(String username, String password) {
            try {
                String quotedPassword = "\"" + password + "\"";
                char unicodePwd[] = quotedPassword.toCharArray();
                byte pwdArray[] = new byte[unicodePwd.length * 2];
                for (int i = 0; i < unicodePwd.length; i++) {
                    pwdArray[i * 2 + 1] = (byte) (unicodePwd[i] >>> 8);
                    pwdArray[i * 2 + 0] = (byte) (unicodePwd[i] & 0xff);
                }
                ModificationItem[] mods = new ModificationItem[1];
                mods[0] = new ModificationItem(DirContext.REPLACE_ATTRIBUTE, new BasicAttribute("UnicodePwd", pwdArray));
                ldapContext.modifyAttributes("cn=" + username + baseName, mods);
            } catch (Exception e) {
                System.out.println("update password error: " + e);
                System.exit(-1);
            }
        }

        public static void main(String[] args) {
            // Security.addProvider(new com.sun.net.ssl.internal.ssl.Provider());
            // the keystore that holds trusted root certificates
            System.setProperty("javax.net.ssl.trustStore", "C:\\Program Files\\Java\\jdk1.7.0_79\\bin\\client.jks");
            System.setProperty("javax.net.ssl.trustStorePassword", "changeit");
            System.setProperty("javax.net.debug", "all");   
            ChangePassword adc = new ChangePassword();
            adc.updatePassword("subuser", "Password!!");
            System.out.println("Password changed successfully");
        }
    }

在这个独立代码中,我可以访问活动目录并可以更改密码。我在Spring MVC中尝试过相同的操作。我在util包中添加了LDAP连接代码。然后我从控制器调用util类方法。我已经在控制器方法中自动安装了util类。

**Util class Code:** 

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import javax.naming.*;
import javax.naming.directory.*;
import javax.naming.ldap.*;
import java.util.*;
import java.security.*;

@Component
public class GetLDAPConnection {

    @Value("${ad.baseName}")
    String baseName;

    @Value("${ad.serverIP}")
    String serverIP;

    @Value("${ad.adminUser}")
    String adminUser;

    @Value("${ad.adminPassword}")
    String adminPassword;

    @Value("${ad.propertyStoreKey}")
    String propertyStoreKey;

    @Value("${ad.propertyStorePath}")
    String propertyStorePath;

    @Value("${ad.propertyTrustStore}")
    String propertyTrustStore;

    @Value("${ad.propertyTrustStorePass}")
    String propertyTrustStorePass;

    @Value("${ad.propertyDebug}")
    String propertyDebug;

    @Value("${ad.propertyDebugValue}")
    String propertyDebugValue;  

    DirContext ldapContext;
    /*String baseName = ",OU=Crowd,DC=Domain,DC=local";
    String serverIP = "192.168.50.164";*/


    @SuppressWarnings({ "unchecked", "rawtypes" })
    public void updatePassword(String username, String password) {
        try {

            System.out.println("adminUser :"+adminUser);
            System.out.println("serverIP :"+serverIP);
            System.out.println("baseName :"+baseName);
            System.out.println("adminPassword "+adminPassword);



            Hashtable ldapEnv = new Hashtable();
            ldapEnv.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
            ldapEnv.put(Context.PROVIDER_URL, "ldaps://" + serverIP + ":636");
            ldapEnv.put(Context.SECURITY_AUTHENTICATION, "simple");
            ldapEnv.put(Context.SECURITY_PRINCIPAL, "cn=" + adminUser + baseName);
            ldapEnv.put(Context.SECURITY_CREDENTIALS, adminPassword);

            // ldapEnv.put(Context.SECURITY_PROTOCOL, "ssl");
            ldapContext = new InitialDirContext(ldapEnv);
            System.out.println(ldapContext.getEnvironment());
            System.out.println(ldapContext.getNameInNamespace());
            Attributes attrs = ldapContext.getAttributes("dc=Domain,dc=local");
            System.out.println("ALL Data: " + attrs.toString());

            String quotedPassword = "\"" + password + "\"";
            char unicodePwd[] = quotedPassword.toCharArray();
            byte pwdArray[] = new byte[unicodePwd.length * 2];
            for (int i = 0; i < unicodePwd.length; i++) {
                pwdArray[i * 2 + 1] = (byte) (unicodePwd[i] >>> 8);
                pwdArray[i * 2 + 0] = (byte) (unicodePwd[i] & 0xff);
            }
            ModificationItem[] mods = new ModificationItem[1];
            mods[0] = new ModificationItem(DirContext.REPLACE_ATTRIBUTE, new BasicAttribute("UnicodePwd", pwdArray));
            ldapContext.modifyAttributes("cn=" + username + baseName, mods);


        } catch (Exception e) {
            System.out.println(" bind error: " + e);
            e.printStackTrace();
            System.exit(-1);
        } 
    }

}

我正在从属性文件中读取配置。

属性文件:

ad.baseName=,OU=Crowd,DC=Domain,DC=local
ad.serverIP=xxx.xxx.xx.xxx
ad.adminUser=adminUser
ad.adminPassword=Password1234!!
ad.propertyStoreKey=javax.net.ssl.trustStore
ad.propertyStorePath=C:\\Program Files\\Java\\jdk1.7.0_79\\bin\\client.jks
ad.propertyTrustStore=javax.net.ssl.trustStorePassword
ad.propertyTrustStorePass=changeit
ad.propertyDebug=javax.net.debug
ad.propertyDebugValue=all

我收到了异常

绑定错误:javax.naming.NameNotFoundException:[LDAP:错误代码32 - 0000208D:NameErr:DSID-03100238,问题2001(NO_OBJECT),数据0,最佳匹配:     'OU =人群中,DC = DOMAIN,DC =本地' 剩余名称'cn = null,OU = Crowd,DC = Domain,DC = local' javax.naming.NameNotFoundException:[LDAP:错误代码32 - 0000208D:NameErr:DSID-03100238,问题2001(NO_OBJECT),数据0,最佳匹配:     'OU =人群中,DC = DOMAIN,DC =本地'

我收到“javax.naming.NameNotFoundException”,因为CN = null正在追加。任何人都可以解释这是什么问题。我可以读取属性文件并打印出值。但问题只出现在这些方面。我甚至进行了硬编码和检查,但它确实有效。

ldapEnv.put(Context.SECURITY_PRINCIPAL,“cn =”+ adminUser + baseName); ldapEnv.put(Context.SECURITY_CREDENTIALS,adminPassword);

任何人都可以告诉我这里的问题是什么

0 个答案:

没有答案