【问题标题】:WebAPI 2 with OWIN middleware and token-based authentication: OPTIONS request returns "unsupported_grant_type" error带有 OWIN 中间件和基于令牌的身份验证的 WebAPI 2:OPTIONS 请求返回“unsupported_grant_type”错误
【发布时间】:2014-11-05 19:34:07
【问题描述】:

WEBAPI 为认证请求提供端点:http:\...\token

身份验证请求应使用方法“POST”和 Body like 发送

"grant_type=password&username=name&password=mypassword"

此 WebAPI 由使用 AngularJS 编写的前端使用。 有时在发送带有有效正文的“POST”请求之前,会发送一个没有正文的“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

【问题讨论】:

    标签: authentication oauth options


    【解决方案1】:

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

    解决方案:

    我继承自: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);        }
    

    这似乎解决了它。希望对您有所帮助。

    【讨论】:

    • 问题 - if 语句中的第一行 - 应该是 OwinContext.Response 而不是 OwinContext.Request
    • 它应该是OwinContext.Request,因为您正在询问传入的请求。
    • 为了清楚@WojciechWieroński,您有意在请求中添加一个新标头,在响应中添加两个新标头?
    • @JamesThurley 和 @GaragticCowboy ,复制和粘贴错误......我误解了上一个问题中if 的部分。它应该是Response,向请求中添加任何内容都是无用的,因为它已经到达。我会更新原来的解决方案。
    • 如果您使用 angularjs/jQuery 或类似的 CORS,这可能是您正在寻找的解决方案!
    【解决方案2】:

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

    【讨论】:

      【解决方案3】:

      我试图用 Fiddler 测试我的 api,但没有在请求正文部分以正确的格式提供数据。确保将其添加为以“&”分隔的键值列表。

      grant_type=password&username=testUsername&password=testPassword
      

      【讨论】:

        【解决方案4】:

        在这种情况下,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()
                    {     
        
                    });
                }
            }
        }
        

        【讨论】:

        • 完全同意 Alberto,但这里的问题是实际的 OPTIONS 预检请求(到令牌端点)被拒绝,因为没有为上述内容返回“Access-Control-Allow-Origin”动词。话虽如此,启动时的 CORS 配置显然是所有其他动词的先决条件,并且按预期工作。
        • 补充一点:顺序很重要。 UseCors 应该先走。谢谢你的回答,它帮助我找到了这个。
        • IAppBuilder 没有 UseCors 方法,这是一种配置方法。
        猜你喜欢
        • 2014-12-24
        • 2015-01-14
        • 2020-04-23
        • 2019-03-03
        • 1970-01-01
        • 2015-02-09
        • 2015-07-02
        • 1970-01-01
        • 2020-08-18
        相关资源
        最近更新 更多