405方法在带有grails-spring-security-rest插件的/ api / login OPTIONS请求上不被允许(战斗仍在继续...) [英] 405 Method Not Allowed on /api/login OPTIONS request with grails-spring-security-rest plugin (and the fight continues...)

查看:130
本文介绍了405方法在带有grails-spring-security-rest插件的/ api / login OPTIONS请求上不被允许(战斗仍在继续...)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我的应用中,我使用的是grails-spring-security-rest插件,目前正处于构建身份验证流程的阶段。

In my app, I am using grails-spring-security-rest plugin and I am currently at the stage of building authentication flow.

如果我使用其余的客户一切正常:我可以通过输入用户名& json中输入密码并返回令牌。完美!

If I use a rest client everything works as expected: I am able to login by posting username & password in json and get tokens back. Perfect!

现在,我正在尝试将整个内容与Web表单集成在一起,当然,浏览器会发送预检 OPTIONS 请求。

Now, I am trying to integrate this whole thing with the web form and, of course, the browser sends preflight OPTIONS request.

我有一个简单的拦截器设置:

I have a simple interceptor setup:

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

}

拦截器的工作原理非常完美,可以有效地获取有效的get请求并将标头添加到响应中。但是,当我尝试使用以下方法时:

The interceptor works perfectly got valid get requests and adds the headers into the response. However, when I am trying to senf this:

curl -X "OPTIONS" "http://localhost:8080/api/login" \
    -H "Origin: http://localhost:3000" \
    -H "Content-Type: application/json" \
    -d "{\"username\":\"customer\",\"password\":\"password\"}"

我总是收到 405不允许的方法,执行甚至根本没有到拦截器。

I am always getting 405 Method Not Allowed back and the execution is not even getting to interceptor at all.

我的假设是插件提供的登录控制器不允许这样做,因此我需要添加一个附加的URL映射来解决此问题。我的问题是,此映射支持的外观如何?

My assumption is that the login controller provided by the plugin is not allowing that, and I need to put an additional URL mapping to overcome this problem. My problem is, what this mapping support to look like?

此外,可以设置适用于所有OPTIONS请求的映射,因此我无需指定他们一个一个地?

Also, it is possible to setup mapping that will work for all OPTIONS requests, so I don' need to specify them one by one?

给出所有这些,这只是我的假设……我是否朝着正确的方向前进?

Given all that, it is only my assumption... Am I even in the right direction with it?

谢谢

推荐答案

这个问题也被许多其他用户所面对,并在github上被反复询问。和松弛的渠道。我创建了一个示例示例,该示例在src /目录下具有CORS过滤器,并将其注册为spring bean。 此处是带有示例应用程序的github回购。 Cors过滤器代码如下

this problem was faced by many other users as well and was repeatedly asked on github and slack channels. I've created a sample example which has CORS filter in under src/ directory and I've registered it as spring bean. Here is github repo with example app. The Cors filter code is below

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

将此文件注册为resources.groovy文件中的spring bean下方:

Register this as spring bean in resources.groovy file as below:

beans = {
    corsFilter(CorsFilter)
}

这是在此插件的github存储库上问的问题。

Here is the question asked on github repo of this plugin.

更新
Grails3 CORS拦截器插件已更新为包括SpringSecurityCorsFilter。有关使用方法的详细信息,请参阅此示例

Update Grails3 CORS interceptor plugin has been update to include SpringSecurityCorsFilter. For details of how to use, refer to this sample

此插件比我上面编写的servlet过滤器好得多。

This plugin is much better than the servlet filter I've written above.

这篇关于405方法在带有grails-spring-security-rest插件的/ api / login OPTIONS请求上不被允许(战斗仍在继续...)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