Перейти к основному содержимому

Предоставленные полномочия в сравнении с ролью в Spring Security

· 4 мин. чтения

1. Обзор

В этой быстрой статье мы объясним тонкую, но существенную разницу между ролью и GrantedAuthority в Spring Security `` . Подробнее о ролях и полномочиях читайте в статье здесь .

2. Предоставленные полномочия

В Spring Security мы можем думать о каждом GrantedAuthority как об отдельной привилегии . Примеры могут включать READ_AUTHORITY , WRITE_PRIVILEGE или даже CAN_EXECUTE_AS_ROOT . Важно понимать, что имя является произвольным .

При непосредственном использовании GrantedAuthority , например, с помощью выражения hasAuthority('READ_AUTHORITY'), мы ограничиваем доступ на более тонкой основе .

Как вы, вероятно, уже догадались, мы можем ссылаться на понятие авторитета , используя и привилегию .

3. Роль авторитета

Точно так же в Spring Security мы можем думать о каждой роли как о крупнозернистом GrantedAuthority , который представлен в виде строки с префиксом « ROLE » . При непосредственном использовании Роли , например, с помощью выражения типа hasRole("ADMIN") , мы ограничиваем доступ в грубой манере.

Стоит отметить, что префикс « ROLE» по умолчанию настраивается, но объяснение того, как это сделать, выходит за рамки этой статьи.

Основное различие между ними заключается в семантике, которую мы придаем тому, как мы используем эту функцию. Для фреймворка разница минимальна — и он в основном работает с ними точно так же.

4. Роль контейнера

Теперь, когда мы увидели, как фреймворк использует концепцию ролей , давайте также быстро обсудим альтернативу — использование ролей в качестве контейнеров полномочий/привилегий .

Это подход более высокого уровня к ролям, делающий их концепцией, более ориентированной на бизнес, а не на реализацию.

Платформа Spring Security не дает никаких рекомендаций относительно того, как мы должны использовать эту концепцию, поэтому выбор полностью зависит от реализации.

5. Конфигурация безопасности Spring

Мы можем продемонстрировать тонкое требование авторизации, ограничив доступ к /protectedbyauthority для пользователей с READ_AUTHORITY .

Мы можем продемонстрировать грубое требование авторизации, ограничив доступ к /protectedbyrole пользователям с ROLE_USER .

Настроим такой сценарий в нашей конфигурации безопасности:

@Override
protected void configure(HttpSecurity http) throws Exception {
// ...
.antMatchers("/protectedbyrole").hasRole("USER")
.antMatchers("/protectedbyauthority").hasAuthority("READ_PRIVILEGE")
// ...
}

6. Простая инициализация данных

Теперь, когда мы лучше понимаем основные концепции, давайте поговорим о создании некоторых данных настройки при запуске приложения.

Это, конечно, очень простой способ сделать это, чтобы взяться за дело с некоторыми предварительными тестовыми пользователями во время разработки — не так, как вы должны обрабатывать данные в производстве.

Мы собираемся прослушивать событие обновления контекста:

@Override
@Transactional
public void onApplicationEvent(ContextRefreshedEvent event) {
MyPrivilege readPrivilege
= createPrivilegeIfNotFound("READ_PRIVILEGE");
MyPrivilege writePrivilege
= createPrivilegeIfNotFound("WRITE_PRIVILEGE");
}

Фактическая реализация здесь не имеет особого значения — и, как правило, зависит от используемого вами решения для сохранения. Суть в том, что мы сохраняем полномочия, которые используем в коде.

7. Служба сведений о пользователе

В нашей реализации UserDetailsService происходит сопоставление полномочий . Как только пользователь прошел аутентификацию, наш метод getAuthorities() заполняет данные и возвращает объект UserDetails :

private Collection<? extends GrantedAuthority> getAuthorities(
Collection<Role> roles) {
List<GrantedAuthority> authorities
= new ArrayList<>();
for (Role role: roles) {
authorities.add(new SimpleGrantedAuthority(role.getName()));
role.getPrivileges().stream()
.map(p -> new SimpleGrantedAuthority(p.getName()))
.forEach(authorities::add);
}

return authorities;
}

8. Запуск и тестирование примера

Мы можем выполнить пример Java-приложения RolesAuthoritiesApplication , найденный в проекте GitHub .

Чтобы увидеть авторизацию на основе ролей в действии, нам необходимо:

  • Доступ http://localhost:8082/protectedbyrole
  • Авторизуйтесь как user@test.com (пароль «user» )
  • Обратите внимание на успешную авторизацию
  • Доступ http://localhost:8082/protectedbyauthority
  • Обратите внимание на неудачную авторизацию

Чтобы увидеть авторизацию на основе полномочий в действии, нам нужно выйти из приложения, а затем:

  • Доступ http://localhost:8082/protectedbyauthority
  • Авторизуйтесь как admin@test.com/admin
  • Обратите внимание на успешную авторизацию
  • Доступ http://localhsot:8082/protectedbyrole
  • Обратите внимание на неудачную авторизацию

9. Заключение

В этом кратком руководстве мы рассмотрели тонкую, но существенную разницу между ролью и GrantedAuthority в Spring Security. ``