无法使用Java创建活动目录用户

时间:2011-11-17 23:45:22

标签: java active-directory windows-server-2008-r2

我有一个带有活动目录的Windows Server 2008R2。 我想创建一个Java程序,允许08/15用户将新用户添加到此AD。

我在oracle论坛找到了[example] [1]并为我的AD修改了它。:

package model;

import java.io.IOException;
import java.util.Hashtable;

import javax.naming.Context;
import javax.naming.NamingException;
import javax.naming.directory.Attributes;
import javax.naming.directory.BasicAttribute;
import javax.naming.directory.BasicAttributes;
import javax.naming.directory.DirContext;
import javax.naming.directory.ModificationItem;
import javax.naming.ldap.InitialLdapContext;
import javax.naming.ldap.LdapContext;
import javax.naming.ldap.StartTlsRequest;
import javax.naming.ldap.StartTlsResponse;

public class NewUser2 {
public static void main(String[] args) {

    Hashtable<String,String> env = new Hashtable<String, String>();
    String adminName = "CN=Administrator,CN=Users,DC=Dom215-01,DC=local";
    String adminPassword = "g18";
    String userName = "CN=Foo Bar,OU=Schueler,DC=Dom215-01,DC=local";
    String groupName = "OU=Schueler,DC=Dom215-01,DC=local";

    env.put(Context.INITIAL_CONTEXT_FACTORY,
            "com.sun.jndi.ldap.LdapCtxFactory");

    // set security credentials, note using simple cleartext authentication
    env.put(Context.SECURITY_AUTHENTICATION, "simple");
    env.put(Context.SECURITY_PRINCIPAL, adminName);
    env.put(Context.SECURITY_CREDENTIALS, adminPassword);

    // connect to my domain controller
    env.put(Context.PROVIDER_URL, "ldap://10.18.215.112");

    try {

        // Create the initial directory context
        LdapContext ctx = new InitialLdapContext(env, null);

        // Create attributes to be associated with the new user
        Attributes attrs = new BasicAttributes(true);

        attrs.put("objectClass", "Schueler");
        attrs.put("samAccountName", "FooBar");
        attrs.put("cn", "Foo Bar");

        // These are some optional (but useful) attributes
        attrs.put("givenName", "Foo");
        attrs.put("sn", "Bar");
        attrs.put("displayName", "Foo Bar");
        attrs.put("description", "Test Subject");

    /*  
        attrs.put("userPrincipalName", "asdf@asdf.com");
        attrs.put("mail", "sdaf@sdaf.com");
        attrs.put("telephoneNumber", "999 123 4567");
    */

        // some useful constants from lmaccess.h
        int UF_ACCOUNTDISABLE = 0x0002;
        int UF_PASSWD_NOTREQD = 0x0020;
        int UF_PASSWD_CANT_CHANGE = 0x0040;
        int UF_NORMAL_ACCOUNT = 0x0200;
        int UF_DONT_EXPIRE_PASSWD = 0x10000;
        int UF_PASSWORD_EXPIRED = 0x800000;

        attrs.put(
                "userAccountControl",
                Integer.toString(UF_NORMAL_ACCOUNT + UF_PASSWD_NOTREQD
                        + UF_PASSWORD_EXPIRED + UF_ACCOUNTDISABLE));

        // Create the context
        Context result = ctx.createSubcontext(userName, attrs);
        System.out.println("Created disabled account for: " + userName);

        StartTlsResponse tls = (StartTlsResponse) ctx
                .extendedOperation(new StartTlsRequest());
        tls.negotiate();

        ModificationItem[] mods = new ModificationItem[2];

        String newQuotedPassword = "\"Password2000\"";
        byte[] newUnicodePassword = newQuotedPassword.getBytes("UTF-16LE");

        mods[0] = new ModificationItem(DirContext.REPLACE_ATTRIBUTE,
                new BasicAttribute("unicodePwd", newUnicodePassword));
        mods[1] = new ModificationItem(DirContext.REPLACE_ATTRIBUTE,
                new BasicAttribute("userAccountControl",
                        Integer.toString(UF_NORMAL_ACCOUNT
                                + UF_PASSWORD_EXPIRED)));

        ctx.modifyAttributes(userName, mods);
        System.out.println("Set password & updated userccountControl");

        try {
            ModificationItem member[] = new ModificationItem[1];
            member[0] = new ModificationItem(DirContext.ADD_ATTRIBUTE,
                    new BasicAttribute("member", userName));

            ctx.modifyAttributes(groupName, member);
            System.out.println("Added user to group: " + groupName);

        } catch (NamingException e) {
            System.err.println("Problem adding user to group: " + e);
        }

        tls.close();
        ctx.close();

        System.out.println("Successfully created User: " + userName);

    } catch (NamingException e) {
        System.err.println("Problem creating object: ");
        e.printStackTrace();
    }

    catch (IOException e) {
        System.err.println("Problem creating object: ");
        e.printStackTrace();
    }
  }
}

