具有OWIN中间件和基于令牌的身份验证的WebAPI 2:OPTIONS请求返回“unsupported_grant_type”错误

时间:2014-09-11 18:16:12

标签: authentication oauth options

WEbAPI为身份验证请求提供端点:http:\ ... \ token

应使用方法“POST”和Body like

发送身份验证请求
"grant_type=password&username=name&password=mypassword"

前端使用此WebAPI,它是使用AngularJS编写的。 有时在发送带有有效Body的“POST”请求之前,会发送一个没有Body的“OPTIONS”请求。 结果,WebAPI返回以下错误:

Status: 400
{"error":"unsupported_grant_type"}

有没有可以在服务器端实现的解决方案? (在WebAPI中)

HTTP请求方法:选项

Request Header:
Accept:*/*
Accept-Encoding:gzip,deflate,sdch
Accept-Language:en-US,en;q=0.8,de;q=0.6,ru;q=0.4,uk;q=0.2
Access-Control-Request-Headers:accept, authorization, content-type
Access-Control-Request-Method:POST
Cache-Control:no-cache
Host:...
Origin:...
Pragma:no-cache
Proxy-Connection:keep-alive
Referer:...
User-Agent:Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/37.0.2062.120 Safari/537.36

Response Header:
Cache-Control: no-cache
Pragma: no-cache
Content-Length: 34
Content-Type: application/json;charset=UTF-8
Expires: -1
Server: Microsoft-IIS/7.5
Access-Control-Allow-Origin: *
X-Powered-By: ASP.NET
Date: Thu, 11 Sep 2014 18:05:09 GMT

4 个答案:

答案 0 :(得分:17)

我刚遇到同样的问题......我正在使用ember和ember-simple-auth。对/ token端点的任何预检请求OPTIONS都会产生400 HTTP响应,并且正文已众所周知:{error:“unsuported_grant_type”}。

<强> SOLUTION:

我继承自:OAuthAuthorizationServerProvider并覆盖MatchEndpoint函数:

public override Task MatchEndpoint(OAuthMatchEndpointContext context)
    {
        if (context.OwinContext.Request.Method == "OPTIONS" && context.IsTokenEndpoint)
        {
            context.OwinContext.Response.Headers.Add("Access-Control-Allow-Methods", new[] {"POST"});
            context.OwinContext.Response.Headers.Add("Access-Control-Allow-Headers", new[] { "accept", "authorization", "content-type" });
            context.OwinContext.Response.Headers.Add("Access-Control-Allow-Origin", new[] { "*" });
            context.OwinContext.Response.StatusCode = 200;
            context.RequestCompleted();

            return Task.FromResult<object>(null);
        }

        return base.MatchEndpoint(context);        }

这似乎照顾它。希望它有所帮助。

答案 1 :(得分:5)

当我忘记将Content-Type: application/x-www-form-urlencoded添加到请求标头时,我收到了同样的错误。

答案 2 :(得分:2)

在这种情况下, OPTIONS 是一个CORS预检请求。发送它是为了确定实际请求(POST)是否可以安全发送。如果使用GETHEADPOST以外的方法或设置自定义标头,则会预先确定跨站点请求。

为了避免400 HTTP响应,在Startup类中,您应该使用UseCors扩展方法为OWIN中间件启用CORS并定义自定义System.Web.Cors.CorsPolicy

using Microsoft.Owin.Cors;
using Microsoft.Owin.Security.OAuth;
using Owin;

namespace AuthorizationServer
{
    public partial class Startup
    {
        public void ConfigureAuth(IAppBuilder app)
        {
            app.UseCors(CorsOptions.AllowAll);

            app.UseOAuthAuthorizationServer(new OAuthAuthorizationServerOptions()
            {     

            });
        }
    }
}

答案 3 :(得分:1)

我试图用Fiddler测试我的api,并且没有在Request Body部分提供正确格式的数据。请确保将其添加为由&#39;&amp;&#39;分隔的键值列表。

grant_type=password&username=testUsername&password=testPassword