0

I'm using the code from Spring Data Rest and Cors in Spring Boot and How do I get basic auth working in AngularJS? for AngularJS.

CORS was working before I set up Basic Authentication. The Authentication itself was working on the server alone, but not in combination.

Yes I'm using Chrome and I read that CORS is not always correct working;
but it was working, and when I build the server and start it online (spring boot port 8080), it's also not working.

I'm getting: Refused to set unsafe header "Access-Control-Request-Headers" and the typical Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:63344' is therefore not allowed access. The response had HTTP status code 401. error.

Spring Boot

CORS

@Configuration
public class RestConfiguration {

    /**
     * https://stackoverflow.com/a/31748398/122441 until https://jira.spring.io/browse/DATAREST-573
     */
    @Bean
    public FilterRegistrationBean corsFilter() {
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        CorsConfiguration config = new CorsConfiguration();
        config.setAllowCredentials(true);
        config.addAllowedOrigin("*");
        config.addAllowedHeader("*");
        config.addAllowedMethod("OPTIONS");
        config.addAllowedMethod("HEAD");
        config.addAllowedMethod("GET");
        config.addAllowedMethod("PUT");
        config.addAllowedMethod("POST");
        config.addAllowedMethod("DELETE");
        config.addAllowedMethod("PATCH");
        source.registerCorsConfiguration("/**", config);
        // return new CorsFilter(source);
        final FilterRegistrationBean bean = new FilterRegistrationBean(new CorsFilter(source));
        bean.setOrder(0);
        return bean;
    }
}

Security

@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
    private static final String username = "dummy";
    private static final String password = "dummy";

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                .authorizeRequests() //Authorize Request Configuration
                .antMatchers("/api/**").hasRole("API")
                .anyRequest().authenticated()
                .and() //HTTP basic Authentication only for API
                .antMatcher("/api/**").httpBasic();
    }

    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
        auth
                .inMemoryAuthentication()
                .withUser(username).password(password).roles("API");
    }
}

AngularJS

app.config(function ($httpProvider, Base64Provider) {
    // https://stackoverflow.com/a/17959564/2715720
    $httpProvider.defaults.useXDomain = true;
    $httpProvider.defaults.withCredentials = true;
    delete $httpProvider.defaults.headers.common["X-Requested-With"];
    $httpProvider.defaults.headers.common["Accept"] = "application/json";
    $httpProvider.defaults.headers.common["Content-Type"] = "application/json";
    $httpProvider.defaults.headers.common["Access-Control-Request-Headers"] = "accept, content-type, origin, authorization";
    $httpProvider.defaults.headers.common['Authorization'] = 'Basic ' + Base64Provider.encode('dummy' + ':' + 'dummy');
});
br.julien
  • 3,420
  • 2
  • 23
  • 44
rala
  • 895
  • 2
  • 18
  • 43

1 Answers1

1

You need to add a cors filter in the security configuration.

@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                .addFilterBefore(new CORSFilter(), ChannelProcessingFilter.class)

                .authorizeRequests() 
                .antMatchers("/api/**").hasRole("API")
                .anyRequest().authenticated()
                .and() 
                .antMatcher("/api/**").httpBasic();
    }
}
Rafael Zeffa
  • 2,334
  • 22
  • 20