2016-04-18 6 views
1

私はSpringを使ってアプリケーションを開発しています。 Access Control Accessセクションで、Spring Security Aclを使用したい(私はAclで新しくなった)。私は2点について、私のアプリケーションベースでACLを実装する:カスタムスプリングセキュリティaclを実装する方法は?

  1. アプリケーションは、5つの権限、readcreatemodifydeleteAdministratorを持っている必要があります。
  2. 権限ユーザーがcreate権限を持っているとき、それはreadのことができるようにする必要があり、階層、またはそれはmodify権限を持っているとき、それはreadcreatemodifyにできるはずですし、など

がそれです可能?どうやって?

更新
私のアプリケーションはSpring MVCの安らかに拠点です。ユーザーが独自の情報を変更したい場合、Ajaxを使用してjsonデータを送信します。 jsonデータの例は次のとおりです。

{ 
    "id": 1,//user Id 
    "name": "my name", 
    "password": "my password", 
    "email": "[email protected]", 
    ... 
} 

悪意のあるユーザーが自分のアカウントにログインできるようになりました。このユーザーはmodifyのデータを他のすべてのユーザーと同様に扱うことができます。彼がデータを送信する前に、自分のIDを変更し、別のアカウントのユーザー情報modifyを変更してください。私はこの破壊的な仕事を防ぐためにACLを使いたい。そして、ユーザーは、他の人が自分の情報を変更できるように、いくつかのアクセス権を得ることができます。

+0

別に何かを作成する必要はありません。ロール管理はSpringセキュリティによって提供されます。ロール 'ROLE_READ、ROLE_CREATE'などを簡単に作成し、' @Secured( "condition") 'または' @PreAuthorize( "condition") 'というアノテーションを使用することができます。また、何を試してみましたか? –

+0

**オブジェクトと一緒にメソッドを保護したい** –

+0

安全なオブジェクトとはどういう意味ですか?メソッドはオブジェクトのgetterを呼び出します。メソッドが許可されていない場合は、オブジェクトも順番に許可されません。また、何を試してみたのですか? –

答えて

3

春のセキュリティで簡単なソリューションを実装できます。 org.springframework.security.access.PermissionEvaluatorを実装するクラスを作成し、メソッドhasPermissionをオーバーライドすることです。今

@Component("permissionEvaluator") 
public class PermissionEvaluator implements org.springframework.security.access.PermissionEvaluator { 

    /** 
    * @param authentication  represents the user in question. Should not be null. 
    * @param targetDomainObject the domain object for which permissions should be 
    *       checked. May be null in which case implementations should return false, as the null 
    *       condition can be checked explicitly in the expression. 
    * @param permission   a representation of the permission object as supplied by the 
    *       expression system. Not null. 
    * @return true if the permission is granted, false otherwise 
    */ 
    @Override 
    public boolean hasPermission(Authentication authentication, Object targetDomainObject, Object permission) { 
     if (authentication != null && permission instanceof String) { 
      User loggedUser = (User) authentication.getPrincipal(); 
      String permissionToCheck = (String) permission; 
      // in this part of the code you need to check if the loggedUser has the "permission" over the 
      // targetDomainObject. In this implementation the "permission" is a string, for example "read", or "update" 
      // The targetDomainObject is an actual object, for example a object of UserProfile class (a class that 
      // has the profile information for a User) 

      // You can implement the permission to check over the targetDomainObject in the way that suits you best 
      // A naive approach: 
      if (targetDomainObject.getClass().getSimpleName().compareTo("UserProfile") == 0) { 
       if ((UserProfile) targetDomainObject.getId() == loggedUser.getId()) 
        return true; 
      } 
      // A more robust approach: you can have a table in your database holding permissions to each user over 
      // certain targetDomainObjects 
      List<Permission> userPermissions = permissionRepository.findByUserAndObject(loggedUser, 
       targetDomainObject.getClass().getSimpleName()); 
      // now check if in userPermissions list we have the "permission" permission. 

      // ETC... 
     } 
     //access denied 
     return false; 
    } 

} 

、この実装で、あなたのサービス層は、例えば、このような@PreAuthorize注釈で使用することができます:次の例を見て@PreAuthorize注釈内の「hasPermissionも」受信

@PreAuthorize("hasPermission(#profile, 'update')") 
public void updateUserProfileInASecureWay(UserProfile profile) { 
    //code to update user profile 
} 

をupdateUserProfileInASecureWayメソッドのパラメータからtargetDomainObject #profileを取得し、必要な権限(この場合は 'update')も渡します。

