2013-08-21 82 views
0

這裏的建議將深受讚賞。Grails中的Spring Security提供授權

我們使用Spring Security域對象安全性來鎖定對Grails應用程序中特定對象的訪問。我們也擴展了權限。我們使用普通的@PreAuthorize註釋來控制對域對象的訪問,這取決於分配給特定用戶的權限。

在這個架構中,我想讓一個用戶能夠邀請第二個用戶加入一個組。爲此,第二個用戶收到第一個用戶加入具有特定權限的組的邀請。第二個用戶可以選擇接受或拒絕邀請。

鑑於域對象屬於第一個用戶,而不是第二個用戶,我怎麼能夠授予第二個用戶對域對象的訪問權限?

我試圖在服務方法上使用@PreAuthorize(「permitAll」)來破解一個解決方案,以查看是否可行。雖然沒有要求安全作爲授予對象特權給域對象設置權限,但它至少會讓我去。但沒有喜悅,我繼續得到「accessDenied for class」錯誤,大概是因爲當前用戶是第二個用戶,而不是域對象所有者。

我需要通過SpEL建議here嗎?我很不明白bean解析器是如何工作的。

編輯:即使當我驗證邀請在調用時有效Spring ACL在嘗試插入新用戶的第一個ACE時會引發異常。

空隙setPermissions(ObjectIdentity進行OID,收件人,收集權限){ 西特SID = createSid(受體)

MutableAcl acl 
try { 
    acl = aclService.readAclById(oid) 
} 
catch (NotFoundException e) { 
    acl = aclService.createAcl(oid) 
} 

int deleted = 0 
acl.entries.eachWithIndex { AccessControlEntry ace, int i -> 
    if (ace.sid == sid) { 
     acl.deleteAce(i-deleted) 
     deleted++ 
    } 
} 

permissions.each { 
    acl.insertAce(acl.entries.size(), it, sid, true) 
} 

aclService.updateAcl acl 
:在所述insertAce呼叫空隙setPermissions(ObjectIdentity進行OID,收件人,收集權限)時發生的異常

}

我認爲訪問被拒絕,因爲當前用戶(在發出邀請時誰不存在)沒有權限設置其他用戶擁有的對象的權限。

+0

所以@PreAuthorize並沒有真正授權一路下跌到ACL的。要訪問受ACL保護的域對象,需要當前用戶具有訪問權限。所以要麼我徹底破解了ACE插入,要麼我在這個特例中弄清楚瞭如何授予權限。 –

+0

那麼我可以使用RunAs身份驗證替換嗎?看起來它會做這項工作。 http://static.springsource.org/spring-security/site/docs/3.0.x/reference/runas.html –

+0

嗯,它應該工作,但它沒有。我在db中創建了一個新角色RUN_AS_INVITED_USER,使用grails.plugins.springsecurity.useRunAs = true啓用RUnAss,設置grails.plugins.springsecurity.acl.authority.changeAclDetails ='ROLE_RUN_AS_INVITED_USER'然後用@Secured註釋該方法(['ROLE_USER ','RUN_AS_INVITED_USER']),但仍然沒有喜悅。更糟糕的是,當我用springSecurityService.getPrincipal()。getAuthorities()查詢方法中的當前角色時,我看不到我的新角色集。 –

回答

0

答案原來是使用RunAs。對於Grails,我做了如下:

  1. 創建一個特定的角色,允許被邀請的用戶充當管理員以訪問受保護的對象。在引導,確保這個角色被加載到SecRole域:

    高清invitedRole = SecRole.findByAuthority( 'ROLE_RUN_AS_INVITED_USER') 如果{ invitedRole =新SecRole() invitedRole(invitedRole!)。權威= 「ROLE_RUN_AS_INVITED_USER」 invitedRole.save(failOnError:真,沖洗:真) }

  2. 確保Config.groovy中,所述角色可以改變目標object:grails.plugins.springsecurity.acl.authority.changeAclDetails = 'ROLE_RUN_AS_INVITED_USER'

  3. Config.groovy中

    啓用運行方式

    grails.plugins.springsecurity.useRunAs =真 grails.plugins.springsecurity.runAs.key = [鍵]

  4. 註釋的服務方法

@PreAuthorize([檢查,這確實是一個被邀請的用戶]) @Secured([ 'ROLE_USER', 'RUN_AS_INVITED_USER'])

,它所有的作品。訣竅是使ROLE_RUN_AS_INVITED_USER能夠更改acl。

參考: http://static.springsource.org/spring-security/site/docs/3.0.x/reference/runas.html http://grails-plugins.github.io/grails-spring-security-acl/docs/manual/guide/2.%20Usage.html#2.5%20Run-As%20Authentication%20Replacement

0

您不僅可以將Role類用於通用角色(AdminUser等),還可以將其用於特定應用程序。只需允許用戶爲資源創建Role,然後允許其被邀請者被授予該角色。 Spring Security帶有一個方便的ifAnyGranted()方法,該方法接受逗號分隔的角色名稱字符串。在資源入口處,只需確保授予特定角色即可:

class Conversation{ 
    Role role 
} 
class ConversationController{ 
    def enterConversation(){ 
     // obtain conversation instance 
     if(!SpringSecurityUtils.ifAnyGranted(conversationInstance.role.authority){response.sendError(401)} 
    } 
} 
+0

謝謝,但我不確定這是否符合我的需求。雖然我可以檢查以確保在資源入口點處有一個對象(邀請,因爲用戶可能尚未在服務上註冊),但我發現在設置ACL權限時我仍然遇到異常。 –

+0

由於接受邀請是未來可能發生或可能不會發生的事件,因此需要在驗證週期外正確處理完整的單獨用例場景。您可以查看電子郵件確認插件以瞭解「確認」部分的示例實現,其中包括計劃域類,處理超時的石英作業以及使用事件偵聽器API來響應各種場景結果。無論哪種情況,在授予角色權限之前,您都一定要註冊用戶。希望有所幫助。 – Anatoly

+0

問題是我沒有授予新用戶一個角色,我正在授予新的用戶對域對象的訪問權限。 –