Adding OAuth to HttpClient

492 views
Skip to first unread message

Sean Farrow

unread,
Jul 27, 2012, 3:31:56 PM7/27/12
to dotnet...@googlegroups.com

Hi:

Has anybody written a message handler to add Oath to a httpClient request.

Any help appreciated.

Chees

Sean.

Brad Laney

unread,
Jul 27, 2012, 4:03:35 PM7/27/12
to dotnet...@googlegroups.com
I only did bearer... it's not a messagehandler for the client, it just adds the auth header in my base httpclient class


            if (Authorization.AccessTokenExpirationUtc.HasValue)
            {
                if (!Client.RefreshAuthorization(Authorization, TimeSpan.FromSeconds(30)))
                {
                          // redirect to login
                }
            }

client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", Authorization.AccessToken);

Jammer Jamski

unread,
May 1, 2013, 4:26:24 PM5/1/13
to dotnet...@googlegroups.com
How are you applying the client credentials to these requests?  By that I mean the API key and secret?

Andrew Arnott

unread,
May 1, 2013, 9:43:23 PM5/1/13
to dotnetopenid
DotNetOpenAuth v4.3 was recently released and includes the OAuth 1 DelegatingHandlers for use with HttpClient. They apply consumer key & secret and (when applicable) access token & secrets to outbound requests. Please try and let me know how they work for you!

--
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


--
You received this message because you are subscribed to the Google Groups "DotNetOpenAuth" group.
To unsubscribe from this group and stop receiving emails from it, send an email to dotnetopenid...@googlegroups.com.

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

Jammer Jamski

unread,
May 2, 2013, 3:02:19 AM5/2/13
to dotnet...@googlegroups.com
Sorry if this is a ridiculous question I've not looked at the code yet, but I'm using OAuth 2, does this still apply in that case?