このソリューションは、「小さな」ACLを実装することによってACLのすべての複雑さを回避します。多分それはあなたのために働くことができます。

0

次の例で使用されているように、ロール階層の組み合わせを使用できます.Spring aclには基本アクセス権があります。カスタムアクセス権を実装する場合は、APIにBase Permissionsクラスを拡張するカスタムPermissionクラスを作成する必要があります。権限の種類ごとにロールを定義し、ロールの階層を以下のように定義することができます。

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

<!-- A customized PermissionEvaluator that evaluates permissions via the ACL module --> 
<bean class="org.springframework.security.acls.AclPermissionEvaluator" id="permissionEvaluator"> 
    <!-- Reference to the ACL service which performs JDBC calls to an ACL database --> 
    <constructor-arg ref="aclService"/> 
    <property name="permissionFactory" ref="customPermissionFactory" /> 
</bean> 
<bean id="customPermissionFactory" class="org.krams.tutorial.security.CustomPermissionFactory"></bean> 

<!-- A customized ACL service which provides default JDBC implementation --> 
<bean class="org.springframework.security.acls.jdbc.JdbcMutableAclService" id="aclService"> 
    <constructor-arg ref="dataSource"/> 
    <constructor-arg ref="lookupStrategy"/> 
    <constructor-arg ref="aclCache"/> 
</bean> 

<!-- A lookup strategy for optimizing database queries --> 
<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="auditLogger"/> 
    <property name="permissionFactory" ref="customPermissionFactory"/> 
</bean> 

<!-- A MySQL datasource with pooling capabalities for the ACL module --> 
<!-- <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" 
    destroy-method="close" 
    p:driverClass="com.mysql.jdbc.Driver" 
    p:jdbcUrl="jdbc:mysql://localhost/acl" 
    p:user="root" 
    p:password="" 
    p:acquireIncrement="5" 
    p:idleConnectionTestPeriod="60" 
    p:maxPoolSize="100" 
    p:maxStatements="50" 
    p:minPoolSize="10" /> --> 




<bean id="dataSource" 
    class="org.springframework.jdbc.datasource.DriverManagerDataSource"> 
    <property name="driverClassName" value="org.h2.Driver" /> 
    <property name="url" value="jdbc:h2:tcp://localhost/~/springsecurity" /> 

    <!--<property name="url" value="jdbc:h2:tcp://ggk-wrl-win1/~/dev" /> --> 
    <property name="username" value="sa" /> 
    <property name="password" value="" /> 
</bean> 

<!-- An ACL cache to minimize calls to the ACL database --> 
<bean id="aclCache" class="org.springframework.security.acls.domain.EhCacheBasedAclCache"> 
    <constructor-arg> 
     <bean class="org.springframework.cache.ehcache.EhCacheFactoryBean"> 
      <property name="cacheManager"> 
       <bean class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean"/> 
      </property> 
      <property name="cacheName" value="aclCache"/> 
     </bean> 
    </constructor-arg> 
</bean> 

<!-- An ACL authorization strategy to determine whether a principal is permitted to call administrative methods --> 
<bean id="aclAuthorizationStrategy" class="org.springframework.security.acls.domain.AclAuthorizationStrategyImpl"> 
    <constructor-arg> 
     <list> 
      <bean class="org.springframework.security.core.authority.GrantedAuthorityImpl"> 
       <constructor-arg value="ROLE_USER"/> 
      </bean> 
      <bean class="org.springframework.security.core.authority.GrantedAuthorityImpl"> 
       <constructor-arg value="ROLE_USER"/> 
      </bean> 
      <bean class="org.springframework.security.core.authority.GrantedAuthorityImpl"> 
       <constructor-arg value="ROLE_USER"/> 
      </bean> 
     </list> 
    </constructor-arg> 
</bean> 

<!-- An audit logger used to log audit events --> 
<bean id="auditLogger" class="org.springframework.security.acls.domain.ConsoleAuditLogger"/> 

<!-- Defines the role order --> 
<!-- http://static.springsource.org/spring-security/site/docs/3.0.x/apidocs/org/springframework/security/access/hierarchicalroles/RoleHierarchyImpl.html --> 
<bean id="roleHierarchy" class="org.springframework.security.access.hierarchicalroles.RoleHierarchyImpl"> 
    <property name="hierarchy"> 
     <value> 
      ROLE_ADMIN > ROLE_USER 
      ROLE_USER > ROLE_VISITOR 
     </value> 
    </property> 
</bean> 
関連する問題