到目前为止,一切看起来都很好,但是当它试图在第76行创建结果对象时,它会崩溃NoSuchAttributeException和LDAP错误代码16(没有这样的属性)。 我已尝试在用户名字符串和属性中进行各种修改,但没有任何帮助。

有没有人知道为什么会出现这种错误?

1 个答案:

答案 0 :(得分:13)

确定。对不起,我是这个论坛的新手。 无论如何......再次解决方案:

package model;

import java.util.Hashtable;

import javax.naming.Context;
import javax.naming.NamingException;
import javax.naming.directory.Attribute;
import javax.naming.directory.Attributes;
import javax.naming.directory.BasicAttribute;
import javax.naming.directory.BasicAttributes;
import javax.naming.ldap.InitialLdapContext;
import javax.naming.ldap.LdapContext;

public class NewUser {

    private static final String DOMAIN_NAME = "Dom215-01";
    private static final String DOMAIN_ROOT = "DC=Dom215-01,DC=local";
    private static final String DOMAIN_URL = "ldap://10.18.215.112:389";
    private static final String ADMIN_NAME = "CN=Administrator,CN=Users,DC=Dom215-01,DC=local";
    private static final String ADMIN_PASS = "g18";

    private String userName, firstName, lastName, password, organisationUnit;
    private LdapContext context;

    public NewUser(String userName, String firstName, String lastName,
                    String password, String organisationUnit) {

        this.userName = userName;
        this.firstName = firstName;
        this.lastName = lastName;
        this.password = password;
        this.organisationUnit = organisationUnit;

        Hashtable<String, String> env = new Hashtable<String, String>();

        env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");

        // set security credentials, note using simple cleartext authentication
        env.put(Context.SECURITY_AUTHENTICATION, "simple");
        env.put(Context.SECURITY_PRINCIPAL, ADMIN_NAME);
        env.put(Context.SECURITY_CREDENTIALS, ADMIN_PASS);

        // connect to my domain controller
        env.put(Context.PROVIDER_URL, DOMAIN_URL);

        try {
            this.context = new InitialLdapContext(env, null);
        } catch (NamingException e) {
            System.err.println("Problem creating object: ");
            e.printStackTrace();
        }

    }

    public boolean addUser() throws NamingException {

        // Create a container set of attributes
        Attributes container = new BasicAttributes();

        // Create the objectclass to add
        Attribute objClasses = new BasicAttribute("objectClass");
        objClasses.add("top");
        objClasses.add("person");
        objClasses.add("organizationalPerson");
        objClasses.add("user");

        // Assign the username, first name, and last name
        String cnValue = new StringBuffer(firstName).append(" ").append(lastName).toString();
        Attribute cn = new BasicAttribute("cn", cnValue);
        Attribute sAMAccountName = new BasicAttribute("sAMAccountName", userName);
        Attribute principalName = new BasicAttribute("userPrincipalName", userName
                + "@" + DOMAIN_NAME);
        Attribute givenName = new BasicAttribute("givenName", firstName);
        Attribute sn = new BasicAttribute("sn", lastName);
        Attribute uid = new BasicAttribute("uid", userName);

        // Add password
        Attribute userPassword = new BasicAttribute("userpassword", password);

        // Add these to the container
        container.put(objClasses);
        container.put(sAMAccountName);
        container.put(principalName);
        container.put(cn);
        container.put(sn);
        container.put(givenName);
        container.put(uid);
        container.put(userPassword);

        // Create the entry
        try {
            context.createSubcontext(getUserDN(cnValue, organisationUnit), container);
            return true;
        } catch (Exception e) {
            return false;
        }
    }

    private static String getUserDN(String aUsername, String aOU) {
        return "cn=" + aUsername + ",ou=" + aOU + "," + DOMAIN_ROOT;
    }
}