How to use OAuth2 ResourceServer with WebApi?

1,058 views
Skip to first unread message

Brad Laney

unread,
Jul 26, 2012, 6:47:57 PM7/26/12
to dotnet...@googlegroups.com
This is the part I'm battling with:

resourceServer.GetPrincipal(HttpRequestMessageBase, Uri, string[]);

WebApi exposes HttpRequestMessage, not HttpRequestMessageBase.

public class OAuthTokenAuthenticationOperationHandler : OrderedFilterAttribute
{
public override void OnActionExecuting(System.Web.Http.Controllers.HttpActionContext actionContext)
{
actionContext.Request // problem
}
}

Andrew Arnott

unread,
Jul 26, 2012, 9:34:47 PM7/26/12
to dotnet...@googlegroups.com
I'm having a hard time understanding the problem.  Is there some API you'd like to pass your HttpRequestMessage to but the API only takes  HttpRequestMessageBase ?  If so, which API is it?
--
You received this message because you are subscribed to the Google Groups "DotNetOpenAuth" group.
To view this discussion on the web visit https://groups.google.com/d/msg/dotnetopenid/-/7pbFsPI1c1AJ.
To post to this group, send email to dotnet...@googlegroups.com.
To unsubscribe from this group, send email to dotnetopenid...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/dotnetopenid?hl=en.


--
--
Andrew Arnott
"I [may] not agree with what you have to say, but I'll defend to the death your right to say it." - S. G. Tallentyre

Ryan Rousseau

unread,
Jul 26, 2012, 10:58:24 PM7/26/12
to dotnet...@googlegroups.com
Brad - I've got some code I can share with you tomorrow. I can't remember exactly what I did but I think I created a HttpRequestMessageBase and set the values from the HttpRequestMessage. 

Brad Laney

unread,
Jul 27, 2012, 1:40:50 AM7/27/12
to dotnet...@googlegroups.com
The problem is that the ResourceServer class, which is used for validating the request, takes in an HttpRequestMessageBase.

WebApi, through filters (which is where you would put authentication for requests) exposes only an HttpRequest object, not an HttpRequestMessage or an HttpRequestMessageBase

I'm talking about code, from the resource server example in oauth2, the class is the AuthenticationManager class or something like that. It's the only class with the word manager in it :P

I'll keep an eye out for your post tomorrow ryan, but that sort of sounds dangerous >_<. I hate relying on manually constructing request classes like that.

Andrew: The main problem is that the method for validating the request does not take in an HttpRequest. It only accepts HttpRequestMessageBase and HttpRequestMessageProperty

Ryan Rousseau

unread,
Jul 27, 2012, 8:07:52 AM7/27/12
to dotnet...@googlegroups.com
It's actually in the gist for my webapi filter - https://gist.github.com/2972742

The part you'd be interested in is:

// TODO FIXME dnoa doesn't support HttpRequestMessage - manually creating HttpRequestMessageProperty until they do
var request = new HttpRequestMessageProperty();
request.Headers[HttpRequestHeader.Authorization] = actionContext.Request.Headers.Authorization.ToString();
var requestUri = actionContext.Request.RequestUri;

It's not ideal, but I don't think it's too bad until support for HttpRequestMessage is added.

Aleksander Heintz

unread,
Jul 27, 2012, 9:03:40 AM7/27/12
to dotnet...@googlegroups.com
I'm doing something of the same (by the way, I have OAuth2 resource server working seamingly perfectly with web api, I'll share the code when it's a bit less coupled to the tests I'm currently running). I used the sources found https://github.com/DavidChristiansen/DotNetOpenAuth.WebAPI.40 here. He uses an even dirtier trick though. He just wraps HttpContext.Current.Request in a HttpRequestBaseWrapper (or whatever it's called), but it works, and for now get's the job done.

Brad Laney

unread,
Jul 27, 2012, 11:30:59 AM7/27/12
to dotnet...@googlegroups.com
That is VERY confusing. Because the example does not use the authorization header, it uses NAME.

var operationMessage = OperationContext.Current.RequestContext.RequestMessage.Properties[HttpRequestMessageProperty.Name] as HttpRequestMessageProperty;

Is that because WCF changes it to name? I guess I'll try the code and hope that it works in all situations.

It would be real nice to hear that support for more objects in the immediate future!

Aleksander Heintz

unread,
Jul 27, 2012, 12:18:25 PM7/27/12
to dotnet...@googlegroups.com
Wait, where did you take that from?
Anyways; this is basically what you need: https://github.com/DavidChristiansen/DotNetOpenAuth.WebAPI.40/blob/master/source/DotNetOpenAuth.WebAPI/AuthenticationConfiguration.cs (plus referenced classes, there are 2 or thee more you need to get it working).

