Re: [dotnetopenauth] Question about OAuthConsumerWpf Sample

599 views
Skip to first unread message

Øyvind Sean Kinsey

unread,
Jul 2, 2012, 12:11:57 PM7/2/12
to dotnet...@googlegroups.com
Are you trying to use OAuth2 in the context of a desktop application?
If so then you have two main options, have the desktop app rely on a regular web app to do the token exchange, that way you can use the default way of exchanging codes/tokens, but this means that you need a secure way of transferring the token from the server to the app.
The other option is to use the 'native application' profile as described in http://tools.ietf.org/html/draft-ietf-oauth-v2-28#section-9 combined with the 'implicit grant' (http://tools.ietf.org/html/draft-ietf-oauth-v2-28#section-4.2) where you end up reading the access token out of the user agent in your application.

Alternatively, you implement an extension that lets you retrieve the token in some other way, eg by using verification codes manually inputted by the user and so on. An example of this can be found in https://github.com/AArnott/dotnetopenid/tree/v4.1/samples/OAuthConsumerWpf.

Remember, as long as you control the user agent in the application it doesn't really matter that the redirect_url is not available - you will still be able to access the url navigated to in order to extract the needed data.

Øyvind Sean Kinsey
San Francisco, CA


On Mon, Jul 2, 2012 at 2:53 AM, Vadim D. <vad...@gmail.com> wrote:
Hi,

I am trying to develop OAuth 2.0 server that will use internal user authentication and authorization of the client application.
In order to check the server I am using  OAuthConsumerWpf application provided with the samples.

Everything working just fine until the last stage of the returning the auth token back to client. The client sends returnUrl to be http://localhost/ and then after the process of user authentication and authorization finishes, the server redirects the response.
The log of the server produces the following:

WebDev.WebServer40.exe Information: 0 : Incoming request received: EndUserAuthorizationRequest
WebDev.WebServer40.exe Information: 0 : Binding element DotNetOpenAuth.OAuth2.ChannelElements.TokenCodeSerializationBindingElement did not apply to message.
WebDev.WebServer40.exe Information: 0 : Binding element DotNetOpenAuth.OAuth2.ChannelElements.MessageValidationBindingElement applied to message.
WebDev.WebServer40.exe Information: 0 : Preparing to send EndUserAuthorizationSuccessAuthCodeResponseAS (2.0) message.
WebDev.WebServer40.exe Information: 0 : Binding element DotNetOpenAuth.OAuth2.ChannelElements.MessageValidationBindingElement did not apply to message.
WebDev.WebServer40.exe Information: 0 : DotNetOpenAuth.Messaging.Bindings.ICryptoKeyStore.GetKeys returned no keys for bucket "https://localhost/dnoa/oauth_authorization_code" with the required key length of 256 bits.  A new key will be created
WebDev.WebServer40.exe Information: 0 : Binding element DotNetOpenAuth.OAuth2.ChannelElements.TokenCodeSerializationBindingElement applied to message.
WebDev.WebServer40.exe Information: 0 : Sending message: EndUserAuthorizationSuccessAuthCodeResponseAS
WebDev.WebServer40.exe Information: 0 : Redirecting to http://localhost/?code=E7dl%21IAAAAJl4CfH60tn5k5PONt4tDaXMg_WOjIOSyEB8DCMYNabiEQEAAAGJeKeZoc-32fbJvV-cz_ZnYlulRNrMv7aEfPVY9hdAT_kMEwjucnEh_LPC7Omz8KzRY8zArAUjwF6ZZkZ5DSb8Uw0aec4Hnpj0pxR4kHJ74pJrJ4CR43HnlAwYJ2oOTFofDUl2rMmV4ioFihMTsEoE7uZLvqp2yd536bZHkoWwIpK5Vu-ggSO8dX2gJLwPxpvwZmI9Jhf2mOjsWdlWXHzIRFtwmInRkwZv08o1RwZx2k_1xoV6rIcN-IMEoRkBriT5hY4TO0S8ksoT-sjYv1M4ALRlItPnaZDcZP0Lrr7Oz7scj60AE8gk2NniMg10ittwZ8ntwg5vrKUPlns9LoONk4QlK5nr1jP_2X6-ZldkjQ


The problem is that no one listens on the port 80, thus the ClientAuthorizationView embedded in the dialog fails to navigate to the specified URL. As far as I understand it, I have no control in the OAuthConsumerWpfon the returnUrl parameter without changing the code of the client.

