Autoridade concedida versus função na segurança da primavera
1. Visão geral
Neste artigo rápido, explicaremosthe subtle but significant difference between a Role and a GrantedAuthority in Spring Security. Para obter informações mais detalhadas sobre funções e autoridades, consulte o artigohere.
Leitura adicional:
Tutorial de autenticação do Spring Security
Como criar um processo de registro em nível de produção para novos usuários e fluxo de logon para usuários existentes.
Spring Security para uma API REST
Como proteger uma API REST com Spring Security - a configuração XML, o web.xml, os códigos de status HTTP para autenticação, etc.
Autenticação básica do Spring Security
Configure a autenticação básica no Spring - a configuração XML, as mensagens de erro e exemplo de consumo de URLs protegidos com curl.
2. GrantedAuthority
No Spring Security, podemosthink of each GrantedAuthority as an individual privilege. Os exemplos podem incluirREAD_AUTHORITY,WRITE_PRIVILEGE ou mesmoCAN_EXECUTE_AS_ROOT. O importante a entender é quethe name is arbitrary.
Ao usar aGrantedAuthority diretamente, como por meio do uso de uma expressão comohasAuthority(‘READ_AUTHORITY'),, somosrestricting access in a fine-grained manner.
Como você provavelmente pode deduzir, podemos nos referir ao conceito deauthority usandoprivilege também.
3. Papel como autoridade
Da mesma forma, no Spring Security, podemosthink of each Role as a coarse-grained GrantedAuthority that is represented as a String and prefixed with “ROLE“. Ao usar umRole diretamente, por exemplo, por meio de uma expressão comohasRole(“ADMIN”), estamos restringindo o acesso de maneira grosseira.
É importante notar que o prefixo “ROLE” padrão é configurável, mas explicar como fazer isso está além do escopo deste artigo.
The core difference between these two is the semantics we attach to how we use the feature. Para a estrutura, a diferença é mínima - e basicamente lida com isso exatamente da mesma maneira.
4. Papel como contêiner
Agora que vimos como o framework usa o conceito derole, vamos também discutir rapidamente uma alternativa - que éusing roles as containers of authorities/privileges.
Essa é uma abordagem de nível mais alto para as funções - tornando-as um conceito mais voltado para os negócios do que voltado para a implementação.
O framework Spring Security não dá nenhuma orientação em termos de como devemos usar o conceito, então a escolha é inteiramente específica da implementação.
5. Configuração de segurança da primavera
Podemos demonstrar um requisito de autorização de baixa granularidade, restringindo o acesso a/protectedbyauthority para usuários comREAD_AUTHORITY.
Podemos demonstrar um requisito de autorização de baixa granularidade restringindo o acesso a/protectedbyrole para usuários comROLE_USER.
Vamos configurar esse cenário em nossa configuração de segurança:
@Override
protected void configure(HttpSecurity http) throws Exception {
// ...
.antMatchers("/protectedbyrole").hasRole("USER")
.antMatchers("/protectedbyauthority").hasAuthority("READ_PRIVILEGE")
// ...
}
6. Simple Data Init
Agora que entendemos melhor os conceitos principais, vamos falar sobre a criação de alguns dados de configuração quando o aplicativo for inicializado.
Essa é, é claro, uma maneira muito simples de fazer isso, atingir o ponto inicial com alguns usuários de teste preliminares durante o desenvolvimento - e não a maneira como você deve lidar com dados na produção.
Estaremos atentos ao evento de atualização de contexto:
@Override
@Transactional
public void onApplicationEvent(ContextRefreshedEvent event) {
MyPrivilege readPrivilege
= createPrivilegeIfNotFound("READ_PRIVILEGE");
MyPrivilege writePrivilege
= createPrivilegeIfNotFound("WRITE_PRIVILEGE");
}
A implementação real aqui não importa realmente - e geralmente depende da solução de persistência que você está usando. O ponto principal é - estamos insistindo nas autoridades que usamos no código.
7. UserDetailsService
Nossa implementação deUserDetailsService is where the authority mapping takes place. Depois que o usuário se autentica, nosso métodogetAuthorities() preenche e retorna um objetoUserDetails:
private Collection extends GrantedAuthority> getAuthorities(
Collection roles) {
List authorities
= new ArrayList<>();
for (Role role: roles) {
authorities.add(new SimpleGrantedAuthority(role.getName()));
role.getPrivileges().stream()
.map(p -> new SimpleGrantedAuthority(p.getName()))
.forEach(authorities::add);
}
return authorities;
}
8. Executando e testando o exemplo
Podemos executar o aplicativo Java de exemploRolesAuthoritiesApplication, encontrado emGitHub project.
Para ver a autorização baseada em função em ação, precisamos:
-
Autenticar como[email protected] (a senha é“user”)
-
Observe a autorização bem-sucedida
-
Observe a autorização malsucedida
Para ver a autorização baseada na autoridade em ação, precisamos sair do aplicativo e, em seguida:
-
Autenticar como[email protected] / admin
-
Observe a autorização bem-sucedida
-
Observe a autorização malsucedida
9. Conclusão
Neste tutorial rápido, vimos a diferença sutil, mas significativa entre aRolee aGrantedAuthority no Spring Security.