Brad Laney

unread,
Jul 27, 2012, 3:52:24 PM7/27/12
to dotnet...@googlegroups.com
I took that from their oauth2 WCF resource server sample...

On Fri, Jul 27, 2012 at 11:18 AM, Aleksander Heintz <alx...@alxandr.me> wrote:
Wait, where did you take that from?
Anyways; this is basically what you need: https://github.com/DavidChristiansen/DotNetOpenAuth.WebAPI.40/blob/master/source/DotNetOpenAuth.WebAPI/AuthenticationConfiguration.cs (plus referenced classes, there are 2 or thee more you need to get it working).

--
You received this message because you are subscribed to the Google Groups "DotNetOpenAuth" group.
To view this discussion on the web visit https://groups.google.com/d/msg/dotnetopenid/-/7DAx-m6gd34J.

Brad Laney

unread,
Jul 27, 2012, 3:59:57 PM7/27/12
to dotnet...@googlegroups.com
It's because it's using SOAP, not a big deal.

Brad Laney

unread,
Jul 27, 2012, 4:10:28 PM7/27/12
to dotnet...@googlegroups.com
Okay so I put that into use. But I had to change it from a delegating handler because I need to access the scopes from the AuthorizeAttribute on the actions. My scopes are access types. "public", "admin", etc.

Aleksander Heintz

unread,
Jul 28, 2012, 5:49:49 AM7/28/12
to dotnet...@googlegroups.com
That works as is with the code. I use a DelegatingHandler and I still use [Authorize(Roles="users")] no problem (the scopes are treated as roles).

Andrew Arnott

unread,
Jul 28, 2012, 9:41:24 AM7/28/12
to dotnet...@googlegroups.com
I'm not sure where the idea that DNOA doesn't support this is coming from.  It sounds like the only limitations I'm really hearing are in the samples themselves, which shouldn't be construed as lack of support for other scenarios in the library itself.

Brad said:
 The problem is that the ResourceServer class, which is used for validating the request, takes in an HttpRequestMessageBase.
 
Actually, ResourceServer has two overloads: one takes HttpRequestBase and the other takes HttpRequestMessageProperty.  Everything is representable as an HttpRequestBase, so this should cover every scenario.
 
WebApi, through filters (which is where you would put authentication for requests) exposes only an HttpRequest object, not an HttpRequestMessage or an HttpRequestMessageBase

There are several APIs in ASP.NET that deal in HttpRequest types, and this is very easy to turn into an HttpRequestBase instance: just wrap it with a HttpRequestWrapper, as the constructor for HttpRequestWrapper takes an HttpRequest.  That's the class's express purpose.
 
I'm talking about code, from the resource server example in oauth2, the class is the AuthenticationManager class or something like that. It's the only class with the word manager in it :P

It sounds like you're referring to the sample's OAuthAuthorizationManager class.  And yes, that's written for WCF -- not WebAPI.  I'm not yet familiar with WebAPI so another approach sounds appropriate and could be considered fully supported.  See further below.

Andrew: The main problem is that the method for validating the request does not take in an HttpRequest. It only accepts HttpRequestMessageBase and HttpRequestMessageProperty

I suspect you meant HttpRequestBase and HttpRequestMessageProperty.  And as I said above, HttpRequest is trivially convertable to HttpRequestBase.

Alek said:
I'm doing something of the same (by the way, I have OAuth2 resource server working seamingly perfectly with web api, I'll share the code when it's a bit less coupled to the tests I'm currently running). I used the sources found https://github.com/DavidChristiansen/DotNetOpenAuth.WebAPI.40 here. He uses an even dirtier trick though. He just wraps HttpContext.Current.Request in a HttpRequestBaseWrapper (or whatever it's called), but it works, and for now get's the job done. 

I haven't studied David's sample yet, but as I state above, HttpRequestWrapper is not a dirty trick.  It's the official Microsoft-supplied way of converting HttpRequest into an HttpRequestBase.
 
I hope this helps.

--
Andrew Arnott
"I [may] not agree with what you have to say, but I'll defend to the death your right to say it." - S. G. Tallentyre


On Sat, Jul 28, 2012 at 2:49 AM, Aleksander Heintz <alx...@alxandr.me> wrote:
That works as is with the code. I use a DelegatingHandler and I still use [Authorize(Roles="users")] no problem (the scopes are treated as roles).

--
You received this message because you are subscribed to the Google Groups "DotNetOpenAuth" group.
To view this discussion on the web visit https://groups.google.com/d/msg/dotnetopenid/-/kanPdJ_S0WcJ.

Aleksander Heintz

