Разница между ролью и полномочиями в Spring безопасности
Существуют концепции и реализации в Spring безопасности, такие как интерфейс GrantedAuthority
, чтобы получить полномочия на авторизацию/управление доступом.
Я хотел бы, чтобы это допустимые операции, такие как createSubUsers или deleteAccounts, которые я бы разрешил администратору (с ролью ROLE_ADMIN
).
Я запутался как учебники/демо, которые я вижу в Интернете. Я пытаюсь подключить то, что я читаю, но я думаю, что мы рассматриваем два взаимозаменяемых.
Я вижу hasRole
, потребляющую строку GrantedAuthority
? Я определенно делаю это неправильно в понимании. Что это концептуально в Spring безопасности?
Как сохранить роль пользователя, отдельно от полномочий для этой роли?
Я также смотрю интерфейс org.springframework.security.core.userdetails.UserDetails
, который используется в DAO, использующем аутентификацию поставщика, который потребляет User
(обратите внимание на последний GrantedAuthority):
public User(String username,
String password,
boolean enabled,
boolean accountNonExpired,
boolean credentialsNonExpired,
boolean accountNonLocked,
Collection<? extends GrantedAuthority> authorities)
Или есть ли другой способ отличить два других? Или это не поддерживается, и мы должны сделать свой собственный?
Ответы
Ответ 1
Подумайте о разрешенной доверенности как о "разрешении" или "праве". Эти "разрешения" (обычно) выражаются как строки (с помощью метода getAuthority()
). Эти строки позволяют вам идентифицировать разрешения и позволять вашим избирателям решать, предоставляют ли они что-либо.
Вы можете предоставить пользователям GrenderAuthority (разрешения) разные пользователи, помещая их в контекст безопасности. Вы обычно это делаете, реализуя свой собственный UserDetailsService, который возвращает реализацию UserDetails, которая возвращает необходимые GrantedAuthorities.
Роли (как они используются во многих примерах) - это просто "разрешения" с соглашением об именах, в котором говорится, что роль - это GrantedAuthority, которая начинается с префикса ROLE_
. Больше ничего. Роль - это просто "Разрешенная поддержка" - "разрешение" - "право". Вы видите множество мест в spring безопасности, где роль с префиксом ROLE_
обрабатывается специально, например. в RoleVoter, где префикс ROLE_
используется по умолчанию. Это позволяет вам указывать имена ролей с префиксом ROLE_
. До spring безопасности 4 эта специальная обработка "ролей" не выполнялась очень последовательно, а полномочия и роли часто обрабатывались одинаково (как вы, например, можете видеть в реализации метода hasAuthority()
в SecurityExpressionRoot - который просто вызывает hasRole()
). С spring Security 4 обработка ролей более согласована, а код, который имеет дело с "ролями" (например, выражение RoleVoter
, hasRole
и т.д.), Всегда добавляет префикс ROLE_
для вас. Таким образом, hasAuthority('ROLE_ADMIN')
означает то же, что и hasRole('ADMIN')
, потому что префикс ROLE_
добавляется автоматически. Подробнее см. В руководстве по безопасности spring от 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 и т.д.
В результате вы можете реализовать свои объекты GrantedAuthority
как в этом примере (псевдокод):
@Entity
class Role implements GrantedAuthority {
@Id
private String id;
@OneToMany
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;
@OneToMany
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.
Ответ 2
AFAIK GrantedAuthority и роли одинаковы в безопасности spring. GrantedAuthority getAuthority() - это роль (в соответствии с реализацией по умолчанию SimpleGrantedAuthority).
В вашем случае вы можете использовать иерархические роли
<bean id="roleVoter" class="org.springframework.security.access.vote.RoleHierarchyVoter">
<constructor-arg ref="roleHierarchy" />
</bean>
<bean id="roleHierarchy"
class="org.springframework.security.access.hierarchicalroles.RoleHierarchyImpl">
<property name="hierarchy">
<value>
ROLE_ADMIN > ROLE_createSubUsers
ROLE_ADMIN > ROLE_deleteAccounts
ROLE_USER > ROLE_viewAccounts
</value>
</property>
</bean>
Не точный зол, который вы ищете, но надеюсь, что он поможет
Изменить: ответ на ваш комментарий
Роль подобна разрешению в spring -security. используя intercept-url with hasRole обеспечивает очень мелкий контроль над тем, какая операция разрешена для какой роли/разрешения.
Как мы обрабатываем в нашем приложении, мы определяем разрешение (то есть роль) для каждой операции (или URL-адрес отдыха), например. view_account, delete_account, add_account и т.д. Затем мы создаем логические профили для каждого пользователя, такие как admin, guest_user, normal_user. Профили - это просто логическая группировка разрешений, независимо от spring -security.
Когда новый пользователь добавляется, ему присваивается профиль (имеющий все допустимые разрешения). Теперь, когда пользователь пытается выполнить какое-либо действие, разрешение/роль для этого действия проверяется на пользователя, предоставленномAuthorities.
Также по умолчанию в RoleVoter используется префикс ROLE_, поэтому любой авторитет, начинающийся с ROLE_, рассматривается как роль, вы можете изменить это поведение по умолчанию, используя пользовательский параметр RolePrefix в роли избирателя и используя его в безопасности spring.
Ответ 3
Еще один способ понять взаимосвязь между этими понятиями - это интерпретировать роль как контейнер полномочий.
Полномочия - это детализированные разрешения, нацеленные на конкретное действие в сочетании с определенной областью или контекстом данных. Например, Read, Write, Manage, могут представлять различные уровни разрешений для данного объема информации.
Кроме того, полномочия применяются глубоко в потоке обработки запроса, в то время как ROLE фильтруются путем фильтрации запросов до достижения Контроллера. Лучшие практики предписывают реализацию полномочий органов управления после Контроллера на бизнес-уровне.
С другой стороны, ROLES представляют собой грубое представление набора разрешений. ROLE_READER будет иметь только права на чтение или просмотр, а ROLE_EDITOR будет иметь права на чтение и запись. Роли в основном используются для первого просмотра на окраине обработки запроса, такого как
HTTP....
.antMatcher(...). hasRole (ROLE_MANAGER)
Полномочия, применяемые глубоко в потоке обработки запросов, позволяют более детально применять разрешение. Например, пользователь может иметь разрешение на чтение и запись для первого уровня ресурса, но только для чтения на подресурс. Наличие ROLE_READER ограничило бы его право редактировать ресурс первого уровня, так как ему нужно разрешение на запись для редактирования этого ресурса, но перехватчик @PreAuthorize может заблокировать его предварительное редактирование подресурса.
Джейк