0
votes

I have a Spring Boot App with a RestController, a custom Security Filter and an Angular 2 Application which requests data from the spring service.

Because of the Access-Control-Allow-Origin Issue I have a Filter which sets the header.

This works fine if I call localhost:4200 to localhost:8080 but it doesn't work from localhost:4200 to some ip xx.xx.xx.xx:8080.

So someone have an idea?

Here my Filter:

@Component
public class MyCorsFilter implements Filter {

    public MyCorsFilter() {
        System.out.println("init filter corsssss");
    }

    @Override
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {

        HttpServletRequest request = (HttpServletRequest) req;
        HttpServletResponse response = (HttpServletResponse) res;

        response.setHeader("Access-Control-Allow-Origin", request.getHeader("Origin"));
        response.setHeader("Access-Control-Allow-Credentials", "true");
        response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
        response.setHeader("Access-Control-Max-Age", "3600");
        response.setHeader("Access-Control-Allow-Headers", "Content-Type, Accept, X-Requested-With, remember-me");

        chain.doFilter(req, res);
    }

    @Override
    public void init(FilterConfig filterConfig) {
    }

    @Override
    public void destroy() {
    }
}
2
It seems this is just a "localhost" behavior, if I deploy the spring boot app and angular app both on the server then the filter is working good and the access-control headers are set. - deadpoint

2 Answers

0
votes

I had the same probleme.

Try this in your Controllers:

@Context
private HttpServletResponse servletResponse;

private void allowCrossDomainAccess() {
    if (servletResponse != null) {
        servletResponse.setHeader("Access-Control-Allow-Origin", "*");
    }
}

Then in your POST/GET Methode:

@CrossOrigin
@RequestMapping(value = "/login", method = RequestMethod.POST, consumes = "application/json")
public boolean loginController(@RequestBody User user) throws JSONException, NoSuchAlgorithmException, UnsupportedEncodingException {

    allowCrossDomainAccess();  
    return userService.login(user);
}

Best regards,

0
votes

This is a security feature. Instead of allowing any origin you should control who can access your content, in Spring:

@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
...
@Override
protected void configure(HttpSecurity http) throws Exception {
    http.csrf().csrfTokenRepository(csrfTokenRepository());
}
    ...
@Bean
public CsrfTokenRepository csrfTokenRepository() { 
    CookieCsrfTokenRepository repository = new CookieCsrfTokenRepository();
    repository.setHeaderName("X-XSRF-TOKEN");
    repository.setCookieHttpOnly(false);
    return repository;
}

then in Angular change your app.module.ts

import { HttpModule, XSRFStrategy, CookieXSRFStrategy } from '@angular/http';

export function xsrfFactory() { return new CookieXSRFStrategy('XSRF-TOKEN', 'x-xsrf-token'); }
...
  providers: [
     ...
        { provide: XSRFStrategy, useFactory: xsrfFactory },
...

This way your REST calls will have the cookie parameter attached.

Alternatively you can just do this - I do not suggest it, but it might be useful if you don't want to worry about this right now:

@Override
protected void configure(HttpSecurity http) throws Exception {
    http.csrf().disable();
}