Spring-Security, как ACL предоставляет разрешения - PullRequest
11 голосов
/ 20 сентября 2011

В настоящее время я интегрирую springs-security в наш новый стек веб-приложений.Нам нужно будет предоставить пользователю или роли разрешения на доступ к определенному объекту или ко всем объектам определенного типа.Однако это одна вещь, которую я на самом деле не получил при работе с документацией и примерами:

Предоставляет ли ACL-разрешение только пользователю / роли для одного объекта или это делает для всего типа?Насколько я понимаю, domain object означает тип, но примеры и учебные пособия, похоже, присваивают разрешения конкретным объектам.Я просто запутался или могу сделать и то и другое?Если нет, как я могу сделать другой?

Спасибо!

1 Ответ

25 голосов
/ 20 сентября 2011

С пружинной защитой вы можете сделать и то, и другое. Это возможно, потому что Spring-Security поддерживает так называемые правила разрешений - в терминологии Spring-Security они называют это оценщики разрешений . Правила разрешений охватывают ACL, но вы также можете защищать экземпляры объектов, когда они находятся в определенном состоянии ... и т. Д.

Вот как это работает:

  1. Вам необходимо расширить PermissionEvaluator - это позволяет вам иметь супер настраиваемую логику для определения прав доступа - вы можете проверить тип объекта или проверить для определенного идентификатора, или проверить, является ли пользователь, вызывающий метод, пользователь, который создал объект и т. д.

    public class SomePermissionsEvaluator implements PermissionEvaluator {
        @Override
        public boolean hasPermission(Authentication authentication, Object targetDomainObject, Object permission) {
            if (permission.equals("do_something") && 
            /*authentication authorities has the role A*/) {
                return true
            } else if (permission.equals("do_something_else") && 
            /*authentication authorities has the role B*/) {
                return /*true if targetDomainObject satisfies certain condition*/;
            }
    
            return false;
        }
    
        @Override
        public boolean hasPermission(Authentication authentication,
            Serializable targetId, String targetType, Object permission) {
        throw new UnsupportedOperationException();
        }
    }
    
  2. Теперь, когда у вас есть правило безопасности, вам нужно применить его с помощью аннотаций:

    @PreAuthorize("hasRole('SOME_ROLE_OR_RIGHT') and" +
    " hasPermission(#someDomainObject, 'do_something')")
    public void updateSomeDomainObject(SomeDomainObject someDomainObject) {
        // before updating the object spring-security will check the security rules
    }
    
  3. Чтобы это работало, аннотации безопасности должны быть включены в applicationContext.xml :

    <global-method-security secured-annotations="enabled" pre-post-annotations="enabled">
        <expression-handler ref="expressionHandler"/>
    </global-method-security>
    
    <beans:bean id="expressionHandler" class="org.springframework.security.access.expression.method.DefaultMethodSecurityExpressionHandler">
        <beans:property name="permissionEvaluator">
            <beans:bean id="permissionEvaluator" class="com.npacemo.permissions.SomePermissionsEvaluator"/>
        </beans:property>
    </beans:bean>
    
...