ldap.rememberMe.usernameMapper.userDnBase(?的多个实例)(searchSubtree搜索功能) [英] ldap.rememberMe.usernameMapper.userDnBase (multiple instances of?) (searchSubtree search capability)

查看:129
本文介绍了ldap.rememberMe.usernameMapper.userDnBase(?的多个实例)(searchSubtree搜索功能)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个成功使用最新的 spring-security-core:2.0-RC4 spring-security-ldap的Grails应用程序: 2.0- RC2 即可。用户可以使用
grails.plugin.springsecurity.ldap.search.base 设置完美登录LDAP登录身份验证。



rememberMe userDnBase (mapper)有一个不同的设置,该设置是:
grails.plugin.springsecurity.ldap.rememberMe.usernameMapper .userDnBase



LDAP身份验证 grails.plugin.springsecurity.ldap.search.base 设置为 ou = people,dc = sitcudy,dc = edu 。如上所述 - 登录可以正常工作,因为我设置为true的属性名为 searchSubtree 。不幸的是, searchSubtree 设置不成立,并且在代码的部分 (。ldap.rememberMe 的)* 即可。代码的记忆部分使用基础DN的映射, grails.plugin.springsecurity.ldap.rememberMe.usernameMapper.userDnBase
,所以我把在 config.groovy 文件中的字符串(与验证片段相同)映射到 ou = people,dc = sitcudy,dc = edu ....它被映射到LDAP用于LDAP用户在返回应用程序进行持久性cookie登录时查找。



这是我的问题出现的地方,大多数用户在我们的LDAP系统中被隔离到不同的DIT中。例如,某些用途位于 ou = staff,ou = people,dc = sitcudy,dc = edu ,而其他用户位于 ou =学生ou = people,dc = sitcudy,dc = edu 因此,由于记住了我的映射,在返回到应用程序后,一旦验证cookie,代码就会尝试以这种格式绑定用户, uid = reuben_marcus,ou = people,dc = sitcudy,dc = edu 不存在。存在的是 uid = reuben_marcus,ou = staff,ou = people,dc = sitcudy,dc = edu ,因此cookie被销毁并且登录( em> IS_AUTHENTICATED_REMEMBERED )永远不会发生。



如果我更改 grails.plugin.springsecurity.ldap.rememberMe.usernameMapper .userDnBase
ou = staff,ou = people,dc = sitcudy,dc = edu 对于所有工作人员来说,但它并不适用于所有其他人 - 学生,教师等。

下面这个问题的主要设置对我来说是:
grails.plugin.springsecurity.ldap.rememberMe.usernameMapper.userDnBase



由于这只是一个并且不允许多个 userDNBases searchSubtree 搜索。记得我'的代码应该找到不属于你的用户s基地DN设置... ??



我想知道我是否做错了什么,或者如果这是一个功能请求让我记住我'代码可以选择多个映射 userDNBases 或允许它具有 searchSubtree 搜索功能。



我的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 =组,dc = sitcudy,dc = edu'


grails.plugin.springsecurity.ldap.search.base ='ou =人员,dc = sitcudy,dc = edu'
grails.plugin.springsecurity.ldap.search.searc hSubtree = 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'


//特定于角色的LDAP配置
// grails.plugin.springsecurity.ldap.useRememberMe = true
grails.plugin.springsecurity.ldap.rememberMe.detailsManager.attributesToRetrieve = null
圣杯s.plugin.springsecurity.ldap.rememberMe.detailsManager.groupMemberAttributeName ='uniquemember'
grails.plugin.springsecurity.ldap.rememberMe.detailsManager.groupRoleAttributeName ='cn'
grails.plugin.springsecurity.ldap。 rememberMe.detailsManager.groupSearchBase ='ou =组,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'


解决方案

这里提到了这个问题: Grails - Spring安全插件ldap:记住我不工作



我通过注册自定义 TokenBasedRememberMeServices bean中 resources.groovy
我没有在 grails-spring-security-ldap 插件中使用持久性登录功能,因为我发现它与我的Active Directory树布局不兼容。很可能,这可以通过扩展 LdapUserDetailsManager 来定制,但在我的情况下,我发现它不需要在数据库中存储令牌。



我用常规春季安全记住我的cookie选项,但不在cookie中存储用户密码。我从 TokenBasedRememberMeServices




  • makeTokenSignature - 使用密码字段创建令牌签名

  • processAutoLoginCookie - 如果cookie存在,则从cookie令牌中检索用户名,获取ldap用户的详细信息(我必须编写自己的方法 retrieveUserFromLdap()稍后解释)
  • onLoginSuccess - 当用户使用记住我选项进行登录时,会触发此选项。在这里,我将删除密码并将令牌签名保存到cookie中。



要从LDAP获取用户详细信息和角色,但是我的方法看起来像这样:

$ p $ 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)
}


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'

解决方案

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)
}

这篇关于ldap.rememberMe.usernameMapper.userDnBase(?的多个实例)(searchSubtree搜索功能)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