4

I'm using Spring Boot v2.1.1.RELEASE together with Spring Security and am trying to log into the application via REST.

I have a configuration file which implements WebMvcConfigurer so I can override the addCorsMappings method:

@Override
public void addCorsMappings(final CorsRegistry registry) {
    registry.addMapping("/**");
}

This works fine; I can send my login data to http://localhost:8080/login and get a normal Response back, with session cookie and all:

Access-Control-Allow-Origin: *
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Content-Length: 0
Date: Sun, 20 Jan 2019 13:14:46 GMT
Expires: 0
Pragma: no-cache
Set-Cookie: JSESSIONID=66B74AE4F547BA77604AE199E0A48D7E; Path=/; HttpOnly
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

Mind the Access-Control-Allow-Origin header. However, if I specify the allowed origins as follows, the Response does not include the formerly mentioned header:

@Override
public void addCorsMappings(final CorsRegistry registry) {
    registry.addMapping("/**").allowedOrigins("localhost");
}

Will result in the Response:

Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Content-Length: 20
Date: Sun, 20 Jan 2019 13:15:15 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

It doesn't matter which origin I am allowing; "http://localhost", "http://example.com" and "example.com" all lead to the same result.

While debugging, I noticed that the authentication process stops at the CorsFilter when I include the allowedOrigins bit in the code.

This is all about the login process! I can't use the @CrossOrigin annotation (as far as I'm aware) because I have no method to put it on.

I am testing the REST login with this script: https://pastebin.com/YezC3wWr

Is this a bug in Spring or by design? Am I missing something here?

EDIT: The "Access-Control-Allow-Origin" header in the response is only sent if the request is sent from an allowed origin, and that was NOT the case. I was hosting the HTML test file on http://localhost:8000, so I had to add this exact URL to the allowed origins on the server. Not localhost, not localhost:8000 but http://localhost:8000. The authentication then succeeds and the header is also included in the response.

GeckStar
  • 1,136
  • 1
  • 14
  • 22

2 Answers2

1

If you're running the HTML page on the same domain as the login request, there will be no Origin header in request, thus no Access-Control-Allow-Origin. Is this the case with your code? do you run the HTML file under http://localhost:8080/ ?

If no, please post the error from the browser's console. Also, would be great if you can post both request and response headers

Niros
  • 632
  • 5
  • 18
0

Try using "http://localhost:8080". Do you test it via web browser or POST directly for example with Postman?

Ruku
  • 62
  • 5
  • That url doesn't work either. I'm testing it via web browser with the following HTML file: https://pastebin.com/YezC3wWr – GeckStar Jan 20 '19 at 14:16
  • After lunching your html file, open browser console and navigate to Network section. Then reload page and try to login. Did the OPTIONS request pass? – Ruku Jan 20 '19 at 14:23
  • It does not do any OPTIONS request (which is strange?), neither with allowed origins nor without. Only one POST request to `http://localhost:8080/login`. – GeckStar Jan 20 '19 at 14:37
  • Try adding xhr.setRequestHeader("Origin", "http://localhost:8080") to your html file. Also please check the result of POST login call using Postman. – Ruku Jan 20 '19 at 14:49
  • Found the problem, I was hosting the HTML file on `http://localhost:8000`, not 8080. When I add that to the allowed origins, everything's fine. – GeckStar Jan 20 '19 at 15:37