Quantcast

Cannot get database roles to work with Grails Spring Security LDAP plugin

classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate
star

Cannot get database roles to work with Grails Spring Security LDAP plugin

typoknig
This post was updated on .
I have a situation where I need to validate a user via LDAP, but use roles stored in my database to secure different sections of my website. I don't want to store passwords on my database, but I do want to store some additional information about the user in my database which I will get from LDAP. I would rather not have a separate class for user details, but instead just use the User class created by the Spring Security plugin. I have had user validation via LDAP working correctly at some point, but not in conjunction with using roles from my database. I have commented out the password attribute and some other fields from the User class which I do not need, then added in some of my own fields so the class looks like this:

package mypackage

class User {

transient springSecurityService

String displayName // Added by me
String email // Added by me
String firstName // Added by me
String lastName // Added by me
String username
//String password
boolean enabled
//boolean accountExpired
//boolean accountLocked
//boolean passwordExpired

static constraints = {
displayName( nullable: true )
email( nullable: true )
firstName( nullable: true )
lastName( nullable: true )
username( blank: false, nullable: true, unique: true )
//password( nullable: true )
enabled( nullable: true )
//accountExpired( nullable: true )
//accountLocked( nullable: true )
//passwordExpired( nullable: true )
}

// static mapping = {
// password column: '`password`'
// }

Set getAuthorities() {
UserRole.findAllByUser(this).collect { it.role } as Set
}

// def beforeInsert() {
// encodePassword()
// }

// def beforeUpdate() {
// if (isDirty('password')) {
// encodePassword()
// }
// }

// protected void encodePassword() {
// password = springSecurityService.encodePassword(password)
// }

String toString() {
firstName + " " + lastName
}
}


I have a User, Role, and UserRole instance in my database, and the user in question is also in LDAP. When I attempt to log in I get the following error:

URI:
/mypackage/j_spring_security_check
Class:
groovy.lang.MissingPropertyException
Message:
No such property: password for class: mypackage.User
It appears to me that the Spring Security plugin is looking for a password in my database, and I don't think the LDAP validation has happened yet but I have verified the LDAP validation has taken place using Wireshark. In my config file I have specified
grails.plugins.springsecurity.providerNames = ['ldapAuthProvider', 'anonymousAuthenticationProvider']
because the docs indicate this should instruct the plugin to only validate against LDAP.

Here is the rest of my config for the Spring Security plugin:

// Spring Security LDAP configuration
grails.plugins.springsecurity.ldap.context.managerDn = 'user@example.com'
grails.plugins.springsecurity.ldap.context.managerPassword = 'password'
grails.plugins.springsecurity.ldap.context.server = 'ldap://ldap.server.com:389'
grails.plugins.springsecurity.ldap.authorities.ignorePartialResultException = true // This is needed for Active Directory
grails.plugins.springsecurity.ldap.search.base = 'dc=mydc,dc=example,dc=com'
grails.plugins.springsecurity.ldap.search.filter="sAMAccountName={0}" // This is needed for Active Directory
grails.plugins.springsecurity.ldap.auth.hideUserNotFoundExceptions = false
grails.plugins.springsecurity.ldap.authorities.retrieveDatabaseRoles = true
grails.plugins.springsecurity.providerNames = ['ldapAuthProvider', 'anonymousAuthenticationProvider'] // specify this when you want to skip attempting to load from db and only use LDAP
grails.plugins.springsecurity.ldap.useRememberMe = true
//grails.plugins.springsecurity.ldap.search.attributesToReturn = ['mail', 'displayName'] // extra attributes you want returned

// Added by Spring Security LDAP to make the "remember me" feature on the login page work.
grails.plugins.springsecurity.rememberMe.persistent = true
grails.plugins.springsecurity.rememberMe.persistentToken.domainClassName = 'mypackage.PersistentLogin'

// Added by the Spring Security Core plugin:
grails.plugins.springsecurity.userLookup.userDomainClassName = 'mypackage.User'
grails.plugins.springsecurity.userLookup.authorityJoinClassName = 'mypackage.UserRole'
grails.plugins.springsecurity.authority.className = 'mypackage.Role'
grails.plugins.springsecurity.successHandler.defaultTargetUrl = '/search' // This is the location a user is sent to after they login unless they were trying to access a different page before they logged in.


Any guidance would be much appreciated.
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate
star

Re: Cannot get database roles to work with Grails Spring Security LDAP plugin

typoknig
I should note that Spring Security LDAP + database roles works fine IF I specify a password in the database.  It doesn't matter what that password is, as long as it isn't null or an empty string.

It just seems to me that I should not need the password field at all in Spring Security plugin's User class if I am not using it.
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate
star

Re: Cannot get database roles to work with Grails Spring Security LDAP plugin

rlovtangen
I don't know the details of the LDAP plugin, but when implementing my own authentication provider, I faced the problem that my userdetail class (which is not the same as the domain class for user) extended org.codehaus.groovy.grails.plugins.springsecurity.GrailsUser, which calls the constructor on its superclass org.springframework.security.core.userdetails.User :

    public User(String username, String password, boolean enabled, boolean accountNonExpired,
            boolean credentialsNonExpired, boolean accountNonLocked, Collection<? extends GrantedAuthority> authorities) {

        if (((username == null) || "".equals(username)) || (password == null)) {
            throw new IllegalArgumentException("Cannot pass null or empty values to constructor");
        }
   ...

As you can see, it doesn't work well with null as password, even if it's not used by the authentication provider.

I endend up just providing a dummy password, that is never used.


Also, the remember me functionality will not work without a password, if not using persistent cookie (which is best anyway). This is because TokenBasedRememberMeServices uses password when creating token (so that a token is no longer valid if user changed his password).


Ronny

On Jul 3, 2012, at 8:54 PM, typoknig wrote:

> I should note that Spring Security LDAP + database roles works fine IF I
> specify a password in the database.  It doesn't matter what that password
> is, as long as it isn't null or an empty string.
>
> It just seems to me that I should not need the password field at all in
> Spring Security plugin's User class if I am not using it.
>
> --
> View this message in context: http://grails.1312388.n4.nabble.com/Cannot-get-database-roles-to-work-with-Grails-Spring-Security-LDAP-plugin-tp4631006p4631009.html
> Sent from the Grails - user mailing list archive at Nabble.com.
>
> ---------------------------------------------------------------------
> To unsubscribe from this list, please visit:
>
>    http://xircles.codehaus.org/manage_email
>
>


---------------------------------------------------------------------
To unsubscribe from this list, please visit:

    http://xircles.codehaus.org/manage_email


Loading...