Spring -security как ACL предоставляет разрешения

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

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

Спасибо!

Ответ 1

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

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

  • Вам необходимо расширить 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();
        }
    }
    
  • Теперь, когда у вас есть правило безопасности, вам необходимо применить его через аннотации:

    @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
    }
    
  • Чтобы это работать, аннотации безопасности должны быть включены в 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>