1

我們正在創建一個grails應用程序,我們希望用戶使用他們的Active Directory憑據登錄。此外,我們希望賦予此應用程序的業主擁有控制訪問某些鏈接(操作)的權限的能力。正因爲如此,我們正在使用我們的Grails應用程序的插件如下:如何將LDAP用戶與Spring Security在Grails中創建的PERSON表集成?

  1. Spring Security的核心
  2. Spring Security的LDAP
  3. Spring Security的UI

因爲我們要賦予企業用戶在必要時創建具有特定權限(動作)的定製角色,我們認爲最好的Spring Security配置是基於請求映射數據庫的方法

到目前爲止,我們已經完成如下:

  • 我們能夠對Active Directory身份驗證成功。
  • 我們還能夠通過彈簧安全的UI插件的UI界面來創建不同的角色(ROLE_XXX)不同的請求映射

問題/問題

彈簧安全-core插件創建以下表:

  • PERSON
  • AUTHORITY
  • PERSON_AUTHORITY
  • REQUESTMAP

這些是支持創建角色,網址進行角色分配表。然而,作爲約定名稱的Person_Authoritity表意味着它是PERSON和AUTHORITY(ROLE)之間的多對多關係,因爲一個人可能具有多個角色。我的問題是我沒有Person,因爲這個人已經存在於Active Directory(外部源)中,並且它沒有在應用程序中創建。

有沒有辦法讓認證用戶成爲PERSON?彈簧安全解決方案要求使用Person行或對象,但是您更願意引用它。

我也張貼了問題在這裏:

http://grails.1312388.n4.nabble.com/Issues-integrating-LDAP-Authentication-with-Requestmap-to-Secure-URLs-td4644040.html

感謝,

+1

下面是我們做了什麼。我們遇到過類似的情況,用戶使用LDAP進行身份驗證,結果我們最終做的是,一旦一個人通過LDAP進行身份驗證,我們就會在Persons表中找到他,如果他不存在,我們會用一些基本信息創建他,然後將該對象添加到RequestMap。如果該人員已經存在於Persons表中,那麼我們不會添加他,但是關鍵部分是在兩種情況下用戶仍在使用LDAP進行身份驗證。 – allthenutsandbolts 2013-04-29 21:29:31

+0

@allthenutsandbolts嘗試它沒有成功。密碼字段是必填字段,如何將j_password字段傳遞給創建用戶的用戶/保存操作?將登錄信息發佈到j_security_check時,我無法再訪問憑證來插入人員記錄。我嘗試通過Spring-security-ui手動在人員表中創建一個用戶,同時仍然通過LDAP進行身份驗證,但是當我去到一個安全的URL時,它不起作用,好像人員表中的用戶與LDAP中的用戶,或者某些內容未被註冊或初始化。 – Viriato 2013-05-01 13:21:40

+0

您可以將該密碼設置爲任何你想要的。您將不會將其用於身份驗證。你是對的,你沒有權限訪問j_password字段。 – allthenutsandbolts 2013-05-01 14:12:23

回答

6

所以,你需要基本映射AD用戶到某個人。

以下是您在src/groovy中需要的3個類。顯然根據需要修改它們:

package yourpackagename 

    import org.codehaus.groovy.grails.plugins.springsecurity.GrailsUser 
    import org.springframework.security.core.GrantedAuthority 

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

package yourpackagenamehere 

import org.codehaus.groovy.grails.plugins.springsecurity.GrailsUserDetailsService 
import org.springframework.security.core.authority.GrantedAuthorityImpl 
import org.springframework.security.core.userdetails.UserDetails 
import org.springframework.security.core.userdetails.UsernameNotFoundException 
import org.codehaus.groovy.grails.plugins.springsecurity.SpringSecurityUtils 

class CustomUserDetailsService implements GrailsUserDetailsService { 

    /** 
    * Some Spring Security classes (e.g. RoleHierarchyVoter) expect at least one role, so 
    * we give a user with no granted roles this one which gets past that restriction but 
    * doesn't grant anything. 
    */ 
    static final List NO_ROLES = [new GrantedAuthorityImpl(SpringSecurityUtils.NO_ROLE)] 

    UserDetails loadUserByUsername(String username, boolean loadRoles) 
    throws UsernameNotFoundException { 
     return loadUserByUsername(username) 
    } 

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

package yourpackagenamehere 

import groovy.sql.Sql 

import org.springframework.ldap.core.DirContextAdapter 
import org.springframework.ldap.core.DirContextOperations 
import org.springframework.security.core.userdetails.UserDetails 
import org.springframework.security.ldap.userdetails.UserDetailsContextMapper 
import org.springframework.security.core.authority.GrantedAuthorityImpl 
import org.springframework.security.core.GrantedAuthority 
import org.codehaus.groovy.grails.plugins.springsecurity.SpringSecurityUtils 

import org.springframework.security.core.userdetails.UsernameNotFoundException 
import org.springframework.security.authentication.DisabledException 

class CustomUserDetailsContextMapper implements UserDetailsContextMapper { 

