Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

WebAPI 2 with OWIN middleware and token-based authentication: OPTIONS request returns "unsupported_grant_type" error

WEbAPI provides end-point for authentication request: http:\...\token

Authentication request should be sent using Method "POST" and Body like

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

This WebAPI is used by Front-End which is written using AngularJS. Sometimes before sending "POST" request with valid Body, a "OPTIONS" request is sent without Body. As result the following error is returned by WebAPI:

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

Is there any solution which can be implemented on Server-side? (in WebAPI)

HTTP Request Method: OPTIONS

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
like image 829
user3653175 Avatar asked Sep 11 '14 18:09

user3653175


1 Answers

I just ran into the same issue..I'm using ember and ember-simple-auth. Any preflight requests OPTIONS to the /token endpoint were resulting in a 400 HTTP response and the body had the well known: {error: "unsuported_grant_type"}.

SOLUTION:

I inherit from: OAuthAuthorizationServerProvider and override the MatchEndpoint function:

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

That seems to take care of it. Hope it helps.

like image 73
Wojciech Wieroński Avatar answered Nov 01 '22 23:11

Wojciech Wieroński