使用Grails 3和Spring Security REST配置CORS

时间:2016-10-07 08:05:48

标签: rest grails spring-security cors

我正在试图弄清楚如何将Angular 2前端(在localhost:4200上运行)插入Grails 3后端(在localhost:8080上运行),因此我需要在grails应用程序中启用CORS支持。

我发现这个Github项目(https://github.com/appcela/grails3-cors-interceptor-spring-security-rest-sample-app)显示了如何使用grails3-cors-interceptor插件启用CORS。我正在运行这个应用程序作为测试后端,我在CorsService.processPreflight()中放置一个断点来检查它何时被调用。当我在/api/books上进行GET时,浏览器首先发送一个通过断点的OPTIONS调用,但是下面的GET似乎没有去那里,我无法弄清楚原因。有什么想法吗?

2 个答案:

答案 0 :(得分:13)

更新

Grails 3.2.1具有支持CORS的内置功能。看看http://docs.grails.org/latest/guide/theWebLayer.html#cors

只需在application.yml中添加此内容即可启用

grails:
    cors:
        enabled: true

(确保查找要启用CORS的环境)

原帖

您不需要插件(除非您想使用该插件)在此处启用CORS。那么,对于您的休息端点,您始终可以使用Grails拦截器启用CORS,如下所示:

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 }
}

但Grails拦截器无法拦截Spring Security核心/静态插件提供的端点,因为拦截器的优先级高于Grails拦截器的优先级。因此,您首先需要添加一个客户过滤器,然后在Spring相关过滤器之前注册它。

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)
        }
    }
}

resources.groovy

上注册
beans = {
    corsFilterFoo(CorsFilter)
}

现在,在安全上下文过滤器之前将其添加到Spring的过滤器链中(在Bootstrap.groovy中):

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

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

答案 1 :(得分:2)

使用最新版本的Grails 3,如果您在本地grails run-app上运行应用程序,则只需启用CORS。我的版本是Grails Version: 3.3.10。 Groovy grails.cors.enabled=true