Autenticação básica do Spring Security

Autenticação básica do Spring Security

1. Visão geral

Este tutorial mostra como instalar, configurar e personalizarBasic Authentication with Spring. Vamos construir em cima doSpring MVC example simples e proteger a IU do aplicativo MVC com o mecanismo de autenticação básica fornecido pelo Spring Security.

2. A configuração de segurança Spring

Podemos configurar o Spring Security usando a configuração Java:

@Configuration
@EnableWebSecurity
public class CustomWebSecurityConfigurerAdapter extends WebSecurityConfigurerAdapter {

    @Autowired
    private MyBasicAuthenticationEntryPoint authenticationEntryPoint;

    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
        auth.inMemoryAuthentication()
          .withUser("user1").password(passwordEncoder().encode("user1Pass"))
          .authorities("ROLE_USER");
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
          .antMatchers("/securityNone").permitAll()
          .anyRequest().authenticated()
          .and()
          .httpBasic()
          .authenticationEntryPoint(authenticationEntryPoint);

        http.addFilterAfter(new CustomFilter(),
          BasicAuthenticationFilter.class);
    }

    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }
}

Aqui, estamos usando o elementohttpBasic() para definir a autenticação básica, dentro do métodoconfigure() de uma classe que estendeWebSecurityConfigurerAdapter.

O mesmo poderia ser alcançado usando XML também:



    
    



    
        
            
        
    

O que é relevante aqui é o elemento<http-basic> dentro do elemento<http> principal da configuração - isso é suficiente para habilitar a autenticação básica para todo o aplicativo. O Gerenciador de autenticação não é o foco deste tutorial, portanto, estamos usando um gerenciador de memória com o usuário e a senha definidos em texto sem formatação.

Oweb.xml do aplicativo da web habilitando Spring Security já foi discutido emSpring Logout tutorial.

3. Consumindo o aplicativo seguro

O comandocurl é nossa ferramenta para consumir o aplicativo seguro.

Primeiro, vamos tentar solicitar/homepage.html sem fornecer nenhuma credencial de segurança:

curl -i http://localhost:8080/spring-security-rest-basic-auth/api/foos/1

Recebemos de volta os401 Unauthorized ethe Authentication Challenge esperados:

HTTP/1.1 401 Unauthorized
Server: Apache-Coyote/1.1
Set-Cookie: JSESSIONID=E5A8D3C16B65A0A007CFAACAEEE6916B; Path=/spring-security-mvc-basic-auth/; HttpOnly
WWW-Authenticate: Basic realm="Spring Security Application"
Content-Type: text/html;charset=utf-8
Content-Length: 1061
Date: Wed, 29 May 2013 15:14:08 GMT

O navegador interpretaria esse desafio e nos solicitaria as credenciais com uma caixa de diálogo simples, mas como estamos usandocurl, esse não é o caso.

Agora, vamos solicitar o mesmo recurso - a página inicial - masprovide the credentials para acessá-lo também:

curl -i --user user1:user1Pass
  http://localhost:8080/spring-security-rest-basic-auth/api/foos/1

Agora, a resposta do servidor é200 OK junto com umCookie:

HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
Set-Cookie: JSESSIONID=301225C7AE7C74B0892887389996785D; Path=/spring-security-mvc-basic-auth/; HttpOnly
Content-Type: text/html;charset=ISO-8859-1
Content-Language: en-US
Content-Length: 90
Date: Wed, 29 May 2013 15:19:38 GMT

No navegador, o aplicativo pode ser consumido normalmente - a única diferença é que uma página de login não é mais um requisito difícil, pois todos os navegadores oferecem suporte à autenticação básica e usam uma caixa de diálogo para solicitar credenciais ao usuário.

4. Configuração Adicional - O ponto de entrada

Por padrão, oBasicAuthenticationEntryPoint provisionado pelo Spring Security retorna uma página inteira para uma resposta401 Unauthorized de volta ao cliente. Essa representação HTML do erro é bem renderizada em um navegador, mas não é adequada para outros cenários, como uma API REST em que uma representação json pode ser preferida.

O espaço para nome também é flexível o suficiente para esse novo requisito - para resolver isso - o ponto de entrada pode ser substituído:

O novo ponto de entrada é definido como um bean padrão:

@Component
public class MyBasicAuthenticationEntryPoint extends BasicAuthenticationEntryPoint {

    @Override
    public void commence(
      HttpServletRequest request, HttpServletResponse response, AuthenticationException authEx)
      throws IOException, ServletException {
        response.addHeader("WWW-Authenticate", "Basic realm="" + getRealmName() + """);
        response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
        PrintWriter writer = response.getWriter();
        writer.println("HTTP Status 401 - " + authEx.getMessage());
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        setRealmName("example");
        super.afterPropertiesSet();
    }
}

Ao escrever diretamente na resposta HTTP, agora temos controle total sobre o formato do corpo da resposta.

5. As dependências do Maven

As dependências do Maven para Spring Security foram discutidas antes emSpring Security with Maven article - precisaremos despring-security-webespring-security-config disponíveis em tempo de execução.

6. Conclusão

Neste exemplo, protegemos um aplicativo MVC com Spring Security e Basic Authentication. Discutimos a configuração XML e consumimos o aplicativo com comandos simples de curvatura. Finalmente, assumiu o controle do formato exato da mensagem de erro - movendo-se da página de erro HTML padrão para um texto personalizado ou formato JSON.

A implementação completa deste tutorial pode ser encontrada emthe GitHub project - este é um projeto baseado em Maven, portanto, deve ser fácil de importar e executar como está.

Quando o projeto é executado localmente, o HTML de amostra pode ser acessado em: