【问题标题】:Change mail attribute of Active Directory更改 Active Directory 的邮件属性
【发布时间】:2014-02-24 03:43:17
【问题描述】:

我正在尝试使用 java 更改 Active Directory 的邮件和密码属性。为此,它生成了一个安全证书并导入到 jvm (carcerts) 的证书存储中。使用 ssl 成功建立连接,但是在尝试更改任何字段(例如邮件)时,我收到以下错误消息:

javax.naming.OperationNotSupportedException: [LDAP: error code 53 - 00002035: LdapErr: DSID-0C090B3E, comment: Operation not allowed through GC port, data 0, v1db1

源代码:

// change mail
private void salvarEmailESenhaNoAd() throws IOException, NamingException {
    Properties mudaSenhaProperties = new PropertiesFactory().propertiesByJndi("mudaSenha");

    ADUtil adUtil = null;

    try
    {
        adUtil = new ADUtil(mudaSenhaProperties);

        adUtil.changeEmail("CN=018061671627,OU=SDS,OU=CS,OU=STI,OU=DG,OU=PRES,OU=TRERN,DC=tre-rn,DC=jus,DC=br", dadosUsuario.getEmail());

    }
    finally
    {
        if (adUtil != null)
        {
            adUtil.close();
        }
    }
}



public class ADUtil {

private LdapContext ldapContext = null;

public ADUtil(Properties properties) throws NamingException
{
    ldapContext = createUserContext(properties);
}


private LdapContext createUserContext(Properties properties) throws NamingException {


    String javaNamingFactoryInitial = properties.getProperty("java.naming.factory.initial");
    String javaNamingProviderUrl = properties.getProperty("java.naming.provider.url");
    String javaNamingSecurityAuthentication = properties.getProperty("java.naming.security.authentication");
    String javaNamingSecurityPrincipal = properties.getProperty("java.naming.security.principal");
    String javaNamingSecurityCredentials = properties.getProperty("java.naming.security.credentials");
    String javaNamingSecurityProtocol = properties.getProperty("java.naming.security.protocol");
    String javaNamingReferral = properties.getProperty("java.naming.referral");
    String javaNetSslTrustStore = properties.getProperty("javax.net.ssl.trustStore");
    String javaNetSslTrustStorePassword = properties.getProperty("javax.net.ssl.trustStorePassword");

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

    System.setProperty("javax.net.ssl.trustStore", javaNetSslTrustStore);
    System.setProperty("javax.net.ssl.trustStorePassword", javaNetSslTrustStorePassword);

    env.put(Context.INITIAL_CONTEXT_FACTORY, javaNamingFactoryInitial);
    env.put(Context.SECURITY_AUTHENTICATION, javaNamingSecurityAuthentication);
    env.put(Context.SECURITY_PRINCIPAL, javaNamingSecurityPrincipal);
    env.put(Context.SECURITY_CREDENTIALS, javaNamingSecurityCredentials);
    env.put(Context.SECURITY_PROTOCOL, javaNamingSecurityProtocol); // para poder modificar password y grupos del usuario.
    env.put(Context.PROVIDER_URL, javaNamingProviderUrl);
    env.put(Context.REFERRAL, javaNamingReferral);

    return new InitialLdapContext(env, null);
}


public void changePassword(String userCN, String newPassword) throws NamingException, UnsupportedEncodingException, IOException {

    modifyAdAttribute(userCN, "unicodePwd", converteString(newPassword));
    System.out.println("Password changed for " + userCN);
}

public void changeEmail(String userDN, String newEmail) throws NamingException, UnsupportedEncodingException, IOException {

    modifyAdAttribute(userDN, "mail", converteString(newEmail));
    System.out.println("Email changed for " + newEmail);

} 


private void modifyAdAttribute(String userCN, String attribute, Object value) throws NamingException{
    ModificationItem[] modificationItem = new ModificationItem[1];
    modificationItem[0] = new ModificationItem(DirContext.REPLACE_ATTRIBUTE,
            new BasicAttribute(attribute, value));
    ldapContext.modifyAttributes(userCN, modificationItem);

}


private static byte[] converteString(String password) throws UnsupportedEncodingException{
    String newQuotedPassword = "\"" + password + "\"";
    return newQuotedPassword.getBytes("UTF-16LE");
}

public void close() throws NamingException
{
    if (ldapContext != null)
    {
        ldapContext.close();
    }
}

读取属性通常使用以下代码:

public class TesteLdap {

/**
 * @param args the command line arguments
 */
private static SearchControls getSimpleSearchControls() {
    SearchControls searchControls = new SearchControls();
    searchControls.setSearchScope(SearchControls.SUBTREE_SCOPE);
    searchControls.setTimeLimit(30000);
    //String[] attrIDs = {"objectGUID"};
    //searchControls.setReturningAttributes(attrIDs);
    return searchControls;
}

public static void main(String[] args) throws NamingException {


    try {

        Hashtable env = new Hashtable();
        env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
        env.put(Context.PROVIDER_URL, "ldap://rndc10.tre-rn.jus.br:3269");
        env.put(Context.SECURITY_AUTHENTICATION, "simple");
        env.put(Context.SECURITY_PRINCIPAL, "user");
        env.put(Context.SECURITY_CREDENTIALS, "password");

        env.put(Context.SECURITY_PROTOCOL, "ssl");
        env.put(Context.REFERRAL, "ignore");

        String filter = "(&(objectClass=user)(CN=018061671627))";

        LdapContext ctx = new InitialLdapContext(env, null);
        ctx.setRequestControls(null);
        NamingEnumeration<?> namingEnum = ctx.search("OU=DG,OU=PRES,OU=TRERN,DC=tre-rn,DC=jus,DC=br", filter, getSimpleSearchControls());

        while (namingEnum.hasMore()) {
            SearchResult result = (SearchResult) namingEnum.next();
            Attributes attrs = result.getAttributes();
            System.out.println(attrs.get("cn"));
            System.out.println(attrs.get("displayname"));
            System.out.println(attrs.get("mail"));
            System.out.println(attrs.get("distinguishedName"));

        }
        namingEnum.close();
    } catch (Exception e) {
        e.printStackTrace();

我的环境:Windows 2008R2 Standart 上的 Active Directory,在 unbutu 12.10 上运行的 Open JDK 7。

如果有人帮助我,我将不胜感激,因为我已经尝试了所有方法,但无法成功。

【问题讨论】:

    标签: java active-directory ldap runtime-error change-password


    【解决方案1】:

    错误似乎是不言自明的。您应该使用端口 636 通过 LDAPS 执行此操作。 你试过用吗

    env.put(Context.PROVIDER_URL, "ldaps://rndc10.tre-rn.jus.br:636");
    

    (请注意,如果您单独指定 ssl,则 ldaps:// 不是强制性的)。

    【讨论】:

      【解决方案2】:

      您的环境中是否有 RODC(只读 DC)?如果是,那么 rndc10.tre-rn.jus.br 是 RODC 吗?

      也许您应该指向一个可写的 DC?

      您是否尝试过更新此字符串:

       env.put(Context.PROVIDER_URL, "ldap://rndc10.tre-rn.jus.br:3269");
      

      到:

       env.put(Context.PROVIDER_URL, "ldaps://rndc10.tre-rn.jus.br:3269");
                                          ^
      

      【讨论】:

        猜你喜欢
        • 2022-11-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-06-11
        • 2023-03-26
        • 1970-01-01
        • 1970-01-01
        • 2023-04-04
        相关资源
        最近更新 更多