ldap.rememberMe.usernameMapper.userDnBase (multiple instances of?) (searchSubtree search capability)

自古美人都是妖i 提交于 2020-01-03 00:55:10

问题


I have a Grails application that is successfully using the latest spring-security-core:2.0-RC4 and spring-security-ldap:2.0-RC2. Users can login perfectly using grails.plugin.springsecurity.ldap.search.base setting for LDAP login authentication.

There is a different setting for the rememberMe userDnBase (mapper) and that setting is: grails.plugin.springsecurity.ldap.rememberMe.usernameMapper.userDnBase

The LDAP authentication grails.plugin.springsecurity.ldap.search.base is set to ou=people,dc=sitcudy,dc=edu. As mentioned above - the logins work fine because there is a property called searchSubtree that I have set to true. Unfortunately, the searchSubtree setting does not hold true and carry through consistently within the 'remember-me' portion of the code (.ldap.rememberMe)*. The remember-me portion of the code uses a map for the base DN, grails.plugin.springsecurity.ldap.rememberMe.usernameMapper.userDnBase so I put in a string in the config.groovy file (the same as for the authentication piece) to map to the base DN of ou=people,dc=sitcudy,dc=edu.... which gets mapped to the DN for the LDAP user look up upon returning to the application for persistence cookie login.

Here's where my problem comes in, most users are segregated into different DIT's in our LDAP system. For example, some uses are in ou=staff,ou=people,dc=sitcudy,dc=edu while other users are in ou=students,ou=people,dc=sitcudy,dc=edu therefore, because of the remember me mapping, upon returning to the application, once verifying the cookie, the code tries to bind users in this format, uid=reuben_marcus,ou=people,dc=sitcudy,dc=edu which doesn't exist. What does exist is uid=reuben_marcus,ou=staff,ou=people,dc=sitcudy,dc=edu therefore the cookie is destroyed and the login (IS_AUTHENTICATED_REMEMBERED) never occurs.

If I change grails.plugin.springsecurity.ldap.rememberMe.usernameMapper.userDnBase to ou=staff,ou=people,dc=sitcudy,dc=edu the remember me functionality works perfect for all staff members, but it doesn't work for all other people - students, faculty etc.

The main setting in question below for me in this issue is: grails.plugin.springsecurity.ldap.rememberMe.usernameMapper.userDnBase

Since this is just a mapping and there isn't allowance for multiple userDNBases or searchSubtree search.. How is the ‘remember-me’ code supposed to find users that do not fall into this base DN setting...??

I wonder if I'm doing something wrong or if this is a feature request to have the ‘remember me’ code have options for multiple mapping userDNBases or allow it to have a searchSubtree search capability.

Relevant settings from my config.groovy:

grails.plugin.springsecurity.ldap.mapper.roleAttributes = 'sitPriRole,uid'
grails.plugin.springsecurity.ldap.context.managerDn = 'uid=SPS_bind,ou=People,dc=sitcudy,dc=edu'
grails.plugin.springsecurity.ldap.context.managerPassword = 'xxx' 
grails.plugin.springsecurity.ldap.context.server = 'ldap://ds01.sitcudy.edu:389'
grails.plugin.springsecurity.ldap.authorities.groupSearchBase ='ou=Groups,dc=sitcudy,dc=edu' 


grails.plugin.springsecurity.ldap.search.base = 'ou=People,dc=sitcudy,dc=edu'
grails.plugin.springsecurity.ldap.search.searchSubtree = true
grails.plugin.springsecurity.ldap.auth.hideUserNotFoundExceptions = false
grails.plugin.springsecurity.ldap.search.attributesToReturn = ['uid', 'sitPriRole', 'mail', 'displayName']
grails.plugin.springsecurity.providerNames = ['ldapAuthProvider', 'anonymousAuthenticationProvider', 'rememberMeAuthenticationProvider']
grails.plugin.springsecurity.ldap.authorities.retrieveGroupRoles = false
grails.plugin.springsecurity.ldap.authorities.retrieveDatabaseRoles = false
grails.plugin.springsecurity.password.algorithm = 'SHA-256'


grails.plugin.springsecurity.rememberMe.persistent = true 
grails.plugin.springsecurity.rememberMe.persistentToken.domainClassName = 'od.PersistentLogin' 


// role-specific LDAP config 
// grails.plugin.springsecurity.ldap.useRememberMe = true
grails.plugin.springsecurity.ldap.rememberMe.detailsManager.attributesToRetrieve = null 
grails.plugin.springsecurity.ldap.rememberMe.detailsManager.groupMemberAttributeName = 'uniquemember'
grails.plugin.springsecurity.ldap.rememberMe.detailsManager.groupRoleAttributeName = 'cn' 
grails.plugin.springsecurity.ldap.rememberMe.detailsManager.groupSearchBase = 'ou=Groups,dc=sitcudy,dc=edu'
grails.plugin.springsecurity.ldap.rememberMe.detailsManager.passwordAttributeName = 'userPassword'
grails.plugin.springsecurity.ldap.rememberMe.usernameMapper.userDnBase = 'ou=People,dc=sitcudy,dc=edu'
grails.plugin.springsecurity.ldap.rememberMe.usernameMapper.usernameAttribute = 'uid'

回答1:


This problem was mentioned here: Grails - Spring security plugin ldap: remember me not working

I found a workaround for this by registering custom TokenBasedRememberMeServices bean in resources.groovy. I didn't use persistent logins functionality available in grails-spring-security-ldap plugin, because I found it incompatible with my Active Directory tree layout. Most probably, this could be customized by extending LdapUserDetailsManager but in my situation I found it unnecessary to store token in database.

I used regular spring security remember me cookie option but without storing user password in the cookie. I extended the following methods from TokenBasedRememberMeServices

  • makeTokenSignature - make token signature without password field
  • processAutoLoginCookie- if cookie exists, then retrieve username from cookie token and fetch ldap user details (I had to write my own method retrieveUserFromLdap() explained later)
  • onLoginSuccess - this gets triggered when user logs in with remember-me option checked. Here, I'm removing password and saving token signature to cookie.

To fetch user details and roles from LDAP it might depend on specific implementation but my method looks like this:

    static protected UserDetails retrieveUserFromLdap(String username) {
    def ldapUserSearch = Holders.applicationContext.getBean('ldapUserSearch')
    def userContextMapper = Holders.applicationContext.getBean('ldapUserDetailsMapper')
    def authoritiesPopulator = Holders.applicationContext.getBean('ldapAuthoritiesPopulator')

    def userContext = ldapUserSearch.searchForUser(username)
    def userAuthorities = authoritiesPopulator.getGrantedAuthorities(userContext,username)
    userContextMapper.mapUserFromContext(userContext,username,userAuthorities)
}


来源:https://stackoverflow.com/questions/26784260/ldap-rememberme-usernamemapper-userdnbase-multiple-instances-of-searchsubtre

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!