Please advice what am I missing and what should be done to fix it.

Thanks in advance
Vadim

--
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/-/SpsA_VganOIJ.
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,
Jul 2, 2012, 12:51:03 PM7/2/12
to dotnet...@googlegroups.com
Thanks, Oyvind. 

Actually the authorization code grant type is an option for native clients, and I still prefer that approach.  But I think it requires that the native app set up its own client account with the authorization server, which is outside the scope of the spec but certainly something that could be done using DNOA.

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

Øyvind Sean Kinsey

unread,
Jul 2, 2012, 1:02:12 PM7/2/12
to dotnet...@googlegroups.com
This also requires some extra work at the Authorization Server right? Not all AS have facilities for 'out of bound' authorization, but if it does or you are the one building it, then using the code grant is absolutely worth it.

- Sean

Andrew Arnott

unread,
Jul 2, 2012, 1:33:33 PM7/2/12
to dotnet...@googlegroups.com
Yes, the authorization server must support it.  

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


Vadim D.

unread,
Jul 3, 2012, 1:52:03 AM7/3/12
to dotnet...@googlegroups.com
Thanks you for your answers.

My authorization server supports client registration out-of-band so there is no problem with it.
I am using OAuthConsumerWpf in order to check the server side  and I am using the Generic 2.0 tab with the following parameters:

I have stepped in into the ClientAuthorizationView source code in order to understand how the interception of the navigation happens and so it happens every time the event WebBrowser1_Navigating is pumped up. But somehow, when I have redirection from the AS with the code, the embedded browser pups up the event with wrong URL, so function SignificantlyEqual is always false.

If I put a breakpoint on ProcessLocationChanged in class ClientAuthorizationView, these are the URLs I am getting:
The problem is that tha last URL should be the client's callback URL and it's never received by the embedded browser, although the server sent redirection in method AuthorizeResponse, where the code
is checking the client, checking the scope, adding new authorization to the DB and then returning with:

response = _authorizationServer.PrepareApproveAuthorizationRequest(pendingRequest, User.Identity.Name);
return _authorizationServer.Channel.PrepareResponse(response).AsActionResult();


I will try to install Fiddler the check what is returned from the server, but it looks very strange to me.

Vadim
- Sean


Thanks, Oyvind. 

To unsubscribe from this group, send email to dotnetopenid+unsubscribe@googlegroups.com.

For more options, visit this group at http://groups.google.com/group/dotnetopenid?hl=en.

--
You received this message because you are subscribed to the Google Groups "DotNetOpenAuth" group.
To post to this group, send email to dotnet...@googlegroups.com.
To unsubscribe from this group, send email to dotnetopenid+unsubscribe@googlegroups.com.

For more options, visit this group at http://groups.google.com/group/dotnetopenid?hl=en.

--
You received this message because you are subscribed to the Google Groups "DotNetOpenAuth" group.
To post to this group, send email to dotnet...@googlegroups.com.
To unsubscribe from this group, send email to dotnetopenid+unsubscribe@googlegroups.com.

For more options, visit this group at http://groups.google.com/group/dotnetopenid?hl=en.

--
You received this message because you are subscribed to the Google Groups "DotNetOpenAuth" group.
To post to this group, send email to dotnet...@googlegroups.com.
To unsubscribe from this group, send email to dotnetopenid+unsubscribe@googlegroups.com.

Vadim D.

unread,
Jul 3, 2012, 2:48:34 AM7/3/12
to dotnet...@googlegroups.com
Very strange, but after installing and running Fiddler everything started to work ... I have checked again without Fiddler - not working

Vadim D.

unread,
Jul 3, 2012, 9:49:57 AM7/3/12
to dotnet...@googlegroups.com
I have continued to run the Fiddler and now I have another strange problem - I have server side exception in Token action that the client is not authenticated.
I have checked the reason and found that this is happening while server tries to authenticate the client from HTTP headers.

The problem is that .NET framework does not send this header when you do something like:

HttpWebRequest request = (HttpWebRequest)WebRequest.Create(...);

request.Credentials = new NetworkCredential("username", "password");

but instead it waits for server to reply with 401 and
WWW-Authenticate header presented - only after this the proper authentication header will be sent.
So it seems to me that I have to change somehow the Token action to require client authentication (your example of the server does not contains this)

