nirgn
nirgn

Reputation: 2074

Angular2 authentication fail with 401

I'm building an Angular2 app with Spring-MVC. I added authentication with Spring Security, and when I query my REST server with postman everything is fine. When I add the Authorization to my header in Angular2 I get an 401 error.

The error: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:4200' is therefore not allowed access. The response had HTTP status code 401

My Angular2 service:

@Injectable()
export class BookService {
  headers = new Headers();
  options = new RequestOptions({ headers: this.headers });

  constructor(
    private http: Http) {
      this.headers.append('Content-Type', 'application/json');
      this.headers.append('Authorization', 'Basic ' + btoa('nirgn:password'));
  }

  getBooksByCategory(categoryId: number) {
    return this.http.get(environment.baseUrl + 'categories/' + categoryId + '/books', this.options)
      .map((res: Response) => <Book[]>res.json()._embedded.books)
      .catch(this.handleError);
  }
}

In spring I allow all origin like this: response.addHeader("Access-Control-Allow-Origin", "*"); (in CORSFilter implements Filter class).

Also, I added the authentication like this:

@Override
protected void configure(HttpSecurity http) throws Exception {
    http.httpBasic().and().authorizeRequests().anyRequest().authenticated();
}

And when I remove the .and().authorizeRequests().anyRequest().authenticated() I don't get any error, and able to GET the data from the server.

So, all in all I'm pretty sure it's not Access-Control-Allow-Origin and it's because the server don't get my Authorization header. When I try to query the server in postman, without auth I also get 401, but when I add Basic auth I get 200.

I also check the output of the password in postman and in angualr2 to make sure 'Basic ' + btoa('nirgn:password') in angualr2 output the same password postman does and it's the same. Here it is: enter image description here

Upvotes: 1

Views: 751

Answers (1)

nirgn
nirgn

Reputation: 2074

So I manage to figure it out. It was the CORS after all (in spring).

I had to tell my configure class to use the CORSFilter I created like

@Override
protected void configure(HttpSecurity http) throws Exception {
    http.httpBasic().and().authorizeRequests().anyRequest().authenticated()
        .and().addFilterAfter(new CORSFilter(), CsrfFilter.class);
}

The strange thing I still don't understand is why with postman it was successful and in the browser (with angular) I get the error.

Upvotes: 1

Related Questions