1

I'm trying to implement login functionality using angular and spring boot.

Im following spring tutorial https://spring.io/guides/tutorials/spring-security-and-angular-js/ But in my case my angular project is hosted on localhost:4200 and spring on localhost:8080

Now im sending a '/user' request to spring server. My angular code look like:

const headers = new HttpHeaders(credentials ? {
        authorization: 'Basic ' + btoa(credentials.username + ':' + credentials.password)
    } : {});

    this.http.get('http://localhost:8080'+'/user', { headers: headers }).subscribe(response => {
        if (response['name']) {
            this.authenticated = true;
        } else {
            this.authenticated = false;
        }
        return callback && callback();
    });

Now because of CORS it sends OPTIONS request which is successful with status 200. After this it is not sending actual GET request which should send credentials as Angular $http is sending OPTIONS instead of PUT/POST

My spring code looks like this:

@CrossOrigin(origins = "*", maxAge = 3600, allowedHeaders={"x-auth-token", "x-requested-with", "x-xsrf-token"})
@RequestMapping("/user")
public Principal user(Principal user) {
    return user;
}

@Configuration
@Order(SecurityProperties.DEFAULT_FILTER_ORDER)
protected static class SecurityConfiguration extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.httpBasic().and().cors().and().authorizeRequests().antMatchers("/index.html", "/", "/home", "/login").permitAll()
                .anyRequest().authenticated().and().csrf()
                .csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse());
    }
}

Also i have added Spring Security in pom file.

Can you please help to find out why GET request is not triggered after OPTIONS request.

Jawad
  • 103
  • 1
  • 8
  • Can you check browsers developer tool(network tab) – Priyesh Kumar Jun 03 '18 at 09:15
  • My Response Header look like: `Access-Control-Allow-Headers: x-requested-with Access-Control-Allow-Methods: GET,HEAD,POST Access-Control-Allow-Origin: * Access-Control-Max-Age: 3600 Cache-Control: no-cache, no-store, max-age=0, must-revalidate Content-Length: 0 Date: Sun, 03 Jun 2018 09:16:14 GMT Expires: 0 Pragma: no-cache Vary: Origin Vary: Access-Control-Request-Method Vary: Access-Control-Request-Headers X-Content-Type-Options: nosniff X-Frame-Options: DENY X-XSS-Protection: 1; mode=block` – Jawad Jun 03 '18 at 09:17
  • Is this your OPTIONS response?? – miiiii Jun 03 '18 at 09:17
  • Yes its my Response Header for OPTIONS request – Jawad Jun 03 '18 at 09:18
  • Is there any other call happening at browser after the success of OPTIONS?? – miiiii Jun 03 '18 at 09:24
  • Like, the GET call is made by the browser but server not receiving.. we can see that in networks tab. Please check it once more..!! – miiiii Jun 03 '18 at 09:25
  • No after OPTIONS request is successful there is no request that is being sent – Jawad Jun 03 '18 at 09:26
  • Alright, that means browser is not making the GET call on behalf of your code. !! – miiiii Jun 03 '18 at 09:27
  • Lemme understand it once again with response header. – miiiii Jun 03 '18 at 09:28

1 Answers1

3

Root Cause: In your spring security, you allowed only three types of request headers, i.e. allowedHeaders={"x-auth-token", "x-requested-with", "x-xsrf-token"}

But, in your http.GET request you are doing the basic authentication using header name as authorization which is rejected by Spring Security. So, the spring responses the allowed headers to your browser (i.e. preflight request with OPTIONS method) and your browser sees that.. Ooops.. authorization header is not allowed so I can't proceed with original GET call.

Solution: Allow authorization header also in your spring security. It should work.!!

miiiii
  • 1,580
  • 1
  • 16
  • 29
  • Is there any way like throw exception on console that server has rejected this request? – Priyesh Kumar Jun 03 '18 at 10:02
  • Actually, server is not rejecting it, server is telling your browser that I allow only these requests. – miiiii Jun 03 '18 at 10:03
  • @PriyeshKumar those preflight requests are actually a security check performed by the browser before making calls to cross origin servers. And, in response, they get set of criteria that are allowed by server, based on those criteria browser checks for your request, if it is valid with those so called criteria, then only browser makes the original call. Hope it makes sense..!! – miiiii Jun 03 '18 at 10:13