Pense em uma GrantedAuthority como sendo uma "permissão" ou um "direito". Essas "permissões" são (normalmente) expressas como seqüências de caracteres (com o getAuthority()método). Essas cadeias permitem identificar as permissões e permitir que seus eleitores decidam se concedem acesso a algo.
Você pode conceder diferentes GrantedAuthoritys (permissões) aos usuários colocando-os no contexto de segurança. Você normalmente faz isso implementando seu próprio UserDetailsService que retorna uma implementação de UserDetails que retorna as GrantedAuthorities necessárias.
Funções (como são usadas em muitos exemplos) são apenas "permissões" com uma convenção de nomenclatura que diz que uma função é uma GrantedAuthority que começa com o prefixo ROLE_. Não há mais nada. Uma função é apenas uma Autoridade Concedida - uma "permissão" - um "direito". Você vê muitos lugares na segurança da primavera em que a função com seu ROLE_prefixo é tratada especialmente como, por exemplo, no RoleVoter, onde o ROLE_prefixo é usado como padrão. Isso permite que você forneça os nomes das funções sem o ROLE_prefixo. Antes da segurança da Primavera 4, esse tratamento especial de "funções" não era seguido de maneira muito consistente e as autoridades e funções eram frequentemente tratadas da mesma maneira (como vocêhasAuthority()hasRole()) Com o Spring Security 4, o tratamento de funções é mais consistente e o código que lida com "funções" (como RoleVotera hasRoleexpressão etc.) sempre adiciona o ROLE_prefixo para você. Isso hasAuthority('ROLE_ADMIN')significa o mesmo que hasRole('ADMIN')porque o ROLE_prefixo é adicionado automaticamente. Consulte o guia de migração de segurança de mola 3 a 4 para obter mais informações.
Mas ainda assim: um papel é apenas uma autoridade com um ROLE_prefixo especial . Portanto, no Spring security 3 @PreAuthorize("hasRole('ROLE_XYZ')")é o mesmo que @PreAuthorize("hasAuthority('ROLE_XYZ')")e no Spring security 4 @PreAuthorize("hasRole('XYZ')")é o mesmo que @PreAuthorize("hasAuthority('ROLE_XYZ')").
Em relação ao seu caso de uso:
Os usuários têm funções e as funções podem executar determinadas operações.
Você pode acabar com GrantedAuthoritiesas funções às quais um usuário pertence e as operações que uma função pode executar. As GrantedAuthoritiesfunções para têm o prefixo ROLE_e as operações têm o prefixo OP_. Um exemplo para as autoridades de operação poderia ser OP_DELETE_ACCOUNT, OP_CREATE_USER, OP_RUN_BATCH_JOBetc. Os papéis podem ser ROLE_ADMIN, ROLE_USER, ROLE_OWNERetc.
Você pode acabar implementando suas entidades GrantedAuthoritycomo neste exemplo (pseudo-código):
@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;
}
}
Os IDs das funções e operações que você cria em seu banco de dados são a representação GrantedAuthority, por exemplo ROLE_ADMIN, OP_DELETE_ACCOUNTetc. Quando um usuário é autenticado, verifique se todas as GrantedAuthorities de todas as suas funções e as operações correspondentes são retornadas do UserDetails.getAuthorities () método.
Exemplo: A função admin com id ROLE_ADMINtem as operações OP_DELETE_ACCOUNT, OP_READ_ACCOUNT, OP_RUN_BATCH_JOBatribuído a ele. A função de usuário com id ROLE_USERpossui a operação OP_READ_ACCOUNT.
Se um administrador logs no contexto de segurança resultante terá os GrantedAuthorities:
ROLE_ADMIN, OP_DELETE_ACCOUNT, OP_READ_ACCOUNT,OP_RUN_BATCH_JOB
Se um usuário fizer isso, ele vai ter:
ROLE_USER,OP_READ_ACCOUNT
O UserDetailsService cuidaria de coletar todas as funções e todas as operações dessas funções e disponibilizá-las pelo método getAuthorities () na instância retornada de UserDetails.