0
votes

Im currently working on integration of my app with company ldap. While i was able to make application actually check users on ldap for authentication, users are not able to overcome spring security ROLES configuration. Im getting: "Denied Sorry, you're not authorized to view this page." Every time i try to enter page that has @Secured(['ROLE_USER']) on it. I would like to know how to add every user on LDAP to have ROLE_USER so he will be able to fully use application.

My ldap configuration is pretty simple:

grails.plugin.springsecurity.providerNames = ['ldapAuthProvider','anonymousAuthenticationProvider','rememberMeAuthenticationProvider']
grails.plugin.springsecurity.ldap.context.anonymousReadOnly = true
grails.plugin.springsecurity.ldap.context.server = "SOME LDAP ADRESS"
grails.plugin.springsecurity.ldap.authorities.groupSearchBase = 'ou=Employees,O=*****,C=****'

grails.plugin.springsecurity.ldap.search.base = 'O=****,C=****'
grails.plugin.springsecurity.ldap.authorities.retrieveGroupRoles = true
grails.plugin.springsecurity.ldap.authorities.retrieveDatabaseRoles = true
grails.plugin.springsecurity.ldap.authorities.groupSearchFilter = 'member={0}'
grails.plugin.springsecurity.ldap.search.attributesToReturn = null

And spring security core is default one:

// Added by the Spring Security Core plugin:
grails.plugin.springsecurity.userLookup.userDomainClassName = 'amelinium1.grails.SecUser'
grails.plugin.springsecurity.userLookup.authorityJoinClassName = 'amelinium1.grails.SecUserSecRole'
grails.plugin.springsecurity.authority.className = 'amelinium1.grails.SecRole'
grails.plugin.springsecurity.controllerAnnotations.staticRules = [
    '/**':                              ['permitAll'],
    '/**/systeminfo':                 ['permitAll'],
    '/**/js/**':                      ['permitAll'],
    '/**/css/**':                     ['permitAll'],
    '/**/images/**':                  ['permitAll']]
grails.plugin.springsecurity.logout.postOnly = false

Documentation provided on http://grails-plugins.github.io/grails-spring-security-core/docs/manual/guide/single.pdf seems to be not up to date even if it is for 2.0 version of spring security core. I've tried to implement Custom GrailsUser and GrailsUserDetailsService but they dont seem to blend with rest of the plugin.(implementation based on documentation).

Anyone could point me to right direction with some info about how to implement LDAP in newest version 2.0-RC2?

EDIT

My CustomUserDetailsService class, but im not sure if its right configuration for LDAP:

    class CustomUserDetailsService implements GrailsUserDetailsService{

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {

        User.withTransaction { status ->

            User user = User.findByUsername(username)
            if (!user) throw new UsernameNotFoundException('User not found', username)

            def authorities = user.authorities.collect {new GrantedAuthorityImpl(it.authority)}

            return new CustomUserDetails(user.username, user.password, user.enabled,
                    !user.accountExpired, !user.passwordExpired,
                    !user.accountLocked, authorities ?: NO_ROLES, user.id,
                    user.firstName, user.lastName)
        } as UserDetails
    }

    @Override
    public UserDetails loadUserByUsername(String username, boolean loadRoles)
            throws UsernameNotFoundException, DataAccessException {

        return loadUserByUsername(username);
    }

}

And CustomUserDetails class:

class CustomUserDetails extends GrailsUser{
        final String firstName
        final String lastName

        CustomUserDetails(String username, String password, boolean enabled,
                          boolean accountNonExpired, boolean credentialsNonExpired,
                          boolean accountNonLocked,
                          Collection<GrantedAuthority> authorities,
                          long id, String firstName, String lastName) {
            super(username, password, enabled, accountNonExpired,
                    credentialsNonExpired, accountNonLocked, authorities, id)

            this.firstName = firstName
            this.lastName = lastName
        }
    }

Problem is that i cannot get other informations from LDAP than username as ldap login. Would appreciate help here also. After reworking application to beb ased on Customclasses im getting errors like : No signature of method: static org.springframework.security.core.userdetails.User.findByUsername() is applicable for argument types: (java.lang.String) values: [hajduk]

1

1 Answers

5
votes

By default the Spring Security plugin gets user and role data from the database. The Spring bean that is responsible for reading the user and role data is named userDetailsService. If you want to get your user and role data from somewhere else - e.g. LDAP - you simply need to replace this bean with your own, e.g.

import org.springframework.security.core.userdetails.*
import org.springframework.security.core.userdetails.UsernameNotFoundException
import org.springframework.dao.DataAccessException

class LdapUserDetailsService implements UserDetailsService {

    UserDetails loadUserByUsername(String username) throws UsernameNotFoundException, DataAccessException {
        // load the user and their role(s) from LDAP by username and return their 
        // details as an instance of a class that implements the UserDetails interface
    }
}

Don't forget to register this class as a Spring bean in resources.groovy

userDetailsService(LdapUserDetailsService)

There are plugins that integrate Spring Security with LDAP, but I would prefer to do it myself given that it's so easy. The docs provide an example of a custom UserDetailsService. Note that it's not necessary to extend any particular class when writing your own implementations of UserDetailsService/UserDetails, and for the purposes of debugging it's probably easier to just implement the interfaces directly.