unread,
Jul 28, 2012, 11:02:33 AM7/28/12
to dotnet...@googlegroups.com
I think you've misunderstood something (or I have). The problem is that there is introduced a new Request-class in Web API named System.Net.Http.HttpRequestMessage. It has (next to) nothing in common with the regular HttpRequest. For instance, as far as I can tell, HttpRequestMessage does not parse form-data, and almost all of the methods exposed on the object is async only.

Oh, and as a side-node; I do not think HttpRequestWrapper is a dirty trick; I think using the ThreadStatic property HttpContext.Current is. Also, using ThreadStatic properties in an async method makes my hair tingle, and not in a good way...

Andrew Arnott

unread,
Jul 28, 2012, 12:18:25 PM7/28/12
to dotnet...@googlegroups.com
Alek,

In reviewing the docs for HttpRequestMessage, I don't see any way to access the POST entity at all, parsed or not.  Am I missing something?

--
Andrew Arnott
"I [may] not agree with what you have to say, but I'll defend to the death your right to say it." - S. G. Tallentyre


On Sat, Jul 28, 2012 at 8:02 AM, Aleksander Heintz <alx...@alxandr.me> wrote:
I think you've misunderstood something (or I have). The problem is that there is introduced a new Request-class in Web API named System.Net.Http.HttpRequestMessage. It has (next to) nothing in common with the regular HttpRequest. For instance, as far as I can tell, HttpRequestMessage does not parse form-data, and almost all of the methods exposed on the object is async only.

Oh, and as a side-node; I do not think HttpRequestWrapper is a dirty trick; I think using the ThreadStatic property HttpContext.Current is. Also, using ThreadStatic properties in an async method makes my hair tingle, and not in a good way...

--
You received this message because you are subscribed to the Google Groups "DotNetOpenAuth" group.
To view this discussion on the web visit https://groups.google.com/d/msg/dotnetopenid/-/NYYAzusuNUMJ.

Aleksander Heintz

unread,
Jul 28, 2012, 12:24:14 PM7/28/12
to dotnet...@googlegroups.com
It's called Body I think. Oh, and if you'd like a more indepth discussion (on a more efficient medium) I'm avail at rizzoma.

Aleksander Heintz

unread,
Jul 28, 2012, 12:54:17 PM7/28/12
to dotnet...@googlegroups.com
I found this: request.Content.ReadAsFormDataAsync()

Aleksander Heintz

unread,
Jul 28, 2012, 2:24:14 PM7/28/12
to dotnet...@googlegroups.com
So, eh, yeah... Have fun:  https://gist.github.com/3194281

Brad Laney

unread,
Jul 30, 2012, 1:16:57 PM7/30/12
to dotnet...@googlegroups.com
Thanks Aleksander, I'll use that class. Still a bit scary though.
But yeah, that's what I was failing to mention is the HttpRequestMessage class and all the classes in WebApi are completely unrelated to the normal Web or MVC classes.

Brad Laney

unread,
Jul 30, 2012, 1:19:34 PM7/30/12
to dotnet...@googlegroups.com
Unfortunately I won't be able to use async quite yet. Do you know if that will cause a significant problem?


On Saturday, July 28, 2012 1:24:14 PM UTC-5, Aleksander Heintz wrote:

Brad Laney

unread,
Jul 30, 2012, 1:22:45 PM7/30/12
to dotnet...@googlegroups.com
Actually.. what version of webapi release are you using? I am using RC1 and most of the properties you have here don't work. Are they extension methods that you have that I am missing?


On Saturday, July 28, 2012 1:24:14 PM UTC-5, Aleksander Heintz wrote:

Aleksander Heintz

unread,
Jul 30, 2012, 2:17:23 PM7/30/12
to dotnet...@googlegroups.com
Yeah, most of them are extension-methods, but I included the using-statements, so that shouldn't be a problem. Also, it should be fairly easy to rewrite this to not use the async/await-keywords. Just replace any await keywords with continuation-statements like shown below:

// with await
var something = await this.someMethod();
var somethingElse = await something.someOtherMethod();
return somethingElse.value;

// without await
return this.someMethod()
    .ContinueWith(t => t.Result.someOtherMethod()).Unwrap() // takes a Task<Task<TResult>> and returns a Task<TResult>
    .ContinueWith(t => t.Result.value);

If it hasn't been done, I'll probably do it myself when I have time, though right now I'm reading for exams that are due in a couple of weeks... Leaves little time for play-stuff like programming for fun, need to focus on the math <.<

Oh, and btw; I hate math Q.Q

Brad Laney

unread,
Jul 31, 2012, 12:40:25 PM7/31/12
to dotnet...@googlegroups.com
I actually don't have any of those extension methods in my build of RC1