Thanks for the re[;y Andrew, much appreciated.  I've been meaning to upgrade for a while now.  Will get that fixed up over the weekend.

Andrew Arnott

unread,
May 5, 2013, 12:55:06 AM5/5/13
to dotnetopenid
It doesn't apply to OAuth 2, because DNOA already offers an OAuth2 DelegatingHandler for HttpClient, as of v4.1.2 or so.

--
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


Jammer Jamski

unread,
May 6, 2013, 3:13:57 AM5/6/13
to dotnet...@googlegroups.com
Ahh, OK.  I need to have a look into this asap as I have been using WebClient so far and it's less that optimal.  Just for the record so others might find this more useful the method on ClientBase is CreateAuthorizingHandler() which creates and returns an instance of BearerTokenHttpMessageHandler.

I'm going to have a closer look at this as applying these credentials to EVERY outbound request might itself be a bit 'sledgehammer to crack a nut' scenario.

Thanks Andrew.

Ton Yeung

unread,
May 6, 2013, 4:25:32 PM5/6/13
to dotnet...@googlegroups.com
Sorry, I'm not sure I understand.
Does this mean that I need to use the webserverclient in order to send out requests? or do I pass the httpclient somewhere in order to get the headers added?

Ton Yeung

unread,
May 6, 2013, 4:34:54 PM5/6/13
to dotnet...@googlegroups.com
Is the referenced test below what I'm supposed to do in order to get my httpclient signed?
https://github.com/AArnott/dotnetopenid/blob/master/src/DotNetOpenAuth.Test/OAuth2/WebServerClientAuthorizeTests.cs#L149


On Friday, July 27, 2012 2:31:56 PM UTC-5, Sean Farrow wrote:

Andrew Arnott

unread,
May 7, 2013, 10:14:07 AM5/7/13
to dotnetopenid
Yes. The WebServerClient or UserAgentClient have this method. Once you have the HttpMessageHandler from the CreateAuthorizingHandler method, you construct an HttpClient, passing in the HttpMessageHandler as an argument to the constructor. Then anything you use that HttpClient for will automatically have the bearer token included.
As Jammer warns though, you should only use this HttpClient instance for those requests for which you want the Bearer token applied.

--
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


--
You received this message because you are subscribed to the Google Groups "DotNetOpenAuth" group.

Jammer Jamski

unread,
May 13, 2013, 6:40:51 PM5/13/13
to dotnet...@googlegroups.com
Hi Ton,

What I actually did is re-write my API client and used the WebServerClient as my base class like this:

public class MyApiClient : WebServerClient

This builds in a lot of the required functionality into your client without needing to repeat code (I'm also guessing this is the reason that WebServerClient isn't a sealed class).  Once you have this inheritance set up you can do this in your client code:

        private static readonly AuthorizationServerDescription MyApiDescription = new AuthorizationServerDescription
        {
            TokenEndpoint = new Uri(ConfigurationManager.AppSettings["ApiTokenUrl"].ToString(CultureInfo.InvariantCulture)),
            AuthorizationEndpoint = new Uri(ConfigurationManager.AppSettings["ApiAuthorizeUrl"].ToString(CultureInfo.InvariantCulture))
        };
        private readonly IAuthorizationState _authorizationState;

Then in your methods within your client code you can do this:

For synchronous methods you can do this:

            using (var httpClient = new HttpClient(CreateAuthorizingHandler(_authorizationState)))
            {
                var response = httpClient.GetAsync(ApiRootUrl + "stuff/range/" +
                                                   start.ToString(DateService.DefaultDateFormatString) +
                                                   "/" +
                                                   end.ToString(DateService.DefaultDateFormatString)).Result;

                var responsecontent = response.Content;
                return responsecontent.ReadAsAsync<List<MyClass>>().Result;
            }

Even though HttpClient is more or less inherantly Asynchronous including the .Result calls turns them into synchronous calls, I've done this as a lot of these methods are called via my controllers but using Ajax on the client so the blocking behavior isn't an issue.

If you wanted to implement this Async you would do it like this:

        public async Task<List<MyClass>> GetStuffAsync(DateTime start, DateTime end,
                                                                CancellationToken cancelToken =
                                                                    default(CancellationToken))
        {
            using (var httpClient = new HttpClient(CreateAuthorizingHandler(_authorizationState)))
            {
                var response = await httpClient.GetAsync(ApiRootUrl + "stuff/range/" +
                                                         start.ToString(DateService.DefaultDateFormatString) +
                                                         "/" +
                                                         end.ToString(DateService.DefaultDateFormatString), cancelToken);
                return (await response.Content.ReadAsAsync<List<MyClass>>());

Jammer Jamski

unread,
May 13, 2013, 6:43:20 PM5/13/13
to dotnet...@googlegroups.com
Incidentally Im also going to build in some code into the client to check for https:// protocol when built in release mode as you REALLY don't want the bearer token going over an insecure http:// channel ...


On Monday, 6 May 2013 21:34:54 UTC+1, Ton Yeung wrote:

Ton Yeung

unread,
May 13, 2013, 7:11:12 PM5/13/13
to dotnet...@googlegroups.com
I thought that unless you explicitly allow relaxed security in the config on both your client and server, you can't send https.

Ton Yeung

unread,
May 13, 2013, 7:12:33 PM5/13/13
to dotnet...@googlegroups.com
in your
                var response = httpClient.GetAsync(ApiRootUrl + "stuff/range/" +
                              
                     start.ToString(DateService.DefaultDateFormatString) +
                                                   "/" +
                                                   end.ToString(DateService.DefaultDateFormatString)).Result;

the stuff/range, is that where you are entering the scope?
Also, the start and end, is that the time period where the access token is valid for?

Jammer Jamski

unread,
May 14, 2013, 10:42:06 AM5/14/13
to dotnet...@googlegroups.com
That's true but you can never be too secure! :)

Jammer Jamski

unread,
May 14, 2013, 10:44:58 AM5/14/13
to dotnet...@googlegroups.com
stuff/range is actually part of the request URL (eg: http://localhost/stuff/range/)

start and end are part of the query string specifying the date range for the results you're interested in getting back from the server.
Reply all
Reply to author
Forward
0 new messages