Introdução às expressões de segurança da Spring

Introdução às expressões de segurança da Spring

1. Introdução

Neste tutorial, vamos nos concentrar em expressões de segurança Spring e, claro, em exemplos práticos com essas expressões.

Antes de olhar para implementações mais complexas (como ACL), é importante ter um conhecimento sólido sobre as expressões de segurança - pois podem ser bastante flexíveis e poderosas se usadas corretamente.

Este artigo é uma extensão deSpring Security Expressions – hasRole Example.

2. Dependências do Maven

Para usar Spring Security, você precisa incluir a seguinte seção em seu arquivopom.xml:


    
        org.springframework.security
        spring-security-web
        4.1.1.RELEASE
    

A última versão pode ser encontradahere.

E uma nota rápida - esta dependência cobre apenas Spring Security; não se esqueça de adicionar spring-core espring-context para um aplicativo da web completo.

3. Configuração

Primeiro, vamos dar uma olhada em uma configuração Java.

EstenderemosWebSecurityConfigurerAdapter - de modo que tenhamos a opção de conectar em qualquer um dos pontos de extensão que a classe base oferece:

@Configuration
@EnableAutoConfiguration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityWithoutCsrfConfig extends WebSecurityConfigurerAdapter {
    ...
}

É claro que também podemos fazer uma configuração XML:



    

4. Expressões de segurança da web

Agora, vamos começar a olhar para as expressões de segurança:

  • Hasrole, Hasanyrole

  • Hasauthority, Hasanyauthority

  • Permall, Denyall

  • Isanônimo, Isrememberme, Isauthenticated, Isfullyauthenticated

  • Principal, Autenticação

  • hasPermission

E agora vamos examinar cada um deles em detalhes.

4.1. hasRole, hasAnyRole

Essas expressões são responsáveis ​​por definir o controle de acesso ou a autorização para URLs ou métodos específicos em seu aplicativo.

Vejamos o exemplo:

@Override
protected void configure(final HttpSecurity http) throws Exception {
    ...
    .antMatchers("/auth/admin/*").hasRole("ADMIN")
    .antMatchers("/auth/*").hasAnyRole("ADMIN","USER")
    ...
}

Neste exemplo, especificamos o acesso a todos os links começando com/auth/ restrito aos usuários que estão logados com a funçãoUSER ou funçãoADMIN. Além disso, para acessar links começando com/auth/admin/ nós precisa ter a função deADMIN no sistema.

A mesma configuração pode ser alcançada no arquivo XML, escrevendo:


    
    

4.2. hasAuthority, hasAnyAuthority

Funções e autoridades são semelhantes na primavera.

A principal diferença é que as funções têm semântica especial - começando com Spring Security 4, o prefixo ‘ROLE_’ é adicionado automaticamente (se ainda não estiver lá) por qualquer método relacionado à função.

Portanto,hasAuthority(‘ROLE_ADMIN') é semelhante ahasRole(‘ADMIN') porque o prefixo ‘ROLE_’ é adicionado automaticamente.

Mas a coisa boa sobre o uso de autoridades é que não precisamos usar o prefixoROLE_.

Aqui está um exemplo rápido em que definimos usuários com autoridades específicas:

@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
    auth.inMemoryAuthentication()
      .withUser("user1").password("user1Pass")
      .authorities("USER")
      .and().withUser("admin").password("adminPass")
      .authorities("ADMIN");
}

É claro que podemos usar estas expressões de autoridades:

@Override
protected void configure(final HttpSecurity http) throws Exception {
    ...
    .antMatchers("/auth/admin/*").hasAuthority("ADMIN")
    .antMatchers("/auth/*").hasAnyAuthority("ADMIN", "USER")
    ...
}

Como podemos ver - não estamos mencionando funções aqui.

Por fim - é claro que também podemos obter a mesma funcionalidade usando a configuração XML:


    
        
            
            
        
    

And:


    
    

4.3. permitAll, denyAll

Essas duas anotações também são bastante diretas. Nós podemos permitir o acesso a algum URL em nosso serviço ou podemos negar o acesso.

Vamos dar uma olhada no exemplo:

