Разница между ролью и GrantedAuthority в весенней безопасности
есть концепции и реализации в Spring Security, такие как GrantedAuthority
интерфейс, чтобы получить авторитет для авторизации / управления доступом.
Я хотел бы, чтобы допустимые операции, такие как createSubUsers или deleteAccounts, который я бы позволил admin (С ролью ROLE_ADMIN
).
Я запутываюсь, как учебники / демонстрации, которые я вижу в интернете. Я пытаюсь связать то, что я читаю, но я думаю мы относимся к этим двум взаимозаменяемо.
Я вижу hasRole
потребление GrantedAuthority
строку? Я определенно делаю это неправильно понять. Что это такое концептуально в весенней безопасности?
как сохранить роль пользователя, отдельно от полномочий для этой роли?
Я тоже смотрю на 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)
или есть другой способ отличить два других? Или это не поддерживается, и мы должны сделать наш собственный?
3 ответа:
подумайте о GrantedAuthority как о "разрешении"или " праве". Эти "разрешения" (обычно) выражаются в виде строк (с
getAuthority()
метод). Эти строки позволяют идентифицировать разрешения и позволяют вашим избирателям решать, предоставляют ли они доступ к чему-либо.вы можете предоставить различные GrantedAuthoritys (разрешения) для пользователей, поместив их в контекст безопасности. Обычно вы делаете это, реализуя свой собственный UserDetailsService, который возвращает UserDetails реализация, которая возвращает необходимые GrantedAuthorities.
роли (как они используются во многих примерах) - это просто "разрешения" с Соглашением об именах, в котором говорится, что роль является GrantedAuthority, которая начинается с префикса
ROLE_
. Больше ничего нет. Роль - это просто предоставленное право - "разрешение" - "право". Вы видите много мест в spring security, где роль с ееROLE_
префикс обрабатывается специально, например, в RoleVoter, гдеROLE_
префикс используется по умолчанию. Это позволяет предоставить имена ролей безROLE_
префикс. До Spring security 4 Эта специальная обработка "ролей" не соблюдалась очень последовательно, и власти и роли часто обрабатывались одинаково (как вы, например, можете видеть в реализацииhasAuthority()
метод SecurityExpressionRoot - который просто называетhasRole()
). С Spring Security 4 обработка ролей более последовательна и код, который имеет дело с "ролями" (напримерRoleVoter
наhasRole
выражение etc.) всегда добавляетROLE_
префикс для вас. Так чтоhasAuthority('ROLE_ADMIN')
означает то же самое, что иhasRole('ADMIN')
потому чтоROLE_
префикс добавляется автоматически. См. безопасность весны 3 до 4 руководство по миграции для получения дополнительной информации.но все же: роль-это просто авторитет со специальным
ROLE_
префикс. Так что весной безопасность 3@PreAuthorize("hasRole('ROLE_XYZ')")
это то же самое, что@PreAuthorize("hasAuthority('ROLE_XYZ')")
а весной безопасность 4@PreAuthorize("hasRole('XYZ')")
это то же самое, что@PreAuthorize("hasAuthority('ROLE_XYZ')")
.что касается вашего варианта использования:
пользователи имеют роли и роли могут выполнять определенные операции.
вы можете оказаться в
GrantedAuthorities
для ролей, к которым принадлежит пользователь, и операций, которые может выполнять роль. ЭлементGrantedAuthorities
для ролей есть префиксROLE_
и операции имеют префиксOP_
. Примером для оперативных органов может бытьOP_DELETE_ACCOUNT
,OP_CREATE_USER
,OP_RUN_BATCH_JOB
etc. Роли могут быть 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" и т. д. Когда пользователь проходит проверку подлинности, убедитесь, что все предоставленные полномочия всех его ролей и соответствующих операций возвращаются из 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.
AFAIK GrantedAuthority и роли одинаковы в spring security. Строка getAuthority () GrantedAuthority является ролью (согласно реализации по умолчанию 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>
Не точный sol вы ищете, но надеюсь, что это поможет
Edit: ответ на ваш комментарий
роль - это как разрешение в spring-security. использование intercept-url с hasRole обеспечивает очень мелкозернистый контроль того, какая операция разрешена для какой роли/разрешения.
то, как мы обрабатываем в нашем приложении, мы определяем разрешение (т. е. роль) для каждой операции (или url-адрес rest), например, view_account, delete_account, add_account и т. д. Затем мы создаем логические профили для каждого пользователя, такие как admin, guest_user, normal_user. Профили - это просто логическая группировка разрешений, независимая от spring-security. При добавлении нового пользователя ему присваивается профиль (имеющий все допустимые разрешения). Теперь, когда пользователь пытается выполнить какое-либо действие, разрешение/роль для этого действия проверяется на соответствие пользовательским grantedAuthorities.
также defaultn RoleVoter использует префикс ROLE_, поэтому любой авторитет, начинающийся с ROLE_, рассматривается как роль, вы можете изменить это поведение по умолчанию, используя пользовательский RolePrefix в Role voter и используя его в spring security.
еще один способ понять взаимосвязь между этими понятиями-это интерпретировать роль как контейнер авторитетов.
полномочия-это мелкозернистые разрешения, нацеленные на конкретное действие, иногда связанное с определенной областью данных или контекстом. Например, чтение, запись, Управление могут представлять различные уровни разрешений для данной области информации.
кроме того, полномочия применяются глубоко в потоке обработки запроса, в то время как роль фильтруется по запросу фильтруйте путь до достижения контроллера. Передовая практика предписывает внедрение правоприменения органов власти мимо контролера на бизнес-уровне.
с другой стороны, роли-это грубое представление набора разрешений. ROLE_READER будет только читать или просматривать полномочия, в то время как ROLE_EDITOR будет читать и писать. Роли главным образом использованы для первого скрининга на outskirt обрабатывать запроса как http. ... .antMatcher(...).hasRole (ROLE_MANAGER)
полномочия, применяемые глубоко в потоке процесса запроса, позволяют более тонкое применение разрешения. Например, пользователь может иметь разрешение на чтение и запись первого уровня ресурса, но читать только на суб-ресурсов. Имея ROLE_READER будет ограничивать его право на редактирование первого ресурса уровне, он должен написать разрешение на редактирование этого ресурса, а @предварительного блокирования средств перехватчик может заблокировать его попытки изменить суб-ресурс.
Джейк