Vadim

Andrew Arnott

unread,
Jul 5, 2012, 12:14:57 PM7/5/12
to dotnet...@googlegroups.com
Yes, .NET makes it extremely difficult to include an HTTP Authorization header in the initial request and requires the authenticate challenge response first.

Support for HTTP Basic client authentication is new in DNOA v4.1.  The MVC controller in the authorization server sample doesn't have an [Authorize] attribute because DNOA handles it internally.  If you step through the OAuthClient and OAuthAuthorizationServer samples together, you'll see the first request come in, get rejected with the error, and the client will automatically retry applying the client credentials in the Authorization header.  This is how your app should presumably work as well.

Alternatively you can simply use the old style method of applying client id and secret inside your POST payload, but OAuth 2 strongly discourages this.

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


To view this discussion on the web visit https://groups.google.com/d/msg/dotnetopenid/-/kxkxXDvWc-MJ.

To post to this group, send email to dotnet...@googlegroups.com.
To unsubscribe from this group, send email to dotnetopenid...@googlegroups.com.

weblivz

unread,
Jul 5, 2012, 12:23:48 PM7/5/12
to dotnet...@googlegroups.com
Might I suggest you look at the System.Net.Http namespace on ASP.NET MVC4.i

Allows you to do something like this:

            string authInfo = "myusername" + ":" + "mypassword";
            authInfo = Convert.ToBase64String(Encoding.Default.GetBytes(authInfo));

            var httpClient = new HttpClient()
            {
                BaseAddress = new Uri(System.Configuration.ConfigurationManager.AppSettings["Domain"])
            };

            // set the oauth info
            httpClient.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Basic", authInfo);

I've used this over TLS to do basic auth on a recent project - works well but it's one of the things i'm looking to do with DotNetOpenAuth in the coming week or so if i get time so not sure what kind of work would be needed.

/steven

Andrew Arnott

unread,
Jul 5, 2012, 12:41:06 PM7/5/12
to dotnet...@googlegroups.com
DNOA still targets .NET 3.5, so it can't take a dependency on a .NET 4.0 class like HttpClient, if I understand what you're proposing correctly.  However there are specific DNOA builds that support #ifdef around code that might allow DNOA to use HttpClient when specifically building against .NET 4.0.  Another option may be to implement your own IDirectWebRequestHandler, in which case your implementation can use HttpClient and then since DNOA will use your handler instead of its own internal default it will work the way you want.

On the other hand, you could keep doing it the way the samples do and it already works, just with an extra round trip.

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


To view this discussion on the web visit https://groups.google.com/d/msg/dotnetopenid/-/Y7nfMSSDk54J.

To post to this group, send email to dotnet...@googlegroups.com.
To unsubscribe from this group, send email to dotnetopenid...@googlegroups.com.

Vadim D.

unread,
Jul 8, 2012, 11:24:47 AM7/8/12
to dotnet...@googlegroups.com
Thanks for the answer. I prefer not to change the client side.

What I did what to add the [RequireBasicAuthentication] attribute and implement it this way:

[AttributeUsage(AttributeTargets.Method)]
    public sealed class RequireBasicAuthentication : FilterAttribute, IAuthorizationFilter
    {       
        public void OnAuthorization(AuthorizationContext filterContext)
        {
            var req = filterContext.HttpContext.Request;
            if (String.IsNullOrEmpty(req.Headers["Authorization"]))
            {
                filterContext.Result = new ContentResult() { Content = "Not Authorized"};
                var res = filterContext.HttpContext.Response;
                res.StatusCode = 401;
                res.AddHeader("WWW-Authenticate", "Basic realm=\"XXXXXXXXXXXX\"");
                res.End();               
            }
        }
    }

Now it's working just fine without changing client side code.
I am stil struggling with the issue that somehow the WPF client supplied with the samples works only while Fiddler is on ... Without fiddler I am getting the error page in embedded browser control

Andrew Arnott

unread,
Aug 31, 2012, 7:40:56 PM8/31/12
to dotnet...@googlegroups.com
Hi James,

You've brought up an interesting point.  Yes, if the nonce appears twice, the first in a message without authentication and the second in a message with it, then it seems the nonce should only be "consumed" the second time.  The fact that DNOA is consuming it both times sounds problematic.  I don't know why the sample is working in this case either.  It's worth looking more into.  Do you have cycles to debug into it?