...
.antMatchers("/*").permitAll()
...

Com esta configuração, autorizaremos todos os usuários (anônimos e logados) a acessar a página começando com ‘/ '(por exemplo, nossa página inicial).

Também podemos negar o acesso a todo o espaço da URL:

...
.antMatchers("/*").denyAll()
...

E, novamente, a mesma configuração também pode ser feita com uma configuração XML:


     
     

4.4. isAnonymous, isRememberMe, isAuthenticated, isFullyAuthenticated

Nesta subseção, focamos nas expressões relacionadas ao status de login do usuário. Vamos começar com o usuário que não fez login em nossa página. Ao especificar o seguinte na configuração Java, permitimos que todos os usuários não autorizados acessem nossa página principal:

...
.antMatchers("/*").anonymous()
...

O mesmo na configuração XML:


    

Se quisermos garantir o site que todos os que o usam terão de fazer login, precisamos usar o métodoisAuthenticated():

...
.antMatchers("/*").authenticated()
...

ou versão XML:


    

Além disso, temos duas expressões adicionais,isRememberMe()eisFullyAuthenticated(). Com o uso de cookies, o Spring habilita os recursos de lembrança de mim, para que não seja necessário fazer login no sistema a cada vez. Você pode lermore about Remember Me here.

Para conceder acesso aos usuários que efetuaram login apenas pela função Lembre-se de mim, podemos usar o seguinte:

...
.antMatchers("/*").rememberMe()
...

ou versão XML:


    

Por fim, algumas partes de nossos serviços exigem que o usuário seja autenticado novamente, mesmo que o usuário já esteja logado. Por exemplo, o usuário deseja alterar as configurações ou informações de pagamento; é claro que é uma boa prática solicitar autenticação manual nas áreas mais confidenciais do sistema.

Para fazer isso, podemos especificarisFullyAuthenticated(), que retornatrue se o usuário não for um usuário anônimo ou lembrar de mim:

...
.antMatchers("/*").fullyAuthenticated()
...

ou a versão XML:


    

4.5. principal, authentication

Essas expressões permitem acessar o objetoprincipal que representa o usuário autorizado (ou anônimo) atual e o objetoAuthentication atual deSecurityContext, respectivamente.

Podemos, por exemplo, usarprincipal para carregar o e-mail de um usuário, avatar ou qualquer outro dado acessível ao usuário conectado.

Eauthentication fornece informações sobre o objetoAuthentication completo, junto com suas autoridades concedidas.

Ambos são descritos em mais detalhes no seguinte artigo:Retrieve User Information in Spring Security.

4.6. APIshasPermission

Esta expressão édocumentede destina-se a fazer a ponte entre o sistema de expressão e o sistema ACL da Spring Security, permitindo-nos especificar restrições de autorização em objetos de domínio individuais, com base em permissões abstratas.

Vamos dar uma olhada em um exemplo. Temos um serviço que permite a redação cooperativa de artigos, com um editor principal, decidindo qual artigo proposto por outros autores deve ser publicado.

Para permitir o uso desse serviço, podemos criar os seguintes métodos com os métodos de controle de acesso:

@PreAuthorize("hasPermission(#articleId, 'isEditor')")
public void acceptArticle(Article article) {
   …
}

Apenas o usuário autorizado pode chamar este método, e também o usuário precisa ter permissãoisEditor no serviço.

Também precisamos nos lembrar de configurar explicitamente aPermissionEvaluator em nosso contexto de aplicativo:


    



    

ondecustomInterfaceImplementation será a classe que implementaPermissionEvaluator.

Obviamente, também podemos fazer isso com a configuração Java:

@Override
protected MethodSecurityExpressionHandler expressionHandler() {
    DefaultMethodSecurityExpressionHandler expressionHandler =
      new DefaultMethodSecurityExpressionHandler();
    expressionHandler.setPermissionEvaluator(new CustomInterfaceImplementation());
    return expressionHandler;
}

5. Conclusão

Este tutorial é uma introdução e um guia abrangentes para o Spring Security Expressions.

Todos os exemplos discutidos aqui estão disponíveison the GitHub project.