Думайте о предоставленном полномочии как о «разрешении» или «праве». Эти «разрешения» (обычно) выражаются в виде строк (с помощью getAuthority()
метода). Эти строки позволяют вам определить разрешения и позволить вашим избирателям решать, предоставляют ли они доступ к чему-либо.
Вы можете предоставлять различные GrantedAuthoritys (разрешения) пользователям, помещая их в контекст безопасности. Обычно вы делаете это, реализуя свой собственный UserDetailsService, который возвращает реализацию UserDetails, которая возвращает необходимые GrantedAuthorities.
Роли (как они используются во многих примерах) - это просто «разрешения» с соглашением об именах, которое говорит, что роль - это GrantedAuthority, который начинается с префикса ROLE_
. Там больше ничего нет. Роль - это просто предоставленное право - «разрешение» - «право». Вы видите много мест в весенней безопасности, где роль с ROLE_
префиксом обрабатывается специально, например, в RoleVoter, где ROLE_
префикс используется по умолчанию. Это позволяет вам предоставлять имена ролей без ROLE_
префикса. До версии Spring security 4 эта особая обработка «ролей» не выполнялась очень последовательно, и полномочия и роли часто рассматривались одинаково (как выhasAuthority()
hasRole()
). В Spring Security 4 обработка ролей более последовательна, и код, который имеет дело с «ролями» (например RoleVoter
, hasRole
выражением и т. Д.), Всегда добавляет ROLE_
префикс для вас. Значит так hasAuthority('ROLE_ADMIN')
же, как и hasRole('ADMIN')
потому, что ROLE_
префикс добавляется автоматически. Дополнительную информацию см. В руководстве по миграции с 3 по 4 весенней безопасности .
Но все же: роль - это просто авторитет со специальным ROLE_
префиксом. Так что в Spring безопасность 3 @PreAuthorize("hasRole('ROLE_XYZ')")
такая же, как @PreAuthorize("hasAuthority('ROLE_XYZ')")
и в Spring безопасность 4 @PreAuthorize("hasRole('XYZ')")
такая же, как @PreAuthorize("hasAuthority('ROLE_XYZ')")
.
Относительно вашего варианта использования:
Пользователи имеют роли, а роли могут выполнять определенные операции.
Вы можете получить GrantedAuthorities
роли, к которым принадлежит пользователь, и операции, которые может выполнять эта роль. Для GrantedAuthorities
ролей есть префикс, ROLE_
а для операций - префикс OP_
. Примером операции власти может быть OP_DELETE_ACCOUNT
, OP_CREATE_USER
, и OP_RUN_BATCH_JOB
т.д. Роли могут быть ROLE_ADMIN
, ROLE_USER
, и ROLE_OWNER
т.д.
Вы можете в конечном итоге реализовать свои сущности, GrantedAuthority
как в этом (псевдокоде) примере:
@Entity
class Role implements GrantedAuthority {
@Id
private String id;
@ManyToMany
private final List<Operation> allowedOperations = new ArrayList<>();
@Override
public String getAuthority() {
return id;
}
public Collection<GrantedAuthority> getAllowedOperations() {
return allowedOperations;
}
}
@Entity
class User {
@Id
private String id;
@ManyToMany
private final List<Role> roles = new ArrayList<>();
public Collection<Role> getRoles() {
return roles;
}
}
@Entity
class Operation implements GrantedAuthority {
@Id
private String id;
@Override
public String getAuthority() {
return id;
}
}
Идентификатором ролей и операций, которые вы создаете в своей базе данных, будет представление GrantedAuthority, например ROLE_ADMIN
, OP_DELETE_ACCOUNT
и т. Д. Когда пользователь проходит аутентификацию, убедитесь, что все GrantedAuthorities всех его ролей и соответствующих операций возвращены из UserDetails.getAuthorities () метод.
Пример: админ роль с идентификатором ROLE_ADMIN
имеет операции OP_DELETE_ACCOUNT
, OP_READ_ACCOUNT
, OP_RUN_BATCH_JOB
возложенные на него. Роль пользователя с идентификатором ROLE_USER
имеет операцию OP_READ_ACCOUNT
.
Если админ журналы в результирующем контексте безопасности будет иметь GrantedAuthorities:
ROLE_ADMIN
, OP_DELETE_ACCOUNT
, OP_READ_ACCOUNT
,OP_RUN_BATCH_JOB
Если пользователь входит в систему , он будет иметь:
ROLE_USER
,OP_READ_ACCOUNT
UserDetailsService позаботится о том, чтобы собрать все роли и все операции этих ролей и сделать их доступными методом getAuthorities () в возвращенном экземпляре UserDetails.
hasRole('xyz')
в Spring Security 4 ожидается, что у вас будет префикс ROLE_, тогда как префиксhasAuthority('xyz')
не ожидает и точно вычисляет, что передается. Я использовал это решение, но столкнулся с проблемами,hasRole('OP_MY_PERMISSION')
поскольку ROLE_ был нужен префикс. Вместо этого я должен был использовать,hasAuthority('OP_MY_PERMISSION')
так как у меня не было префикса.<sec:authorize access="hasRole('ADMIN')">
же, как<sec:authorize access="hasRole('ROLE_ADMIN')">
AFAIK Предоставлено. Авторитет и роли одинаковы в весенней безопасности. Строка getAuthority () GrantedAuthority является ролью (согласно реализации по умолчанию SimpleGrantedAuthority).
Для вашего случая может быть, вы можете использовать иерархические роли
Не то, что вы ищете, но надеюсь, что это поможет
Изменить : Ответить на ваш комментарий
Роль как разрешение в весенней безопасности. Использование intercept-url с hasRole обеспечивает очень точный контроль того, какая операция разрешена для какой роли / разрешения.
То, как мы работаем в нашем приложении, мы определяем разрешение (т.е. роль) для каждой операции (или URL-адреса отдыха), например, для view_account, delete_account, add_account и т. Д. Затем мы создаем логические профили для каждого пользователя, такие как admin, guest_user, normal_user. Профили - это просто логическая группа разрешений, независимая от Spring-Security. Когда добавляется новый пользователь, ему присваивается профиль (имеющий все разрешенные разрешения). Теперь, когда пользователь пытается выполнить какое-либо действие, разрешение / роль для этого действия сравнивается с пользователем grantAuthorities.
Также в RoleVoter по умолчанию используется префикс ROLE_, поэтому любой авторитет, начинающийся с ROLE_, рассматривается как роль, вы можете изменить это поведение по умолчанию, используя собственный RolePrefix в роли избирателя и используя его в весенней безопасности.
источник
Еще один способ понять взаимосвязь между этими понятиями - это интерпретировать роль как контейнер полномочий.
Полномочия - это детализированные разрешения, нацеленные на конкретное действие в сочетании с определенной областью или контекстом данных. Например, Read, Write, Manage, могут представлять различные уровни разрешений для данного объема информации.
Кроме того, полномочия применяются глубоко в потоке обработки запроса, в то время как ROLE фильтруются путем фильтрации запросов до достижения Контроллера. Лучшие практики предписывают реализацию полномочий органов управления после Контроллера на бизнес-уровне.
С другой стороны, РОЛИ - это грубое представление набора разрешений. ROLE_READER будет иметь только права на чтение или просмотр, а ROLE_EDITOR будет иметь права на чтение и запись. Роли в основном используются для первого просмотра на окраине обработки запроса, такой как http. ... .antMatcher (...). hasRole (ROLE_MANAGER)
Полномочия, применяемые глубоко в потоке процесса запроса, позволяют более детально применять разрешение. Например, пользователь может иметь разрешение на чтение и запись для первого уровня ресурса, но только для чтения на подресурс. Наличие ROLE_READER ограничило бы его право редактировать ресурс первого уровня, так как ему нужно разрешение на запись для редактирования этого ресурса, но перехватчик @PreAuthorize может заблокировать его предварительное редактирование подресурса.
Джейк
источник
Как уже упоминалось, я думаю о ролях как контейнерах для более детальных разрешений.
Хотя я обнаружил, что реализации роли иерархии не хватает точного контроля над этими гранулярными разрешениями.
Поэтому я создал библиотеку для управления отношениями и введения разрешений в качестве предоставленных прав доступа в контексте безопасности.
У меня может быть набор разрешений в приложении, например CREATE, READ, UPDATE, DELETE, которые затем связаны с ролью пользователя.
Или более конкретные разрешения, такие как READ_POST, READ_PUBLISHED_POST, CREATE_POST, PUBLISH_POST
Эти разрешения относительно статичны, но отношение ролей к ним может быть динамическим.
Пример -
Вы можете создавать API для управления отношением этих разрешений к роли.
Я не хочу копировать / вставлять другой ответ, поэтому вот ссылка на более полное объяснение SO.
https://stackoverflow.com/a/60251931/1308685
Чтобы повторно использовать мою реализацию, я создал репо. Пожалуйста, не стесняйтесь вносить свой вклад!
https://github.com/savantly-net/spring-role-permissions
источник