Configuring CORS with Grails 3 and Spring Security REST

Update

Grails 3.2.1 has inbuilt feature to support CORS. Check this out http://docs.grails.org/latest/guide/theWebLayer.html#cors

Just add this in your application.yml to enable it

grails:
    cors:
        enabled: true

(Make sure you look for the environment for which you want to enable CORS)

Original Post

You don't need a plugin (unless you want to use that plugin) to enable CORS here. Well, for your rest endpoints, you can always enable the CORS using the Grails interceptors like below:

class CorsInterceptor {

    CorsInterceptor() {
        matchAll()
    }

    boolean before() {
        if (request.method == "OPTIONS") {
            response.setHeader("Access-Control-Allow-Origin", "http://localhost:4200")
            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.status = 200
        }

        return true
    }

    boolean after() { true }
}

But Grails interceptors cannot intercept the endpoints provided by the Spring Security core/rest plugins since the priority of their interceptors are higher than that of Grails interceptors. So you first need to add a customer filter and then register it before the Spring related filters.

Add a file in src/main/groovy:

package test

import org.springframework.web.filter.OncePerRequestFilter

import javax.servlet.FilterChain
import javax.servlet.ServletException
import javax.servlet.http.HttpServletRequest
import javax.servlet.http.HttpServletResponse

class CorsFilter extends OncePerRequestFilter {

    @Override
    protected void doFilterInternal(HttpServletRequest req, HttpServletResponse resp, FilterChain chain)
            throws ServletException, IOException {

        if (req.getMethod() == "OPTIONS") {
            resp.addHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS")
            resp.addHeader("Access-Control-Max-Age", "3600")
            resp.addHeader("Access-Control-Allow-Origin", "http://localhost:4200")
            resp.addHeader("Access-Control-Allow-Credentials", "true")
            resp.status = 200
        } else {
            chain.doFilter(req, resp)
        }
    }
}

Register it on the resources.groovy:

beans = {
    corsFilterFoo(CorsFilter)
}

Now, add it to the Spring's filter chain before the security context filter (in Bootstrap.groovy):

SpringSecurityUtils.clientRegisterFilter("corsFilterFoo",
    SecurityFilterPosition.SECURITY_CONTEXT_FILTER.order - 1)

References: https://github.com/grails-plugins/grails-spring-security-core/blob/v3.1.1/src/main/groovy/grails/plugin/springsecurity/SpringSecurityUtils.groovy#L698


With the latest version of Grails 3 you just need to enable CORS if your running your applications locally grails run-app. My version is Grails Version: 3.3.10. Groovy grails.cors.enabled=true