Ajax login with spring and CORS security

I followed this tutorial to implement the api with spring-security. It works well locally, but when I deploy it to a remote server, the entry endpoint is not available due to cors policy (server: 80 is trying to reach server: 8080).

I added cors filters to handle this, but it seems that the login method (and possibly protected methods, I can't test it since I can't login) is not using my custom filter. Endpoints accessible to unregistered users work well

The request is preprogrammed, but the server is not adding the correct headers on the remote server.

First, here is the request and response for the requested request before reaching the public endpoint

Request:

Host: 01.02.03.04:8080
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Firefox/52.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Access-Control-Request-Method: GET
Access-Control-Request-Headers: x-requested-with
Origin: http://01.02.03.04
Connection: keep-alive
Cache-Control: max-age=0

      

Answer:

Access-Control-Allow-Methods: GET,HEAD,POST
Access-Control-Allow-Origin: http://01.02.03.04
Access-Control-Max-Age: 1800
Allow: GET, HEAD, POST, PUT, DELETE, TRACE, OPTIONS, PATCH
Content-Length: 0
Date: Mon, 10 Jul 2017 10:40:32 GMT
Vary: Origin
access-control-allow-credentials: true
access-control-allow-headers: x-requested-with

      

Here is the request and response for a pre-flight request before reaching the entry endpoint:

Request:

Host: 01.02.03.04:8080
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Firefox/52.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Access-Control-Request-Method: POST
Access-Control-Request-Headers: content-type,x-requested-with
Origin: http://01.02.03.04
Connection: keep-alive

      

Answer:

Allow: GET, HEAD, POST, PUT, DELETE, TRACE, OPTIONS, PATCH
Content-Length: 20
Date: Mon, 10 Jul 2017 11:18:40 GMT

      

We can easily see that when trying to reach / login, the server doesn't respond correctly.

Here is an ajax test to achieve / login:

Login.prototype.login = function(){
  var self = this;
  return function(){
    $.ajax({
      url:properties.serverUrl+'login',
      beforeSend:function(xhr) {
        xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
      },
      type : 'POST',
      dataType:"json",
      contentType: 'application/json',
      data:JSON.stringify({
        username:"username",
        password:"password"
      }),
      success:self.handleToken(),
      error:utils.displayError
    });
  }
}

      

Here's a way to configure the WebSecurityConfigurerAdapter:

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
        .csrf().disable() // We don't need CSRF for JWT based authentication
        .exceptionHandling()
        .authenticationEntryPoint(this.authenticationEntryPoint)

        .and()
            .sessionManagement()
            .sessionCreationPolicy(SessionCreationPolicy.STATELESS)

        .and()
            .authorizeRequests()
                .antMatchers(FORM_BASED_LOGIN_ENTRY_POINT).permitAll() // Login end-point
                .antMatchers(TOKEN_REFRESH_ENTRY_POINT).permitAll() // Token refresh end-point
        .and()
            .authorizeRequests()
                .antMatchers(TOKEN_BASED_AUTH_ENTRY_POINT).authenticated() // Protected API End-points
        .and()
            .addFilterBefore(new CustomCorsFilter(), UsernamePasswordAuthenticationFilter.class)
            .addFilterBefore(buildAjaxLoginProcessingFilter(), UsernamePasswordAuthenticationFilter.class)
            .addFilterBefore(buildJwtTokenAuthenticationProcessingFilter(), UsernamePasswordAuthenticationFilter.class);
    }

      

And here is a custom cors filter:

public class CustomCorsFilter extends CorsFilter {

public CustomCorsFilter() {
    super(configurationSource());
}

private static UrlBasedCorsConfigurationSource configurationSource() {
    CorsConfiguration config = new CorsConfiguration();
    config.setAllowCredentials(true);
    config.addAllowedOrigin("*");
    config.addAllowedHeader("*");
    config.setMaxAge(36000L);
    config.setAllowedMethods(Arrays.asList("GET", "HEAD", "POST", "PUT", "DELETE", "OPTIONS"));
    UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
    source.registerCorsConfiguration("/**", config);
    return source;
}
}

      

Thank you for your responses,

Emmanuel

+3


source to share





All Articles