2013-12-11 28 views
0

在我的應用程序中,用戶可以使用僅鏈接到它們的事物進行操作。所有用戶在彈簧安全中具有相同的角色。所以,爲了禁止用戶查看他的東西,我需要在某些控制器方法中實現我自己的函數來驗證用戶權限。在Spring安全中具有相同角色的用戶之間確保控制器的安全

public void securityValidation(User currentUser, Thing thing) { 
     if(!thing.has(currentUser)) { 
      log.warn("Security Control. User: " + user .getId());    
     } 
    } 

我覺得這不酷。在代碼中很難找到保證或不保證的方法。 可能春天有更優雅的方式來完成這項任務嗎?

或者我可以寫我自己的註釋來確保方法?我需要註釋處理器嗎?例如,您可以將任何控制器方法設置爲超出任何限制爲管理員的控制器方法,例如:

回答

1

您指的是域對象安全性,它不是基本安全包的一部分。 Spring Security ACL是你所需要的,有了它,你可以斷言實際物品的所有權,例如用戶123可以編輯項目789下面的代碼可以確保當前用戶對實體管理權限,他正在編輯:

@PreAuthorize("hasPermission(#entity, 'ADMINISTRATION')") 
public SomeEntity update(SomeEntity entity) { 
... 
} 

但請記住,您現在必須管理這些權限並將其提供給個人用戶。還有一種方法可以將它作爲一個組的一部分來完成。您可以說用戶123和345屬於GROUP_SOME_ID,然後如果您通過對象授予GROUP_SOME_ID管理權限,則用戶123和345將自動獲取它們。從組中刪除用戶123也會自動刪除他的權限。

---- ------ UPDATE

下面是一個直徑達Spring Security的ACL示例應用程序上下文:

<?xml version="1.0" encoding="UTF-8"?> 
<beans xmlns="http://www.springframework.org/schema/beans" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns:security="http://www.springframework.org/schema/security" 
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd 
     http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.2.xsd"> 

    <bean id="expressionHandler" class="org.springframework.security.access.expression.method.DefaultMethodSecurityExpressionHandler"> 
     <property name="permissionEvaluator" ref="permissionEvaluator" /> 
    </bean> 

    <!-- We'll rely on the standard AclPermissionEvaluator implementation --> 
    <bean class="org.springframework.security.acls.AclPermissionEvaluator" id="permissionEvaluator"> 
     <constructor-arg ref="aclService" /> 
     <property name="sidRetrievalStrategy" ref="sidRetrievalStrategy" /> 
     <property name="permissionFactory" ref="permissionFactory"/> 
    </bean> 

    <bean class="org.springframework.security.acls.domain.SidRetrievalStrategyImpl" id="sidRetrievalStrategy" > 
     <constructor-arg ref="roleHierarchy" /> 
    </bean> 

    <!-- Declare an acl service --> 
    <bean class="org.springframework.security.acls.jdbc.JdbcMutableAclService" id="aclService"> 
     <constructor-arg ref="dataSource" /> 
     <constructor-arg ref="lookupStrategy" /> 
     <constructor-arg ref="aclCache" /> 
     <property name="classIdentityQuery" value="select currval(pg_get_serial_sequence('acl_class', 'id'))" /> 
     <property name="sidIdentityQuery" value="select currval(pg_get_serial_sequence('acl_sid', 'id'))" /> 
    </bean> 

    <!-- Declare a lookup strategy --> 
    <bean id="lookupStrategy" class="org.springframework.security.acls.jdbc.BasicLookupStrategy"> 
     <constructor-arg ref="dataSource" /> 
     <constructor-arg ref="aclCache" /> 
     <constructor-arg ref="aclAuthorizationStrategy" /> 
     <constructor-arg ref="permissionGrantingStrategy" /> 
     <property name="permissionFactory" ref="permissionFactory"/> 
    </bean> 

    <bean id="permissionFactory" class="org.springframework.security.acls.domain.DefaultPermissionFactory" /> 

    <!-- Declare an acl cache --> 
    <bean id="aclCache" class="org.springframework.security.acls.domain.SpringCacheBasedAclCache"> 
     <constructor-arg> 
      <bean class="com.example.NoOpCache"> 
       <constructor-arg value="aclCache" /> 
      </bean> 
     </constructor-arg> 
     <constructor-arg ref="permissionGrantingStrategy" /> 
     <constructor-arg ref="aclAuthorizationStrategy" /> 
    </bean> 

    <!-- Declare an acl authorization strategy --> 
    <bean id="aclAuthorizationStrategy" class="org.springframework.security.acls.domain.AclAuthorizationStrategyImpl"> 
     <constructor-arg> 
      <list> 
       <bean class="org.springframework.security.core.authority.SimpleGrantedAuthority"> 
        <constructor-arg value="ROLE_ADMIN" /> 
       </bean> 
       <bean class="org.springframework.security.core.authority.SimpleGrantedAuthority"> 
        <constructor-arg value="ROLE_ADMIN" /> 
       </bean> 
       <bean class="org.springframework.security.core.authority.SimpleGrantedAuthority"> 
        <constructor-arg value="ROLE_ADMIN" /> 
       </bean> 
      </list> 
     </constructor-arg> 
    </bean> 

    <bean id="permissionGrantingStrategy" class="org.springframework.security.acls.domain.DefaultPermissionGrantingStrategy" > 
     <constructor-arg> 
      <bean class="org.springframework.security.acls.domain.ConsoleAuditLogger" /> 
     </constructor-arg> 
    </bean> 

    <bean id="roleHierarchy" class="org.springframework.security.access.hierarchicalroles.RoleHierarchyImpl"> 
     <property name="hierarchy"> 
      <value> 
       ROLE_USER > ROLE_ANONYMOUS 
       ROLE_SUPER_USER > ROLE_USER 
       ROLE_ADMIN > ROLE_SUPER_USER 
      </value> 
     </property> 
    </bean> 
</beans> 
+0

,只有在使用java編譯器調試模式進行部署時,或者實現參數名稱發現者(我嘗試過,但從未實際工作)時纔會工作。由於參數名稱的編譯時依賴性。 – NimChimpsky

+0

@NimChimpsky - 聽起來像你的應用程序上下文連線有問題。此代碼在沒有調試模式或自定義參數名稱發現者的生產應用程序中工作得非常好。 – SergeyB

+0

@NimChimpsky這裏沒有調試模式的解決方法http://lifewithcode.blogspot.ru/2012/04/spring-security-preauthorizehaspermissi.html – user1406196

0
@PreAuthorize("hasRole('ROLE_ADMIN')") 

確保您在web上下文中定義methodSecurityExpressionHandler bean。

+0

在我的情況我的用戶有相同的作用。 – user1406196

+0

@ user1406196 - 查看我的答案,這正是你正在尋找的。 – SergeyB