1

I am trying to use the Dropbox.Api dotnet SDK, which is built on netstandard 2.0, by translating the example from the docs here into a Blazor Webassembly project. I have narrowed down the issue to the fact that the PKCEOAuthFlow class uses private members CodeVerifier and CodeChallenge to implement the PKCE flow, and these private members are generated and set only in the constructor, which makes sense.

So here is specifically where I am stuck: How can I persist that exact object with its one-time generated CodeVerifier/CodeChallenge which must be the same when I try to call ProcessCodeFlowAsync after the Dropbox redirect back to my app?

I have tried the following:

  1. Opening the dropbox authorize URL in a new tab so that the main tab stays open. This fails because when Dropbox redirects the user back, they stay in the new tab and my object is only still alive back in the first tab.
  2. Making an ILoginService class, injecting it into my pages as a singleton by doing builder.Services.AddSingleton<ILoginService, DropboxLoginService>(); inside Program.cs, but I always get a new one. I am not sure exactly why this fails, but I believe that the entire Webassembly app goes out of scope when I send the user to Dropbox and after the redirect it has to create a new ILoginService anyways.
  3. I also tried making my entire DropboxLoginService class static, with a static PKCEOAuthFlow member set in the static constructor. I also end up with a new object every time when I do it this way, probably for the same reason as #2.
  4. I tried saving my object to the browser session storage using Blazored.SessionStorage, but I quickly realized this does not persist any private members, and the object that I retrieve after the redirect again has a new CodeVerifier and CodeChallenge.
  5. DID NOT TRY THIS YET - I think that MAYBE I could serialize the entire object in some binary format, then save a base64 string to the session storage to retrieve it later. However, this feels like a security hole considering that the whole point of PKCE is to avoid untrustworthy storage with sensitive information. It would basically negate the security since an intrepid hacker could possibly get at that object and MITM my user somehow. Basically it is no more secure than going back to normal OAuth2 with my app secret stored somewhere.

Am I making this too complicated? Is there some way to keep my PKCEOAuthFlow object in memory from the start to the end of my flow, across the 2 redirects from my app -> Dropbox -> back to my app? I think this question goes beyond Dropbox and would apply to any OAuth2 + PKCE flow implementation in Blazor Webassembly, or really any serverless SPA or PWA.

4

0 回答 0