Shu*_*sky 2 rest grails spring cors
在我的应用程序中,我使用grails-spring-security-rest插件,我目前正处于构建身份验证流程的阶段.
如果我使用休息客户端,一切都按预期工作:我可以通过在json中发布用户名和密码登录并获取令牌.完善!
现在,我正在尝试将整个内容与Web表单集成,当然,浏览器会发送预检OPTIONS请求.
我有一个简单的拦截器设置:
@GrailsCompileStatic
class CorsInterceptor {
int order = HIGHEST_PRECEDENCE
CorsInterceptor() {
matchAll() // match all controllers
//.excludes(controller:"login") // uncomment to add exclusion
}
boolean before() {
String origin = request.getHeader("Origin");
boolean options = "OPTIONS".equals(request.getMethod());
if (options) {
if (origin == null) return;
response.addHeader("Access-Control-Allow-Headers", "origin, authorization, accept, content-type, x-requested-with");
response.addHeader("Access-Control-Allow-Methods", "GET, HEAD, POST, PUT, DELETE, TRACE, OPTIONS");
response.addHeader("Access-Control-Max-Age", "3600");
}
response.addHeader("Access-Control-Allow-Origin", origin == null ? "*" : origin);
response.addHeader("Access-Control-Allow-Credentials", "true");
true // proceed to controller
}
boolean after() { true }
void afterView() {
// no-op
}
}
Run Code Online (Sandbox Code Playgroud)
拦截器完美地获得了有效的get请求,并将标头添加到响应中.但是,当我试图发送这个:
curl -X "OPTIONS" "http://localhost:8080/api/login" \
-H "Origin: http://localhost:3000" \
-H "Content-Type: application/json" \
-d "{\"username\":\"customer\",\"password\":\"password\"}"
Run Code Online (Sandbox Code Playgroud)
我总是405 Method Not Allowed回来,执行甚至根本没有拦截器.
我的假设是插件提供的登录控制器不允许这样做,我需要添加一个额外的URL映射来克服这个问题.我的问题是,这个映射支持看起来像什么?
此外,可以设置适用于所有OPTIONS请求的映射,因此我不需要逐个指定它们?
鉴于这一切,这只是我的假设......我是否正朝着正确的方向前进?
谢谢,
许多其他用户也面临这个问题,并且在github和slack频道上反复询问.我已经创建了一个示例示例,它在src /目录下有CORS过滤器,我已将其注册为spring bean.这是带有示例应用程序的github repo.Cors过滤器代码如下
@Priority(Integer.MIN_VALUE)
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);
}
}
Run Code Online (Sandbox Code Playgroud)
在resources.groovy文件中将其注册为spring bean,如下所示:
beans = {
corsFilter(CorsFilter)
}
Run Code Online (Sandbox Code Playgroud)
这是关于这个插件的github repo的问题.
更新 Grails3 CORS拦截器插件已更新,包括SpringSecurityCorsFilter.有关如何使用的详细信息,请参阅此示例
这个插件比我上面写的servlet过滤器要好得多.