1

I've been working on a project using spring + spring security on my backend and have recently run into an issue with cors specifically:

The first two lines you can see successful api call output, following that chrome attempts to send http request with an options header to my rest service.

The first two lines you can see successful api call output, following that chrome attempts to send a Http request with an options header to my rest service.


My question is what could potentially be the source of this issue?


My front end in dev uses the angular CLI client, I havent had any issues with CORS until i created a custom filter for spring security hence adding my WebConfigurerAdapter config. Happy to supply additional code if required. However I don't think its related to that as I've removed the filter and the same issue occurs.

Tested in chrome, firefox and ubuntu browser same issue occurs.

Angular CLI is successfully proxying calls to '/api/[blah]' Angular CLI is Proxying my rest service

Here's my proxy config, i've tried just matching on everything but that makes no difference.

{
"/api/*": {
  "target": "http://localhost:8080",
  "secure": false,
  "logLevel": "debug",
  "changeOrigin": true
}

}

WebSecurityAdapter Config

@Override
protected void configure(HttpSecurity http) throws Exception {

    http
            .httpBasic()
            .and()
            .authorizeRequests()
            .antMatchers("/index.html",  "/api/registration", "/api/authenticate",
                    "/api/isAuthenticated", "/api/validateCaptcha", "/console", "/api/loginRecaptchaRequired", "/api/login", "/")
            .permitAll()
            .anyRequest()
            .authenticated()
            .and()
            .addFilterBefore(
                    authenticationFilter(),
                    UsernamePasswordAuthenticationFilter.class)
            .logout()
            .logoutUrl("/api/logout")
            .and()
            .csrf()
            .csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse())
            .and()
            .addFilterAfter(csrfHeaderFilter(), SessionManagementFilter.class);

}

Request headers: enter image description here

Nathan
  • 43
  • 5
  • You appear to be missing the allow-origin header, so no origins can use CORS. [Info](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Origin) – jrtapsell Mar 15 '18 at 15:09
  • 1
    Backend, I would work out which domains should be able to make CORS requests, and whitelist them here, unless you want to make it public, then use `*` – jrtapsell Mar 15 '18 at 15:19
  • 1
    Thanks, using this to add cors: https://docs.spring.io/spring-security/site/docs/current/reference/html/cors.html – Nathan Mar 15 '18 at 15:31

1 Answers1

3

Why your code wasn't working

You are missing the Access-Control-Allow-Origin header, so that no site is allowed to make CORS requests to your site

Fixes

You can either:

  • Make the requests from the same origin
  • Use spring security to add the header to the responses
  • Manually add the header

What origins to allow

The header is either a whitelist of origins to allow, or it can be * to allow any origin to send requests.

Does this stop all requests except whitelisted ones

This only protects in browsers, mallicious software can still make requests to any endpoint without having to comply with CORS.

jrtapsell
  • 6,719
  • 1
  • 26
  • 49
  • Thanks :) the one thing i find strange is that I've been using the same setup for a while now but haven't had to add cors, ideally id like to set it up so that i don't have to allow cors so that there's no way cors is accidentally added to prod. additionally with allowing localhost:4200 couldn't an attacker just proxy themselves to appear as that site? – Nathan Mar 15 '18 at 15:45
  • It is more to prevent cookies being sent with requests, as the attacker wouldn't be able to make requests to the API as a logged in user, even if they proxied access to the API. – jrtapsell Mar 15 '18 at 15:50