Angular 2 Basic Authentication not working

42,348

Solution 1

Simplified version to add custom headers to your request:

import {Injectable} from '@angular/core';
import {Http, Headers} from '@angular/http';

@Injectable()
export class ApiService {

   constructor(private _http: Http) {}

   call(url): Observable<any> {
      let username: string = 'username';
      let password: string = 'password';
      let headers: Headers = new Headers();
      headers.append("Authorization", "Basic " + btoa(username + ":" + password)); 
      headers.append("Content-Type", "application/x-www-form-urlencoded");
      return this._http.post(url, data, {headers: headers})
    }
}

It's hard to determine where you went wrong, because the lack of code of the actual http call you do. But this example should work for you

Solution 2

jrcastillo suggested another option here

I spent so many hours trying to fix this and this one liner solved my problem.

@Override
public void configure(WebSecurity web) throws Exception {
    web.ignoring().antMatchers(HttpMethod.OPTIONS, "/**");
}

I was a bit more specific in the end as this effected my /login path so I did the following instead:

@Override
public void configure(WebSecurity web) throws Exception {
    web.ignoring().antMatchers(HttpMethod.OPTIONS, "/api/**");
}

Solution 3

I had same problem in my application.

As you can see the request that is sended is not POST but OPTION ( pre verification)

https://developer.mozilla.org/fr/docs/HTTP/Access_control_CORS

You must allowed the OPTIONS request at your API side. If you have Spring application you can just add this to Spring Security configuration :

    protected void configure(HttpSecurity http) throws Exception {
        http.csrf().disable()
                .authorizeRequests()
                **.antMatchers(HttpMethod.OPTIONS, "/**").permitAll()**
(..)

}

In my case it works

Solution 4

This solved my issues:
Angular2 http post - how to send Authorization header?

Ok. I found problem.

It was not on the Angular side. To be honest, there were no problem at all.

Reason why I was unable to perform my request succesfuly was that my server app was not properly handling OPTIONS request.

Why OPTIONS, not POST? My server app is on different host, then frontend. Because of CORS my browser was converting POST to OPTION: http://restlet.com/blog/2015/12/15/understanding-and-using-cors/

With help of this answer: Standalone Spring OAuth2 JWT Authorization Server + CORS

I implemented proper filter on my server-side app.

Thanks to @Supamiu - the person which fingered me that I am not sending POST at all.

Share:
42,348

Related videos on Youtube

Peter
Author by

Peter

Updated on January 21, 2020

Comments

  • Peter
    Peter over 4 years

    I'm trying to connect/ do a POST request to an API with Angular2, It's a very simple API with a Basic Authentication password. When disabling the password on the api everything works like expected. But when I enable the Basic Authentication Angular can no longer connect to the API. In Postman everything works. I tried the following without success.

    I've got two headers "Content-Type" and "Authorization"

    headers.append("Content-Type", "application/x-www-form-urlencoded");
    

    I've tried these two headers.

    headers.append("Authorization", "Basic " + btoa(Username + ":" + Password)); 
    headers.append("Authorization", "Basic VXNlcm5hbWU6UGFzc3dvcmQ=");
    

    The only thing I can find is that in the RAW request headers there's only a line with the header names but the values are missing:

    Access-Control-Request-Headers: authorization, content-type
    

    Raw headers:

    #Request Headers
    OPTIONS /shipment HTTP/1.1
    Host: api.example.com
    Connection: keep-alive
    Access-Control-Request-Method: POST
    Origin: http://localhost:4200
    User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.106 Safari/537.36
    Access-Control-Request-Headers: authorization, content-type
    Accept: */*
    Referer: http://localhost:4200/address
    Accept-Encoding: gzip, deflate, sdch
    Accept-Language: en-US,en;q=0.8,nl;q=0.6
    

    Hope someone can help

  • Skyware
    Skyware about 7 years
    I think that an issue is inside of _normalizedNames {"authorization" => "Authorization"}. It shall be {"authorization" => "basic VXNlcm5hbWU6UGFzc3dvcmQ"}.
  • Poul Kruijt
    Poul Kruijt about 7 years
    @Skyware Headers are case insensitive :)
  • Skyware
    Skyware about 7 years
    That`s good to know. However, It should be normalized to "authorization" => "basic xxx" not to "authorization" => "Authorization". Angular 2 normalize an authorization header badly.
  • Poul Kruijt
    Poul Kruijt about 7 years
    Ahh, that's what you meant. And yes, I agree with you
  • Skyware
    Skyware about 7 years
    I think that the solution is on back-end side as the solution mentioned here stackoverflow.com/questions/39408413/…
  • John
    John over 5 years
    I had to assign the new headers like this in order to make it work: headers = headers.append(...);