使用 Grails 3 和 Spring Security REST 配置 CORS
Posted
技术标签:
【中文标题】使用 Grails 3 和 Spring Security REST 配置 CORS【英文标题】:Configuring CORS with Grails 3 and Spring Security REST 【发布时间】:2017-02-16 04:03:06 【问题描述】:我正在尝试弄清楚如何将 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 似乎没有到达那里,我不知道为什么。有什么想法吗?
【问题讨论】:
嘿! Grails 3.2.1 刚刚发布。它内置了 CORS docs.grails.org/latest/guide/introduction.html#whatsNewCors 【参考方案1】:更新
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 core/rest 插件提供的端点,因为它们的拦截器的优先级高于 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
【讨论】:
在哪里添加最后一行注册过滤器? 糟糕!对不起。添加到Bootstrap.groovy
@ShashankAgrawal 我正在使用 Grails 3.2.7 我按照在 application.yml 中使用 grails 3 启用 CORS 的步骤。我试图允许 OPTIONS 方法与任何请求方法一起传递。但是通过简单地启用 cors,我无法实现它。你能详细说明一下吗?
您不必允许 OPTIONS 方法,因为这是用于飞行前请求检查是否允许 CORS 的方法【参考方案2】:
使用最新版本的 Grails 3,如果您在本地运行应用程序,您只需启用 CORS grails run-app
。我的版本是Grails Version: 3.3.10
。
时髦的grails.cors.enabled=true
【讨论】:
以上是关于使用 Grails 3 和 Spring Security REST 配置 CORS的主要内容,如果未能解决你的问题,请参考以下文章
grails acegi 迁移到 spring-security-core
使用 Grails 3 和 Spring Security REST 配置 CORS
如何使用 grails 1.3.2 和插件 spring-security-core 1 实现自定义 FilterSecurityInterceptor?