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