6

I'm currently attempting to use the OAuth 2.0 User-Agent Flow with a clientside C# application, and I'm running into some confusion relating to the redirect URI.

Because I'm working with a clientside application, I cannot supply a standard redirect URL to a web server. However, according to the people I'm trying to authenticate with (Salesforce, in this instance), the User-Agent Flow is the correct one to use for a clientside application.

My question is, what can I do to catch the access token in this situation? Apparently I can create a "local resource accessible to the client," but I'm unfamiliar with the mechanics behind this, and I can't find any resources on the topic (partly because I don't know what to look for).

Any pointers as to where I should start looking would be greatly appreciated.


Edit: Some more digging has revealed the following stackoverflow question:

How do I develop against OAuth locally?

I'm doing some more investigating with what they suggested, but any other suggestions would be great as well.


Edit: Some more searching revealed this article:

http://sarangasl.blogspot.com/2010/09/create-simple-web-service-in-visual.html

Still feels like I'm poking around in the dark without an understanding of the larger picture, but I believe I need to set up a local web service using localhost and point my redirect URI there. I'll then use my web service to unwrap the response from the OAuth server and have my application respond appropriately. More updates to come.


Ooookay. So from what I've been able to gather, I need to set up a local web service to supply as the callback for OAuth. I need to listen on said web service myself and catch the callback to pass it to my app. However, the default ASP.NET web service provided by VS2010 does not support URL parameters, just API calls, so I apparently need to use the WCF Rest starter kit instead.

I am completely foreign to all of this, so any tips would be a godsend at this point. In general, I'm thinking I set up a local WCF Rest service, supply that local URI to OAuth as the callback, and then catch the callback URL using the Rest service. Then I parse the URL and extract the access token. At this point, does my app request the access token, or can my web service "give" the token to my app? I.e., where should the locus of control be?

Community
  • 1
  • 1
sichinumi
  • 1,835
  • 3
  • 21
  • 40

3 Answers3

5

Figured out a clever way to work around this. Instead of setting up a service to listen for OAuth's redirect URL, I embedded a WebBrowser control inside my Windows form.

I pointed this embedded WebBrowser to the authentication URL and let the user log in and authenticate with Salesforce and grant permissions to my app. Then, I let Salesforce redirect my embedded browser to a dummy redirect URL that I supply. This redirect never actually goes anywhere, it just shows up as a 404.

However, by monitoring WebBrowser.Url, I can pick up the entire URL that my embedded WebBrowser control is directed to, including the access token that is appended by Salesforce. Basically, after the user authenticates and grants permissions, the embedded browser is redirected to "http://www.dummyurl.com." Salesforce appends the access token, so WebBrowser.Url ends up looking something like this:

http://www.dummyurl.com#access_token=ABCDEF&instance_url=ABCDEF

From here, I can just parse the URL and go on my way. No third-party web server or local web service required. :)

sichinumi
  • 1,835
  • 3
  • 21
  • 40
  • 2
    This would be an option. But be careful: user can use some tricks on your WebBrowser like going forward and backward inside browser history, page refresh, timeouts, network outage. YOU will have to handle all HTTP error codes + all embedded browser nasty tricks. Good luck :) – Artem Oboturov Jun 01 '12 at 21:09
  • Plus consider the UI of your app which will, probably, be different from the one proposed by Salesforce - and you can't change their default because you don't have control over it. – Artem Oboturov Jun 01 '12 at 21:12
  • Ugh, you're right. I will have to take a look at embedded browser security next. As far as the UI though, my app is a background process that generates a popup on certain events, so authentication is only required once per app launch (usually once per day, in the morning). Thanks for the tips though, I forgot about the security holes that would potentially be opened up with an embedded IE instance. – sichinumi Jun 01 '12 at 21:15
2

The call the Authorization type you need Authonomous Client http://wiki.developerforce.com/page/Digging_Deeper_into_OAuth_2.0_on_Force.com#Obtaining_a_Token_in_an_Autonomous_Client_.28Username-Password_Flow.29. Read about the URL you have to send there.

grant_type=password&client_id=<your_client_id>&client_secret=<your_client_secret>&username=<your_username>&password=<your_password>
Artem Oboturov
  • 4,344
  • 2
  • 30
  • 48
  • I cannot use that flow, unfortunately. If the IP attempting to authenticate is not whitelisted, the password must be appended with the user's security token, which is not an option for my application. – sichinumi Jun 01 '12 at 19:36
  • Put it though your proxy which will be whitelisted. Plus the link is `POST`ed - so request parameters will be encrypted by HTTPS. Do you have any problem with this approach? – Artem Oboturov Jun 01 '12 at 20:20
  • Hmm, I didn't think of proxying it. However, I'm developing this app for other users in other business environments, and routing all traffic through a third-party proxy is not an option. I also don't have control over the whitelists for my users' different organizations. Lastly, I was explicitly told by the API developers to avoid the User-Password OAuth flow. I have no problems with it personally, though, but take a look at my other answer and let me know what you think about it. :) – sichinumi Jun 01 '12 at 20:36
  • You can provide user with security tokens - in this case you don't have to put their IP into white list. Reread last part of Doc about Autonomous Client. – Artem Oboturov Jun 01 '12 at 21:13
  • I reread the doc, but did not find what you were referring to - the user should be the only person capable of generating their own security token, I cannot do it for them. Regardless though, according to the Salesforce API folks, User-Password Flow is evil and bad. :P – sichinumi Jun 01 '12 at 21:19
  • > The API user's Salesforce.com password. If the client's IP address has not been whitelisted in your org, you must concatenate the security token with the password. - right from description `password`. – Artem Oboturov Jun 01 '12 at 21:41
0

You can use DotNetOpenAuth library. There's an example using WPF, where it uses a winforms control called ClientAuthorizationView provided by DotNetOpenAuth library.

It is a control that hosts a browser allowing the user to authorize the client without leaving the application.

Hope this help.

Regards

dave
  • 2,291
  • 3
  • 19
  • 25