Announcement Announcement Module
Collapse
No announcement yet.
Weird behaviour from PasswordPolicyAwareContextSource? Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Weird behaviour from PasswordPolicyAwareContextSource?

    Since I started using this context source I've noticed some odd behaviour. I have a scenario in which I use a SpringSecurityLdapTemplate to do a lookup on a web user. In my test case I either (a) find the user or (b) add the user to my OpenLDAP directory and add him as a member of a groupOfNames. In either case I then use a BindAuthenticator to authenticate the user.

    Now for the weird part. If I use a DefaultSpringSecurityContextSource for the template and authenticator everything works fine but if I use the password policy-aware version all works well for the first user but then the code fails when I attempt to bind subsequent users. The error is a NoPermissionException. This only occurs if I use the new context source AND call BindAuthenticator.authenticate (see below).

    9/09/2010 3:22:22 PM org.springframework.security.ldap.DefaultSpringSec urityContextSource <init>
    INFO: URL 'ldap://localhost:389/dc=example,dc=com', root DN is 'dc=example,dc=com'
    cn=Freddy,ou=people,ou=franchisee not found
    User Freddy created
    User Freddy added to group
    9/09/2010 3:22:22 PM org.springframework.security.ldap.DefaultSpringSec urityContextSource <init>
    INFO: URL 'ldap://localhost:389/dc=example,dc=com', root DN is 'dc=example,dc=com'
    Freddy authenticated
    cn=Fanny,ou=people,ou=franchisee not found
    Exception in thread "main" org.springframework.ldap.NoPermissionException: [LDAP: error code 50 - no write access to parent]; nested exception is javax.naming.NoPermissionException: [LDAP: error code 50 - no write access to parent]; remaining name 'cn=Fanny,ou=people,ou=franchisee'
    at org.springframework.ldap.support.LdapUtils.convert LdapException(LdapUtils.java:177)
    at org.springframework.ldap.core.LdapTemplate.execute WithContext(LdapTemplate.java:810)
    at org.springframework.ldap.core.LdapTemplate.execute ReadWrite(LdapTemplate.java:802)
    at org.springframework.ldap.core.LdapTemplate.bind(Ld apTemplate.java:996)
    at UserMaker.makeUser(UserMaker.java:81)
    at UserMaker.test(UserMaker.java:127)
    at UserMaker.main(UserMaker.java:132)
    Caused by: javax.naming.NoPermissionException: [LDAP: error code 50 - no write access to parent]; remaining name 'cn=Fanny,ou=people,ou=franchisee'
    at com.sun.jndi.ldap.LdapCtx.mapErrorCode(Unknown Source)
    at com.sun.jndi.ldap.LdapCtx.processReturnCode(Unknow n Source)
    at com.sun.jndi.ldap.LdapCtx.processReturnCode(Unknow n Source)
    at com.sun.jndi.ldap.LdapCtx.c_bind(Unknown Source)
    at com.sun.jndi.toolkit.ctx.ComponentDirContext.p_bin d(Unknown Source)
    at com.sun.jndi.toolkit.ctx.PartialCompositeDirContex t.bind(Unknown Source)
    at javax.naming.directory.InitialDirContext.bind(Unkn own Source)
    at org.springframework.ldap.core.LdapTemplate$21.exec uteWithContext(LdapTemplate.java:998)
    at org.springframework.ldap.core.LdapTemplate.execute WithContext(LdapTemplate.java:807)
    ... 5 more

    My test program is:

    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 org.springframework.ldap.NamingException;
    import org.springframework.ldap.core.DirContextAdapter;
    import org.springframework.ldap.core.DirContextOperations ;
    import org.springframework.ldap.core.DistinguishedName;
    import org.springframework.security.authentication.Userna mePasswordAuthenticationToken;
    import org.springframework.security.core.Authentication;
    import org.springframework.security.ldap.SpringSecurityLd apTemplate;
    import org.springframework.security.ldap.authentication.B indAuthenticator;
    import org.springframework.security.ldap.ppolicy.Password PolicyAwareContextSource;


    public class UserMaker {

    private PasswordPolicyAwareContextSource ppCtx;
    private SpringSecurityLdapTemplate template;

    private static final String PASSWORD = "Secret2010";

    public UserMaker() {
    ppCtx = new PasswordPolicyAwareContextSource( "ldap://localhost:389/dc=example,dc=com" );
    ppCtx.setUserDn( "cn=manager,dc=example,dc=com" );
    ppCtx.setPassword( "secret" );
    try {
    ppCtx.afterPropertiesSet();
    }
    catch (Exception e) {

    e.printStackTrace();
    }
    template = new SpringSecurityLdapTemplate( ppCtx );
    }

    private boolean lookup( DistinguishedName dn ) {
    try {
    DirContextAdapter context = (DirContextAdapter) template.lookup( dn );
    System.out.println( dn.toCompactString() + " found" );
    return true;
    }
    catch ( NamingException e ) {
    System.out.println( dn.toCompactString() + " not found" );
    return false;
    }
    }

    private void addUserToGroup( DistinguishedName userDn ) {
    userDn.prepend( new DistinguishedName( "dc=example,dc=com" ) );
    BasicAttribute memberAttribute = new BasicAttribute( "member" );
    memberAttribute.add( userDn.toString() );
    ModificationItem[] modItems = { new ModificationItem( DirContext.ADD_ATTRIBUTE, memberAttribute ) };
    DistinguishedName defaultUserGroup = new DistinguishedName();
    defaultUserGroup.add( "ou", "groups" );
    defaultUserGroup.add( "cn", "Default" );
    template.modifyAttributes( defaultUserGroup, modItems );
    }

    private void makeUser( String username ) {
    DistinguishedName dn = new DistinguishedName();
    dn.add( "ou", "franchisee" );
    dn.add( "ou", "people" );
    dn.add( "cn", username );

    if ( !lookup( dn ) ) {
    Attributes attrs = new BasicAttributes();
    BasicAttribute ocAttr = new BasicAttribute( "objectclass" );
    ocAttr.add( "top" );
    ocAttr.add( "person" );
    ocAttr.add( "organizationalPerson" );
    ocAttr.add( "inetOrgPerson" );
    ocAttr.add( "cisOrgPerson" );
    attrs.put( ocAttr );
    attrs.put( "cn", username );
    attrs.put( "sn", username );
    attrs.put( "givenName", username );
    attrs.put( "userPassword", PASSWORD );
    template.bind( dn, null, attrs );
    System.out.println( "User " + username + " created" );
    addUserToGroup( dn );
    System.out.println( "User " + username + " added to group" );
    }

    UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken( username, PASSWORD );
    if ( !authenticate( token ) ) {
    System.exit( 0 );
    }
    }

    private boolean authenticate( Authentication authentication ) {
    UsernamePasswordAuthenticationToken userToken = ( UsernamePasswordAuthenticationToken ) authentication;
    BindAuthenticator bindAuthenticator = new BindAuthenticator( ppCtx );
    bindAuthenticator.setUserDnPatterns( new String[] { "cn={0},ou=people,ou=franchisee" } );
    try {
    bindAuthenticator.afterPropertiesSet();
    }
    catch (Exception e1) {
    e1.printStackTrace();
    }
    try {
    DirContextOperations userData = bindAuthenticator.authenticate( userToken );
    System.out.println( userToken.getName() + " authenticated" );
    return true;
    }
    catch( Exception e ) {
    e.printStackTrace();
    return false;
    }
    }

    private void test() {
    makeUser( "Freddy" );
    makeUser( "Fanny" );
    }

    public static void main(String[] args) {
    UserMaker userMaker = new UserMaker();
    userMaker.test();
    }

    }


    I've tried creating a fresh context source for each call to BindAuthenticator but that makes no difference. No one else seems to be complaining about this on the web so now I'm not sure if the problem lies with me or Spring Security and would value some feedback from someone more knowledgeable than myself.

    Many thanks in advance.

  • #2
    Hi mate,

    I'm having the exact same issue right now, did you figure out the problem?

    Thanks

    Comment

    Working...
    X