Announcement Announcement Module
Collapse
No announcement yet.
How to add user to active directory. Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • How to add user to active directory.

    Now I can add user in sun one directory server.
    But can not add to MS Active Directory.
    It seems that spring-ldap can not get "UserPassword" attribute from Active Directory.
    My code:
    Code:
    	   protected void mapToContext(User user, DirContextAdapter context) {
    		      context.setAttributeValue("givenname",user.getFirstName() + " " + user.getLastName() );
    		      context.setAttributeValue("cn", user.getUsername() );
    		      context.setAttributeValue("userPassword", user.getConfirmPassword().getBytes());
                    }
    Exception occured at
    context.setAttributeValue("userPassword", user.getConfirmPassword().getBytes());

  • #2
    It would be easier to track down the problem with a complete stack trace. Could you please include one?

    Comment


    • #3
      For active directory passwords don't you work with "unicodePwd" rather than "userPassword".

      Comment


      • #4
        You could try changing the password line to the following:

        Code:
        context.setAttributeValue("unicodePwd", 
            DirectoryUtility.createUnicodePassword(user.getConfirmPassword()));
        The DirectoryUtility class could look something like this:

        Code:
        public class DirectoryUtility {
        
            public static byte[] createUnicodePassword(String password) {
                return toUnicodeBytes(doubleQuoteString(password));
            }
        
            private static byte[] toUnicodeBytes(String str) {
                byte[] unicodeBytes = null;
                try {
                    byte[] unicodeBytesWithQuotes = str.getBytes("Unicode");
                    unicodeBytes = new byte[unicodeBytesWithQuotes.length - 2];
                    System.arraycopy(
                        unicodeBytesWithQuotes,
                        2,
                        unicodeBytes,
                        0,
                        unicodeBytesWithQuotes.length - 2);
                } catch (UnsupportedEncodingException e) {
                    // This should never happen.
                    e.printStackTrace();
                }
                return unicodeBytes;
            }
        
            private static String doubleQuoteString(String str) {
                StringBuffer sb = new StringBuffer();
                sb.append("\"");
                sb.append(str);
                sb.append("\"");
                return sb.toString();
            }
        }

        Comment


        • #5
          Get unicode password

          Before I add user, I want to check whether the user exist.
          I use:
          Code:
          ldapTemplate.search("",filter.encode(),new UserAttributesMapper());
          I got exception:
          Code:
          java.lang.NullPointerException
                  at org.springframework.ldap.LdapTemplate$9.executeWithContext(LdapTemplate.java:682)
                  at org.springframework.ldap.LdapTemplate.executeWithContext(LdapTemplate.java:641)
                  at org.springframework.ldap.LdapTemplate.executeReadOnly(LdapTemplate.java:628)
                  at org.springframework.ldap.LdapTemplate.lookup(LdapTemplate.java:678)
          The excpetion occured in UserAttributeMapper.mapFromAttribute method.
          Code:
          	private class UserAttributesMapper implements AttributesMapper {
          		  
          		 public Object mapFromAttributes(Attributes attrs) throws NamingException {
          	         User user = new User();
          	         Log.info(CLASS_NAME+ " UserAttributesMapper.mapFromAttributes attrs.toString()="+attrs.toString()) ;
          	         
          	         user.setUsername((String)attrs.get("cn").get());
          	         user.setFirstName((String)attrs.get("givenName").get());
          	         user.setLastName((String)attrs.get("sn").get());
          	         user.setPassword(attrs.get("unicodePwd").get().toString());
          	         
          	         return user;
          	         
          	      }
          	   }
          In out log, I find there do not exist "unicodePwd" field in attrs.
          my log:
          Code:
          DEBUG [http-8080-Processor22] -  UserAttributesMapper.mapFromAttributes attrs.toStrin
          g()={displayname=displayName: admin admin, givenname=givenName: admin, samaccounttype=sAMAccountType: 805306368, primarygroup
          id=primaryGroupID: 513, objectclass=objectClass: top, person, organizationalPerson, user, admincount=adminCount: 1, badpasswo
          rdtime=badPasswordTime: 128084908723125000, objectcategory=objectCategory: CN=Person,CN=Schema,CN=Configuration,DC=TEST,DC=co
          m, cn=cn: admin, useraccountcontrol=userAccountControl: 66048, userprincipalname=userPrincipalName: [email protected], codepage=
          codePage: 0, distinguishedname=distinguishedName: CN=admin,CN=Users,DC=TEST,DC=com, whenchanged=whenChanged: 20061120083724.0
          Z, whencreated=whenCreated: 20061115062602.0Z, pwdlastset=pwdLastSet: 128084854443593750, logoncount=logonCount: 1, accountex
          pires=accountExpires: 9223372036854775807, lastlogoff=lastLogoff: 0, objectguid=objectGUID: ?>?vn?K???As?bH, sn=sn: admin, l
          astlogon=lastLogon: 128084908756093750, usnchanged=uSNChanged: 9922343, usncreated=uSNCreated: 9921268, objectsid=objectSid:
                  ~jA????~?j  , countrycode=countryCode: 0, samaccountname=sAMAccountName: admin, instancetype=instanceType: 4,
           memberof=memberOf: CN=Administrators,CN=Builtin,DC=TEST,DC=com, badpwdcount=badPwdCount: 0, name=name: admin}

          Comment


          • #6
            It's quite possible that the unicode password Attribute will only be returned under spacial circumstances. E.g. administrator privileges might be required, or it might be an operational attribute, in which case you'll need to ask for it specifically (using one of the methods which take an array of Attribute names).

            Comment


            • #7
              unicodePwd is only a writable attribute (only by admin user and via LDAPS connection).

              It's used internally to update the real userPassword attribute which is invisible even for admin user.

              Comment


              • #8
                I'm not sure if this helps but it may be worth looking at.

                http://forum.java.sun.com/thread.jsp...2611&tstart=50

                And for more AD information take a look at his other threads. He seems pretty knowledgable about AD

                http://forum.java.sun.com/profile.jspa?userID=488701


                Russ

                Comment


                • #9
                  Thank you very mush guys.

                  After I setup LDAPS in my domain controller, I can add user to AD already.

                  But I find all of the added user are disabled.
                  Anybody meet this problem before?

                  Comment


                  • #10
                    I believe it's the userAccountControl field that controls this, among many other aspects. It's a bitfield and the second bit controls enabled/disabled.

                    In other words, if you currently have say 546 (512+32+2) in userAccountControl for your disabled users, you should instead set it to 544 (512+32).

                    Comment


                    • #11
                      Thank you ulsa.

                      After I add below code, I can add user successfully.
                      Code:
                      context.setAttributeValue("userAccountControl",Integer.toString(UF_NORMAL_ACCOUNT));
                      Now problem is when I update user password, I get below exception:

                      Code:
                      org.springframework.ldap.UncategorizedLdapException: Operation failed; nested exception is javax.naming.directory.AttributeInUseException: [LDAP: error code 20
                      - 0000207E: AtrErr: DSID-03190617, #1:
                              0: 0000207E: DSID-03190617, problem 1006 (ATT_OR_VALUE_EXISTS), data 0, Att 9005a (unicodePwd)
                       ]
                      javax.naming.directory.AttributeInUseException: [LDAP: error code 20 - 0000207E: AtrErr: DSID-03190617, #1:
                              0: 0000207E: DSID-03190617, problem 1006 (ATT_OR_VALUE_EXISTS), data 0, Att 9005a (unicodePwd)
                       ]; remaining name 'cn=test'
                              at com.sun.jndi.ldap.LdapCtx.mapErrorCode(LdapCtx.java:2972)
                              at com.sun.jndi.ldap.LdapCtx.processReturnCode(LdapCtx.java:2934)
                              at com.sun.jndi.ldap.LdapCtx.processReturnCode(LdapCtx.java:2740)
                              at com.sun.jndi.ldap.LdapCtx.c_modifyAttributes(LdapCtx.java:1440)
                              at com.sun.jndi.toolkit.ctx.ComponentDirContext.p_modifyAttributes(ComponentDirContext.java:255)
                              at com.sun.jndi.toolkit.ctx.PartialCompositeDirContext.modifyAttributes(PartialCompositeDirContext.java:172)
                              at javax.naming.directory.InitialDirContext.modifyAttributes(InitialDirContext.java:151)
                              at org.springframework.ldap.LdapTemplate$13.executeWithContext(LdapTemplate.java:741)
                              at org.springframework.ldap.LdapTemplate.executeWithContext(LdapTemplate.java:641)
                              at org.springframework.ldap.LdapTemplate.executeReadWrite(LdapTemplate.java:636)
                              at org.springframework.ldap.LdapTemplate.modifyAttributes(LdapTemplate.java:738)

                      My code:
                      Code:
                      context.setAttributeValue("unicodePwd",LDAPUtil.createUnicodePassword((String) obj));
                      ldapTemplate.modifyAttributes(dn, context.getModificationItems());

                      Comment


                      • #12
                        Please check the contents of getModificationItems and post the results here.

                        Comment


                        • #13
                          I add code:

                          Code:
                          ModificationItem[] milist= context.getModificationItems();
                          		    Log.debug( CLASS_NAME + " saveUser (User user) milist.length=" + milist.length);
                          		    for(int i=0;i<milist.length ;i++)
                          		    {
                          		    	ModificationItem mi=milist[i];
                          		    	
                          		    	Log.debug( CLASS_NAME + " saveUser (User user) mi.toString()=" + mi.toString());
                          		    
                          		    }
                          The log is:

                          Code:
                          DEBUG [http-8080-Processor20] - 
                          ldap.UserDAOLDAP saveUser (User user) milist.length=1
                          2006-12-08, 09:11:53 mcap_log debug
                          DEBUG [http-8080-Processor20] - 
                          ldap.UserDAOLDAP saveUser (User user) mi.toString()=Add attribute: unicodePwd: [B@75725e
                          I think the problem is "Add attribute", how to set it as "Update attribute"?

                          Comment


                          • #14
                            The problem seems to be that Active Directory doesn't allow the attribute to be read, and thus gives us the false impression that it doesn't exist. Spring LDAP then believes the attribute should be added, but since the attribute in fact does exist, the ADD operation fails.

                            This can be avoided by forcing a REPLACE operation for this specific attribute. This will require significant changes in getModificationItems. A short-term solution is to manually change the operation for this attribute from DirContext.ADD_ATTRIBUTE to DirContext.REPLACE_ATTRIBUTE.

                            Comment


                            • #15

                              After I add below code all works. Thank you very much

                              Code:
                              ModificationItem[] milist= context.getModificationItems();
                                 Log.debug( CLASS_NAME + " saveUser (User user) milist.length=" + milist.length);
                              		    
                              for(int i=0;i<milist.length ;i++)
                              {
                                ModificationItem mi=milist[i];
                                Attribute attr=mi.getAttribute();
                                if("unicodePwd".equalsIgnoreCase(attr.getID()))
                               {
                                  mi=new ModificationItem(DirContext.REPLACE_ATTRIBUTE ,attr);
                                  milist[i]=mi;
                                  break;
                               }
                              }
                              		    
                              ldapTemplate.modifyAttributes(dn, milist);

                              Comment

                              Working...
                              X