--
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 Fri, Aug 31, 2012 at 10:10 AM, James Andersen <james.j....@gmail.com> wrote:
I've just been stuck on this as well...   I ran into trouble because I found that first request failed for lack of an authentication header (as already noted) but then the second request (now authenticated) was failing because the INonceStore was returning false because the same entry was already recorded by the first request.   For some reason the sample code (with the DatabaseKeyNonceStore) doesn't seem to have a problem with this even though the values passed to StoreNonce are exactly the same on both requests; my custom implementation was returning false on the second response which seems to be what it SHOULD do.   Is this the expected behavior with StoreNonce?   Should DNOA be calling StoreNonce twice for both the unauthenticated AND the authenticated request with the same values both times?
- Sean


Thanks, Oyvind. 

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.

--
You received this message because you are subscribed to the Google Groups "DotNetOpenAuth" group.
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.

--
You received this message because you are subscribed to the Google Groups "DotNetOpenAuth" group.
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.

--
You received this message because you are subscribed to the Google Groups "DotNetOpenAuth" group.
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.

--
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/-/kxkxXDvWc-MJ.

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.

--
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/-/mngIWxKCCHIJ.

James Andersen

unread,
Sep 4, 2012, 12:36:52 AM9/4/12
to dotnet...@googlegroups.com
Hmm...  Haven't entirely gotten to the bottom of this but on the reason why the DatabaseKeyNonceStore ISN'T failing as one would expect, it appears to be that OAuthAuthorizationServer\Global.asax.cs stores the DataClassesDataContext in HttpContext.Current.Items["DataContext"] which is kept only during an HTTP request.  I'm not sure if that was the intent or if the intent was to keep the context in say HttpContext.Current.Cache so it's available across requests (that where I've kept my custom implementation which surfaced this problem for me).  In any case, my best guess right now is that the non-authenticated and authenticated requests to the token endpoint are spinning up two threads with two instances of the DataContext and the second request isn't quite aware of the first one...   again, not really sure at this point (was just poking at it while watching a movie).

However, assuming the issue with the INonceStore is straightened out, requests to the DNOA token endpoint in the sample would presumably start failing as replay attacks.   Is there a simple way to avoid calling into StoreNonce until the incoming request message has been checked for authorization? (I'm a newbie to DNOA so not really familiar with the pipeline...)  I could open a bug for this if that's useful.

Andrew Arnott

unread,
Sep 4, 2012, 10:15:46 AM9/4/12
to dotnet...@googlegroups.com
James,

Thanks for the investigation.  It sounds like as you say the sample is buggy.  Then DNOA has a bug that it shouldn't call StoreNonce until the request has been otherwise authorized.  This is a bug within the assembly -- not with your configuration.  Can you please file a bug with all this information?

Thanks.

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


To view this discussion on the web visit https://groups.google.com/d/msg/dotnetopenid/-/hFHFG_Bm-HsJ.

James Andersen

unread,
Sep 4, 2012, 10:58:36 AM9/4/12
to dotnet...@googlegroups.com
Done -  Issue #195.    Thanks for the responsiveness!  If I do get some more time I might look into the issue with the sample further; I'm probably less qualified to tackle the issue with INonceStore.StoreNonce being called twice at this point ;-)

James Andersen

unread,
Sep 19, 2012, 1:43:16 AM9/19/12
to dotnet...@googlegroups.com
I've done a bit more debugging on why the sample ISN'T failing and noted my findings in the github issue.   Briefly, it looks like the unauthenticated request causes the error handler in the ASP.NET pipeline to trigger which rolls back the transaction on which INonceStore.StoreNonce attempts to write the nonce the first time.   This implementation of INonceStore happens to accommodate the challenge/response flow well because of the rollback but it seems like a fortunate kludge as other implementations of INonceStore (like the in-memory one I was playing with earlier) would fail.

Andrew Arnott

unread,
Sep 21, 2012, 12:29:55 AM9/21/12
to dotnet...@googlegroups.com
Ah yes, the transaction rollback sounds very likely why this bug was hidden.  Thanks for adding to the bug.  We'll get this fixed soon, I hope.

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


To view this discussion on the web visit https://groups.google.com/d/msg/dotnetopenid/-/LSytdovrV54J.
Reply all
Reply to author
Forward
0 new messages