23

Do you have any idea how I can use, an access_token generated by the default asp.net web api 2 OAuth 2 authorization mechanism, in the url parameters. Currently I am able to authorize successfully by sending a request with Authorization header like this:

Accept: application/json
Content-Type: application/json
Authorization: Bearer pADKsjwMv927u...

What I want is to enable the authorization through URL parameter like this:

https://www.domain.com/api/MyController?access_token=pADKsjwMv927u...
mynkow
  • 4,408
  • 4
  • 38
  • 65
  • I have edited your title. Please see, "[Should questions include “tags” in their titles?](http://meta.stackexchange.com/questions/19190/)", where the consensus is "no, they should not". – John Saunders Feb 01 '14 at 23:07
  • OK, this is new for me. – mynkow Feb 01 '14 at 23:36

3 Answers3

24

Well - I agree that the header is a much better alternative - but there are of course situations where the query string is needed. The OAuth2 spec defines it as well.

Anyways - this feature is built into the Katana OAuth2 middleware:

http://leastprivilege.com/2013/10/31/retrieving-bearer-tokens-from-alternative-locations-in-katanaowin/

public class QueryStringOAuthBearerProvider : OAuthBearerAuthenticationProvider
{
    readonly string _name;

    public QueryStringOAuthBearerProvider(string name)
    {
        _name = name;
    }

    public override Task RequestToken(OAuthRequestTokenContext context)
    {
        var value = context.Request.Query.Get(_name);

        if (!string.IsNullOrEmpty(value))
        {
            context.Token = value;
        }

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

And then:

var options = new JwtBearerAuthenticationOptions
{
    AllowedAudiences = new[] { audience },
    IssuerSecurityTokenProviders = new[]
        {
            new SymmetricKeyIssuerSecurityTokenProvider(
                issuer,
                signingKey)
        },
    Provider = new QueryStringOAuthBearerProvider(“access_token”)
};
mynkow
  • 4,408
  • 4
  • 38
  • 65
leastprivilege
  • 18,196
  • 1
  • 34
  • 50
  • 1
    Nice, much better. Can you please copy and paste the relevant code from the blog post you mentioned so I can mark your response as answer. 10x – mynkow Feb 01 '14 at 22:19
11

So, go to Global.asax and add this method:

        void Application_BeginRequest(object sender, EventArgs e)
        {
            if (ReferenceEquals(null, HttpContext.Current.Request.Headers["Authorization"]))
            {
                var token = HttpContext.Current.Request.Params["access_token"];
                if (!String.IsNullOrEmpty(token))
                {
                    HttpContext.Current.Request.Headers.Add("Authorization", "Bearer " + token);
                }
            }
        }

UPDATE: Check out @leastprivilege answer. Much better solution.

mynkow
  • 4,408
  • 4
  • 38
  • 65
0

This is a terrible idea because the token is not protected in the query string. It is encrypted in the header with SSL.

0leg
  • 966
  • 5
  • 9
  • 7
    Actually, query string parameters are protected under SSL. http://stackoverflow.com/questions/323200/is-an-https-query-string-secure – Eugenio Pace Jan 31 '14 at 18:10
  • Yes, and github api also supports authentication using this method => http://developer.github.com/v3/#authentication – mynkow Feb 01 '14 at 22:16
  • 5
    I wonder how such a wrong answer can be accepted. Apparently the person that posted this doesn't quite understand how HTTP and SSL work. The token is as much protected in the query string as it is in the HTTP headers. This being said, in general it is better to use the HTTP headers for sending sensitive information instead of query strings to avoid it being logged by web servers. – Darin Dimitrov Feb 01 '14 at 22:41
  • You are right Darine, I do not understand how this works. But you are also wrong because as you can see @leastprivilege will be marked as answer... anyway. – mynkow Feb 01 '14 at 23:39