    private static final List NO_ROLES = [new GrantedAuthorityImpl(SpringSecurityUtils.NO_ROLE)] 

    def dataSource 

    @Override 
    public CustomUserDetails mapUserFromContext(DirContextOperations ctx, String username, Collection<GrantedAuthority> authority) { 

     username = username.toLowerCase() 

     User user = User.findByUsername(username) 

     String firstName = ctx.originalAttrs.attrs['givenname'].values[0] 
     String lastName = ctx.originalAttrs.attrs['sn'].values[0] 


     def roles 

     User.withTransaction { 

      if(!user){ 
       user = new User(username: username, enabled: true, firstName: firstName, lastName: lastName) 
       user.save(flush: true) 
      } 
      else { 
       user = User.findByUsername(username) 
       user.firstName = firstName 
       user.lastName = lastName 
       user.save(flush: true) 
      } 

      roles = user.getAuthorities() 
     } 

     if (!user.enabled) 
      throw new DisabledException("User is disabled", username) 


     def authorities = roles.collect { new GrantedAuthorityImpl(it.authority) } 
     authorities.addAll(authority) 
     def userDetails = new CustomUserDetails(username, user.password, user.enabled, false, false, false, authorities, user.id, user.firstName, user.lastName) 

     return userDetails 
    } 

    @Override 
    public void mapUserToContext(UserDetails arg0, DirContextAdapter arg1) { 
    } 
} 

在spring/resources中的配置下。常規:

import yourpackagenamehere.CustomUserDetailsService 
import yourpackagenamehere.CustomUserDetailsContextMapper 
beans = { 
    userDetailsService(CustomUserDetailsService) 

    ldapUserDetailsMapper(CustomUserDetailsContextMapper) { 
     dataSource = ref("dataSource") 
    } 
} 

在Config.groovy中,這裏是我的設置:

grails.plugins.springsecurity.ldap.context.managerDn = 'CN=username,OU=People,DC=foo,DC=com' 
grails.plugins.springsecurity.ldap.context.managerPassword = 'password' 
grails.plugins.springsecurity.ldap.context.server = 'ldap://foo.com:389/' 
grails.plugins.springsecurity.ldap.authorities.ignorePartialResultException = true 
grails.plugins.springsecurity.ldap.search.base = 'ou=People,dc=foo,dc=com' 
grails.plugins.springsecurity.ldap.search.filter="sAMAccountName={0}" 
grails.plugins.springsecurity.ldap.search.searchSubtree = true 
grails.plugins.springsecurity.ldap.auth.hideUserNotFoundExceptions = false 
grails.plugins.springsecurity.ldap.search.attributesToReturn = null 
grails.plugins.springsecurity.providerNames = ['ldapAuthProvider', 'anonymousAuthenticationProvider'] 
grails.plugins.springsecurity.ldap.mapper.userDetailsClass = 'CustomUserDetails' 

grails.plugins.springsecurity.ldap.authorities.retrieveGroupRoles = true 
grails.plugins.springsecurity.ldap.authorities.retrieveDatabaseRoles = true 
grails.plugins.springsecurity.ldap.authorities.groupSearchBase ='dc=foo,dc=com' 
grails.plugins.springsecurity.ldap.authorities.groupSearchFilter = 'member={0}' 
+0

感謝您的回覆。我會盡力讓你的建議工作,並讓你知道。 – Viriato 2013-05-01 13:23:40

+0

非常感謝你的工作!在閱讀文檔http://grails-plugins.github.io/grails-spring-security-ldap/docs/manual/guide/2.%20Usage.html之後,對我來說重寫這兩個類將會做招。我還必須使密碼可以爲空:true和blank:在域類上爲true,並確保它在數據庫端是可以爲空的'Y'。我在運行應用程序時遇到DirContextOperations對象始終爲空的問題。不知道它是什麼,但我現在可以忍受它。 – Viriato 2013-05-02 21:18:22

+0

你知道嗎,我以前有過這個錯誤!它在AIX上運行時失敗,但在Windows上工作。這兩臺機器位於不同的子網上,我將它歸類爲網絡事物。請讓我知道,如果你弄清楚了!!!!!!!! – 2013-05-03 12:39:00

相關問題