Search code examples
c#winformsauthenticationoauth-2.0salesforce

How can I use Salesforce OAuth 2.0 implicit flow authentication in a WinForms application?


I wrote a web application which connects to the Salesforce API using the OAuth 2.0 web server flow, and that all works fine.

But now there is a requirement to access the Salesforce API from a WinForms desktop application and I'm stuck. Salesforce suggest using the User-Agent, or implict, flow for desktop applications.

The flow is described by Salesforce here - https://help.salesforce.com/articleView?id=remoteaccess_oauth_user_agent_flow.htm&type=5

I've created a WinForms application and used the CefSharp library to embed a browser. I can open a web page in the embedded browser using the URL syntax shown in the article, e.g.

https://login.salesforce.com/services/oauth2/authorize?response_type=token& client_id=CLIENT_ID&redirect_uri=REDIRECT_URI

But I don't know where to go from here.

I'm guessing the redirect URI has to be a public endpoint, but how would the token returned by Salesforce to the URI finds it's way back to my desktop application so it can be used in the headers of WebRequests to access the API.

I would be grateful for any help, pointers, sample code, etc.

Thanks.


Solution

  • redirect uri doesn't have to be public. It can be localhost:somePort and your application would have to be listening to traffic on that port.

    For example if you want to develop SF code using SFDX CLI + Visual Studio Code - there's a nice way to authorise access to SF org where you type your credentials on the website but when all is good - the OAuth piece gets sent to localhost:1717. As long as nothing else is listening on this port you're fine. Similar with Salesforce Data Loader - you can type username and pass to it but it also has this web-based flow. And sometimes it's the only option really, if your SF admin enabled Single Sign-On that authenticates against Active Directory/Google/Facebook/... - you might not be able to use SF username and password.

    My C# days are long gone but listening on a port on local machine shouldn't be the end of the world? You shouldn't need a full-blown web server bundled with your app...

    https://learn.microsoft.com/en-us/azure/active-directory/develop/v2-oauth2-implicit-grant-flow has some good theory

    https://learn.microsoft.com/en-us/dotnet/api/system.net.sockets.tcplistener?redirectedfrom=MSDN&view=netcore-3.1 example code?