Думайте о предоставленном полномочии как о «разрешении» или «праве». Эти «разрешения» (обычно) выражаются в виде строк (с помощью 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.