Reputation: 4352
I need to enable CORS for Spring
application that uses Spring Security
and it is not working. I am making GET
request from http://localhost:3000
(which is node.js server) to http://localhost:8080
(which is Tomcat server).
I tried the following approaches but can not make any of them work: https://spring.io/blog/2015/06/08/cors-support-in-spring-framework
https://gist.github.com/zeroows/80bbe076d15cb8a4f0ad
Enabling CORS using Spring Boot 1.3.3-RELEASE
Spring CORS controller annotation not working
Currently I have a @Controller
:
@Controller
@RequestMapping("/views")
public class LoginController{
@Autowired
private EventService eventService;
@RequestMapping(value = "/companies", method = RequestMethod.GET, produces = "application/json")
@ResponseBody
public String listCompanies(Model model) {
String companiesList = eventService.getCompanies();
return companiesList;
}
}
And AppConfig
file where I have been unsuccessfully trying to allow CORS
:
@EnableWebMvc
@Configuration
public class AppConfig extends WebMvcConfigurerAdapter {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**");
}
}
I want to somehow get the json
from the listCompanies
method in my Angular2
app. I am getting No 'Access-Control-Allow-Origin' header is present
error, so I suppose it is CORS
issue.
Upvotes: 0
Views: 3232
Reputation: 225
import java.io.IOException;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.web.filter.OncePerRequestFilter;
/**
* Enabling CORS support - Access-Control-Allow-Origin
*
*
* <code>
<!-- Add this to your web.xml to enable "CORS" -->
<filter>
<filter-name>cors</filter-name>
<filter-class>com.elm.mb.rest.filters.CORSFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>cors</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
* </code>
*/
public class CORSFilter extends OncePerRequestFilter {
private static final Log LOG = LogFactory.getLog(CORSFilter.class);
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
response.addHeader("Access-Control-Allow-Origin", "*");
if (request.getHeader("Access-Control-Request-Method") != null && "OPTIONS".equals(request.getMethod())) {
LOG.trace("Sending Header....");
// CORS "pre-flight" request
response.addHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE");
// response.addHeader("Access-Control-Allow-Headers", "Authorization");
response.addHeader("Access-Control-Allow-Headers", "Content-Type");
response.addHeader("Access-Control-Max-Age", "1");
}
filterChain.doFilter(request, response);
}
}
Upvotes: 0
Reputation: 2232
I had similar problem and fixed it with custom filter as described in documentation: 27.5 Filter based CORS support
Basically, you need to create filter:
public class MyCorsFilter extends CorsFilter {
public MyCorsFilter() {
super(configurationSource());
}
private static UrlBasedCorsConfigurationSource configurationSource() {
CorsConfiguration config = new CorsConfiguration();
config.addAllowedOrigin("*");
config.addAllowedMethod("*");
config.addAllowedHeader("*");
config.setAllowCredentials(true);
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", config);
return source;
}
}
and then add it in web.xml (or corresponding java based config) before springSecurityFilterChain
like this:
<filter>
<filter-name>corsFilter</filter-name>
<filter-class>com.example.configuration.cors.MyCorsFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>corsFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
I also have dispatchOptionsRequest
(which is not necessary according to the new documentation):
<servlet>
<servlet-name>appServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
...
<!-- "OPTIONS" method support -->
<init-param>
<param-name>dispatchOptionsRequest</param-name>
<param-value>true</param-value>
</init-param>
...
</servlet>
Upvotes: 1
Reputation: 286
Did you defined somewhere the allowed origines in spring configuration? http://localhost:8080
@EnableWebMvc
@Configuration
public class AppConfig extends WebMvcConfigurerAdapter {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins("http://localhost:3000")
.allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS")
.allowCredentials(true);
}
}
Look at chapter 27.3 of official docs to enable global CORS configuration : http://docs.spring.io/spring/docs/current/spring-framework-reference/html/cors.html
If you don't need to include cookies on cross-origin request, replace .allowCredentials(true)
by .allowCredentials(false)
Upvotes: 0