2016-04-18 7 views
1

Я разрабатываю приложение, используя Spring. В разделе Access Control Access я хочу использовать Spring Security Acl (я новичок в Acl). Я хочу осуществить ACL в моем приложении базы на 2 пункта:Как реализовать пользовательские весы безопасности acl?

  1. Применения должны пяти разрешений, read, create, modify, delete и Administrator.
  2. право быть иерархией, когда пользователь имеет create разрешения, он должен быть в состоянии read, или когда он имеет modify разрешения, он должен быть в состоянии read, create и modify и т.д.

ли возможное? Как?

обновление:
Мое приложение является базой на Spring MVC успокоительных. Когда пользователь хочет изменить собственную информацию, он отправляет некоторые данные json с Ajax. Примером данных json является следующее:

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

Теперь злоумышленник может зайти на сайт в свою учетную запись. Этот пользователь может modify его данные, как и все остальные пользователи. Прежде чем отправить данные, измените его идентификатор, а modify - другую информацию о пользователе. Я хочу использовать ACL для предотвращения этой подрывной работы. И пользователь может получить доступ к другому, чтобы другие могли модифицировать свою информацию.

+0

Вам не нужно создавать что-либо отдельное. Управление ролями обеспечивается Spring-security. Вы можете просто создавать роли 'ROLE_READ, ROLE_CREATE' и т. Д., А затем использовать аннотации' @Secured («условие») 'или' @PreAuthorize («condition») '. Кроме того, что вы уже пробовали? –

+0

Я хочу защитить методы вместе с ** объектами ** –

+0

Что вы подразумеваете под защищенными объектами? Методы вызова getters для объектов ... если метод не разрешен, то объекты в свою очередь также не допускаются. Кроме того, я спросил, что вы уже пробовали? –

ответ

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(#profile, 'update')") 
public void updateUserProfileInASecureWay(UserProfile profile) { 
    //code to update user profile 
} 

«hasPermission» внутри @PreAuthorize аннотации получает targetDomainObject #profile из параметров метода updateUserProfileInASecureWay, а также мы передаем требуемое разрешение (в данном случае «обновление»).

Это решение устраняет всю сложность ACL, реализуя «маленький» ACL. Возможно, это может сработать для вас.

0

Вы можете использовать комбинацию иерархии ролей, которая используется в следующих примерах. У сервера acl есть базовые разрешения. Если вы хотите реализовать пользовательские разрешения, вам нужно создать собственный класс разрешений, расширяющий класс базовых разрешений в api. мы можем определить роли для каждого вида разрешений и определить иерархию роли, как показано ниже.

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