I would like to do cross origin communication using Grails in server side. The only documentation that I found is this one
https://grails.org/plugin/cors
but this is for an old version of Grails. The other documentation that I found is for spring:
https://spring.io/guides/gs/rest-service-cors/
so I added the file SimpleCorsFilter.groovy
to init/myproject/
folder, but I don't know how to wire this component into resources.groovy
So, if you got here using grails 3.2.+ you can use the default way.
Go to your application.yml
and add:
grails:
cors:
enabled: true
It will add Access-Control-Allow-Origin '*'
.
If you want something different, look this page
We used a normal servlet filter with an entry in resources.groovy to solve this problem:
public class CorsFilter extends OncePerRequestFilter {
@Override
protected void doFilterInternal(HttpServletRequest req, HttpServletResponse resp, FilterChain chain)
throws ServletException, IOException {
String origin = req.getHeader("Origin");
boolean options = "OPTIONS".equals(req.getMethod());
if (options) {
if (origin == null) return;
resp.addHeader("Access-Control-Allow-Headers", "origin, authorization, accept, content-type, x-requested-with");
resp.addHeader("Access-Control-Allow-Methods", "GET, HEAD, POST, PUT, DELETE, TRACE, OPTIONS");
resp.addHeader("Access-Control-Max-Age", "3600");
}
resp.addHeader("Access-Control-Allow-Origin", origin == null ? "*" : origin);
resp.addHeader("Access-Control-Allow-Credentials", "true");
if (!options) chain.doFilter(req, resp);
}
}
resources.groovy:
beans = {
corsFilter(CorsFilter)
}
This works with CORS requests using basic authentication. I wrote the Grails 2.x plugin and this seemed easier than getting it to work with Grails 3.
To be specific, here is some code that works. Notice the interceptor name must match your controller name (here, workRequest), the domain needs to be whatever you are calling from (here, localhost:8081) and it is the before() method you want:
package rest
class WorkRequestInterceptor {
boolean before() {
header( "Access-Control-Allow-Origin", "http://localhost:8081" )
header( "Access-Control-Allow-Credentials", "true" )
header( "Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE" )
header( "Access-Control-Max-Age", "3600" )
true
}
boolean after() { true }
}
I was playing around with the emberjs framework together with a Grails 3.0 rest application when I was hit by the CORS issue. Following the steps in this article http://www.greggbolinger.com/rendering-json-in-grails-for-ember-js/ helped me get further.
The article shows how you can use the new Interceptors to create a CorsInterceptor class which sets the correct headers.
class CorsInterceptor {
CorsInterceptor() {
matchAll()
}
boolean before() {
header( "Access-Control-Allow-Origin", "http://localhost:4200" )
header( "Access-Control-Allow-Credentials", "true" )
header( "Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE")
header( "Access-Control-Max-Age", "3600" )
true
}
boolean after() { true }
}
This worked as expected for GET requests, but failed for POST and PUT requests. The reason for this was that an OPTIONS preflight request was sent first to http://localhost:8080/mycontroller/1234, which in my case caused a 404 not found to be returned.
With the help from this answer https://stackoverflow.com/a/31834551 I modified the CorsInterceptor class to this instead:
class CorsInterceptor {
CorsInterceptor() {
matchAll()
}
boolean before() {
header( "Access-Control-Allow-Origin", "http://localhost:4200" )
boolean options = ("OPTIONS" == request.method)
if (options) {
header( "Access-Control-Allow-Origin", "http://localhost:4200" )
header( "Access-Control-Allow-Credentials", "true" )
header( "Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE")
header( "Access-Control-Max-Age", "3600" )
response.status = 200
}
true
}
boolean after() { true }
}
Now POST and PUT requests were working.
You should use grails 3's new Interceptor API. (https://grails.github.io/grails-doc/3.0.x/guide/single.html#interceptors)
You can create an interceptor with the grails create-interceptor
command. For a CORS Interceptor I would use the after()
method of this Interceptor, and set it up to match all requests (or just the requests you need). You can use the response
object in this method, so setting the headers should be similar to the case described in the Spring documentation.
The cleanest and simplest solution for grails 3.1.x I found is to add the Apache default CorsFilter:
import org.apache.catalina.filters.CorsFilter
// Place your Spring DSL code here
beans = {
corsFilter(CorsFilter) //Custom CorsFilter under src/main/java/ works as well. I prefer Apache though...
}
The answer from #user215556 works as well but the default setting of the Apache Cors filter is ok as well
If you need to enable CORS for endpoints provided by the Spring Security core/rest plugins you have to add this:
Bootstrap.groovy:
SpringSecurityUtils.clientRegisterFilter("corsFilter",
SecurityFilterPosition.SECURITY_CONTEXT_FILTER.order - 1)
resources.groovy:
beans = {
corsFilter(CorsFilter)
}
来源:https://stackoverflow.com/questions/29584164/how-to-enable-cors-in-grails-3-0-1