08-02-2023, 04:25 PM
Update:
Now looking back more than a year later, I am giving an update hope that will help someone else.
Spring IO recommend using CSRF protection for any request that could be processed by a browser by normal users. If you are only creating a service that is used by non-browser clients, you will likely want to disable CSRF protection.
Since my app is an API and will be processed by a browser, so disable CSRF is not an approach.
CSRF is enabled with Spring Boot by default, you would need to add the following code to add a CSRF repository and a filter to add the CSRF token to your http requests. (The solution comes from here
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/assets/**", "/templates/**", "/custom-fonts/**", "/api/profile/**", "/h2/**").permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login")
.permitAll()
.and()
.logout()
.logoutSuccessUrl("/login?logout")
.permitAll()
.and()
.csrf().csrfTokenRepository(csrfTokenRepository())
.and()
.addFilterAfter(csrfHeaderFilter(), SessionManagementFilter.class); // Register csrf filter.
}
The filter & CsrfToken Repository part:
private Filter csrfHeaderFilter() {
return new OncePerRequestFilter() {
@Override
protected void doFilterInternal(HttpServletRequest request,
HttpServletResponse response,
FilterChain filterChain) throws ServletException, IOException {
CsrfToken csrf = (CsrfToken) request.getAttribute(CsrfToken.class.getName());
if (csrf != null) {
Cookie cookie = WebUtils.getCookie(request, "XSRF-TOKEN");
String token = csrf.getToken();
if (cookie == null || token != null
&& !token.equals(cookie.getValue())) {
// Token is being added to the XSRF-TOKEN cookie.
cookie = new Cookie("XSRF-TOKEN", token);
cookie.setPath("/");
response.addCookie(cookie);
}
}
filterChain.doFilter(request, response);
}
};
}
private CsrfTokenRepository csrfTokenRepository() {
HttpSessionCsrfTokenRepository repository = new HttpSessionCsrfTokenRepository();
repository.setHeaderName("X-XSRF-TOKEN");
return repository;
}
_________________________________________________________________________
Original Question I asked back in Feb 2016
I working on enabeing the Global CORS support for a Spring-boot RESTful API with Spring 4.
I am following the official Spring Boot Doc(
public class SomeApiApplication {
public static void main(String[] args) {
SpringApplication.run(SomeApiApplication.class, args);
}
//Enable Global CORS support for the application
@Bean
public WebMvcConfigurer corsConfigurer() {
return new WebMvcConfigurerAdapter() {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins("http://localhost:8080")
.allowedMethods("GET", "POST", "PUT", "DELETE", "HEAD")
.allowedHeaders("header1", "header2") //What is this for?
.allowCredentials(true);
}
};
}
}
I don't get why only GET is working, for the rest of http calls, I am getting an error message saying "Invalid CORS request". Do I miss anything in the set up? If my set up is not right, GET should not work as well. I am very confussed.
Now looking back more than a year later, I am giving an update hope that will help someone else.
Spring IO recommend using CSRF protection for any request that could be processed by a browser by normal users. If you are only creating a service that is used by non-browser clients, you will likely want to disable CSRF protection.
Since my app is an API and will be processed by a browser, so disable CSRF is not an approach.
CSRF is enabled with Spring Boot by default, you would need to add the following code to add a CSRF repository and a filter to add the CSRF token to your http requests. (The solution comes from here
[To see links please register here]
)@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/assets/**", "/templates/**", "/custom-fonts/**", "/api/profile/**", "/h2/**").permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login")
.permitAll()
.and()
.logout()
.logoutSuccessUrl("/login?logout")
.permitAll()
.and()
.csrf().csrfTokenRepository(csrfTokenRepository())
.and()
.addFilterAfter(csrfHeaderFilter(), SessionManagementFilter.class); // Register csrf filter.
}
The filter & CsrfToken Repository part:
private Filter csrfHeaderFilter() {
return new OncePerRequestFilter() {
@Override
protected void doFilterInternal(HttpServletRequest request,
HttpServletResponse response,
FilterChain filterChain) throws ServletException, IOException {
CsrfToken csrf = (CsrfToken) request.getAttribute(CsrfToken.class.getName());
if (csrf != null) {
Cookie cookie = WebUtils.getCookie(request, "XSRF-TOKEN");
String token = csrf.getToken();
if (cookie == null || token != null
&& !token.equals(cookie.getValue())) {
// Token is being added to the XSRF-TOKEN cookie.
cookie = new Cookie("XSRF-TOKEN", token);
cookie.setPath("/");
response.addCookie(cookie);
}
}
filterChain.doFilter(request, response);
}
};
}
private CsrfTokenRepository csrfTokenRepository() {
HttpSessionCsrfTokenRepository repository = new HttpSessionCsrfTokenRepository();
repository.setHeaderName("X-XSRF-TOKEN");
return repository;
}
_________________________________________________________________________
Original Question I asked back in Feb 2016
I working on enabeing the Global CORS support for a Spring-boot RESTful API with Spring 4.
I am following the official Spring Boot Doc(
[To see links please register here]
) and have added this to my Application:public class SomeApiApplication {
public static void main(String[] args) {
SpringApplication.run(SomeApiApplication.class, args);
}
//Enable Global CORS support for the application
@Bean
public WebMvcConfigurer corsConfigurer() {
return new WebMvcConfigurerAdapter() {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins("http://localhost:8080")
.allowedMethods("GET", "POST", "PUT", "DELETE", "HEAD")
.allowedHeaders("header1", "header2") //What is this for?
.allowCredentials(true);
}
};
}
}
I don't get why only GET is working, for the rest of http calls, I am getting an error message saying "Invalid CORS request". Do I miss anything in the set up? If my set up is not right, GET should not work as well. I am very confussed.