[RESOLVIDO] Acesso negado - Spring Boot + Autenticação Basic Http

Olá galera,
tudo bom?

Estou tendo dificuldades para conseguir realizar um request simples em meu projeto. O backend está sendo construído tendo como base o Spring Boot. Implementei uma autenticação HTTP Basic para testar.

Através da ferramenta POSTMAN, consigo obter os dados sem problemas passando usuário + senha no Header da requisição (imagem abaixo). Porém, quando tento montar um request a partir do Frontend (que está apartado do Backend), recebo o seguinte erro: Response for preflight has invalid HTTP status code 401. Já testei diversas formas de realizar o request mas em todas o erro de não autorizado é retornado. Estou começando a imaginar se pode haver a necessidade de realizar alguma liberação no Backend mas não tenho idéia do que seja.

Estou lendo sobre CORS (Cross-origin resource sharing) mas tenho dúvida se o problema está relacionado com isto, visto que pelo POSTMAN o request é feito com sucesso.

Por favor, poderiam me ajudar ?

Bem, seguem minhas classes e arquivo:

IMPLEMENTANDO HTTP BASIC
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SpringSecurityConfigHttpBasic extends WebSecurityConfigurerAdapter {

@Override
protected void configure(HttpSecurity http) throws Exception {
    http.csrf().disable()
            .authorizeRequests()
            .antMatchers("_ah/**").permitAll()
            .anyRequest().authenticated()
            .and().httpBasic()
            .and().sessionManagement()
            .sessionCreationPolicy(SessionCreationPolicy.STATELESS);
}

@Autowired
public void configureGlobalSecurity(AuthenticationManagerBuilder auth) throws Exception {

    auth.inMemoryAuthentication()
            .withUser("admin")
            .password("{noop}admin")
            .authorities("ADMIN");

    auth.inMemoryAuthentication()
            .withUser("user")
            .password("{noop}user")
            .authorities("USER");
}

CONTROLADOR PARA LISTAR PAISES
@RestController
@RequestMapping(path = “/pais”)
public class PaisController {

  private PaisDao paisDao = new PaisDao();

  @PreAuthorize("hasAnyAuthority('USER','ADMIN')")
  @GetMapping
  public ResponseEntity<List<Pais>> paises() {
      List<Pais> paises = paisDao.paises();

      return new ResponseEntity<List<Pais>>(paises, HttpStatus.OK);
  }
}

TESTANDO COM O POSTMAN

TESTANDO A PARTIR DE UM ARQUIVO HTML SIMPLES

<button onclick="listarPaises()">listar paises</button>

<script>	
function listarPaises(){
$.ajax({
    method: 'get',
    url: "http://localhost:8080/pais",  
    beforeSend: function(xhr) { 
    	xhr.setRequestHeader("Authorization", "Basic " + btoa("user" + ":" + "user")); 
    },         
    success:function(dados){
		console.log(dados);
	},
	error:function(dados){
		console.log("erro");
		console.log(dados);
	}
});

</script>

ERRO APRESENTADO CONSOLE

ERRO APRESENTADO NETWORK

CORS não retornaria erro 401, retornaria um erro de Cross origin.
De acordo com algumas respostas nesta thread, não se usa mais o setRequestHeader e sim o headers:

$.ajax({
    type: "GET",
    url: "index1.php",
    dataType: 'json',
    async: false,
    headers: {
        "Authorization": "Basic " + btoa(USERNAME + ":" + PASSWORD)
    },
    data: '{ "comment" }',
    success: function (){
        alert('Thanks for your comment!'); 
    }
});

Ou, ainda

$.ajaxSetup({
    headers: {
        'Authorization': "Basic " + btoa(USERNAME + ":" + PASSWORD)
    }
});

Olá Darlan,
tudo bem?

Obrigado pela ajuda. Fiz a modificação sugerida e agora o erro é o seguinte:

The 'Access-Control-Allow-Origin’

Teria alguma idéia? pelo que estou pesquisando, o erro parece se relacionar com o CORS. Fiz algumas tentativas mas não estou conseguindo.

Existem 2 mensagens de erro: a primeira é 401, unauthorized.
A segunda, sim, CORS.
Implemente o filtro cors do Spring Boot

Oi Darlan.

Consegui incluindo este método:
.antMatchers(HttpMethod.OPTIONS).permitAll()

A classe completa ficou assim:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SpringSecurityConfigHttpBasic extends WebSecurityConfigurerAdapter {

@Override
protected void configure(HttpSecurity http) throws Exception {
    http.csrf().disable()
            .authorizeRequests()
            .antMatchers("_ah/**").permitAll()
            .antMatchers(HttpMethod.OPTIONS).permitAll()
            .anyRequest().authenticated()
            .and().httpBasic()
            .and().sessionManagement()
            .sessionCreationPolicy(SessionCreationPolicy.STATELESS);
}

@Autowired
public void configureGlobalSecurity(AuthenticationManagerBuilder auth) throws Exception {

    auth.inMemoryAuthentication()
            .withUser("admin")
            .password("{noop}admin")
            .authorities("ADMIN");

    auth.inMemoryAuthentication()
            .withUser("user")
            .password("{noop}user")
            .authorities("USER");
  }

}

Nos meus controladores, inclui a anotação @CrossOrigin ficando:
@RestController
@CrossOrigin
@RequestMapping(path = “/pais”)
public class PaisController {
… codigo …
}

Ainda não li todo mas compartilho link do artigo que ajudou:

Valeu man.

Abraço.