It might be because I'm using the 2010 version of webapi/mvc4? Tough luck on my part! I went the creation of the property route instead.

--
You received this message because you are subscribed to the Google Groups "DotNetOpenAuth" group.
To view this discussion on the web visit https://groups.google.com/d/msg/dotnetopenid/-/O4SOJ8l8ruAJ.

Aleksander Heintz

unread,
Jul 31, 2012, 2:07:35 PM7/31/12
to dotnet...@googlegroups.com
You made sure you hade all the namespaces?
Anyways; I'm using a nightly, but I found those extension-methods on SO, from someone using RC, so I was sure they should be there...
But I'm also using C# 4.5, and that might be the "problem".

Andrew Arnott

unread,
Jul 31, 2012, 2:40:03 PM7/31/12
to dotnet...@googlegroups.com
FWIW, you can using async stuff even if you're targeting .NET 4.0, as presented in Stephen Toub's blog post.
--
You received this message because you are subscribed to the Google Groups "DotNetOpenAuth" group.
To view this discussion on the web visit https://groups.google.com/d/msg/dotnetopenid/-/Nzqildq4yzcJ.

To post to this group, send email to dotnet...@googlegroups.com.
To unsubscribe from this group, send email to dotnetopenid...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/dotnetopenid?hl=en.


--

Andrew Arnott

unread,
Sep 9, 2012, 9:38:07 AM9/9/12
to dotnet...@googlegroups.com
Counting legs in OAuth 2 is old and confusing terminology.  May I translate your question to: "are you using client credentials grant or authorization code grant?"

From the resource server standpoint, it's exactly the same.  The difference in grant types is handled by the authorization server.  Although in your case (which is common) the resource server and authorization server are the same server, what this abstraction gives you is that the fact you're doing WebAPI becomes completely irrelevant to your question, and can therefore find your answer in any previous question of "how do I write an authorization server that uses the authorization code grant?" which is much more general and likely to find an answer for.

In fact, the OAuthAuthorizationServer sample that ships with DNOA demonstrates the authorization code (and implicit) grant types, so you will hopefully find what you need there.  That sample is typically paired with OAuthResourceServer, which uses WCF instead of WebAPI, but as I say above, this is irrelevant.  

I hope this helps,

--
Andrew Arnott
"I [may] not agree with what you have to say, but I'll defend to the death your right to say it." - S. G. Tallentyre


On Sun, Sep 9, 2012 at 1:47 AM, Radenko Zec <logic....@gmail.com> wrote:
Hi Aleksander.
Is this two or three legged implementation OAuth2 ResourceServer with WebApi ?
I am looking for three legged implementation...

Thanks



On Saturday, 28 July 2012 11:24:14 UTC-7, Aleksander Heintz wrote:
So, eh, yeah... Have fun:  https://gist.github.com/3194281

--
You received this message because you are subscribed to the Google Groups "DotNetOpenAuth" group.
To view this discussion on the web visit https://groups.google.com/d/msg/dotnetopenid/-/gH36iDPrsf4J.

Andrew Arnott

unread,
Sep 17, 2012, 12:49:45 PM9/17/12
to dotnet...@googlegroups.com
Cool.  Thanks for sharing!

On Thursday, September 13, 2012, koichia wrote:
Hi,
 
I was able to retrieve HttpRequestBase from HttpRequestMessage by using the method described in the following blog:
 
[How to access HTTPContext from within your Web API action]
 
Basically, you get a HttpContext from HttpRequest.Properties.TryGetValue("MS_HttpContext"). Once you get the HttpContext, you can get HttpRequestBase using HttpContext.Request.
 
 

On Saturday, July 28, 2012 8:02:33 AM UTC-7, Aleksander Heintz wrote:
I think you've misunderstood something (or I have). The problem is that there is introduced a new Request-class in Web API named System.Net.Http.HttpRequestMessage. It has (next to) nothing in common with the regular HttpRequest. For instance, as far as I can tell, HttpRequestMessage does not parse form-data, and almost all of the methods exposed on the object is async only.

Oh, and as a side-node; I do not think HttpRequestWrapper is a dirty trick; I think using the ThreadStatic property HttpContext.Current is. Also, using ThreadStatic properties in an async method makes my hair tingle, and not in a good way...

--
You received this message because you are subscribed to the Google Groups "DotNetOpenAuth" group.
To view this discussion on the web visit https://groups.google.com/d/msg/dotnetopenid/-/xm3uViyCG7QJ.

To post to this group, send email to dotnet...@googlegroups.com.
To unsubscribe from this group, send email to dotnetopenid...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/dotnetopenid?hl=en.


--
Reply all
Reply to author
Forward
0 new messages