We are aware of the issue with the badge emails resending to everyone, we apologise for the inconvenience - learn more here.

Forum Discussion

dotNET_Guy's avatar
dotNET_Guy
Explorer | Level 3
4 years ago

OAuth authentication for offline application using .NET SDK

Hi Guys,

 

I've been reading a lot of the Dropbox API documents to get OAuth2 authentication working for my offline Windows application using the .NET SDK. The 'OAuth Guide' was a great starting point and very helpful!

 

I've looked at the code from both these example projects: OAuth Basic and OAuth PKCE

These really helped me to understand it programmatically.


My snippet of code

Uri authorizeUri = DropboxOAuth2Helper.GetAuthorizeUri(OAuthResponseType.Code, ApiKey, redirectUri: (string) null, tokenAccessType: TokenAccessType.Offline);

 

OAuth2Response tokenResult = await DropboxOAuth2Helper.ProcessCodeFlowAsync(authorizationCode, ApiKey, ApiSecret);


I noticed the returned value (a URI) didn't have an Authorization Code, but a URL (and other related items) to redirect to Dropbox to authenticate manually, i.e. non-offline.

 

I then tried the non-overloaded method specifically for no-redirect authentication:

DropboxOAuth2Helper.GetAuthorizeUri(ApiKey)

Again it returned a URI containing a URL (and other related items) for redirect (i.e. non-offline) authentication.

 

Now, I'm thinking this method DropboxOAuth2Helper.GetAuthorizeUri() doesn't handle offline authentication. Or I must be doing something very wrong.

 

Going back to the documentation, and re-reading the 'OAuth Guide' (https://developers.dropbox.com/oauth-guide), I came across the following paragraph:

Applications that require offline access to the API - meaning using the API when the end user is not actively interacting through your app - will not be able to prompt for re-authorization. These apps may instead use long-lived refresh tokens can be used to obtain new access tokens.


So this document tells me I am able to fetch a long-lived refresh token, then fetch consecutive short-lived (sl-) access tokens as I go.

But I am now unsure how to do this using the .NET SDK? (I'd rather not use HTTP calls and stick to the .NET SDK).

 

Can someone please provide a snippet of code to show how this can be done, please. Or point me in the right direction. I have spent 3 days on this, which isn't too frustrating as I have learnt a lot about the Dropbox API.

 

Thanks.

  • Use of a redirect URI is optional, and you can still request offline access to get a refresh token back without using a redirect URI. When not using a redirect URI, the user would just need to manually copy/paste the authorization code into the app.

     

    You can do that like this:

     

    First, get the authorization URL, requesting offline access, like:

    var authorizeUri = DropboxOAuth2Helper.GetAuthorizeUri(oauthResponseType:OAuthResponseType.Code,
    													   clientId: AppKey,
    													   redirectUri: (String)null,
    													   state: state,
    													   tokenAccessType: TokenAccessType.Offline,
    													   scopeList: null,
    													   includeGrantedScopes: IncludeGrantedScopes.None);

     Open that in the user's browser, such as like in the example:

    System.Diagnostics.Process.Start(authorizeUri.ToString());

    Have the user copy/paste the code into your app. This can be via your UI, but for the sake of example, this is how a console app might do this:

    var code = Console.ReadLine();

    Finish the process by exchanging the authorization code:

    var tokenResult = await DropboxOAuth2Helper.ProcessCodeFlowAsync(code: code, appKey: AppKey, appSecret: AppSecret, redirectUri: null);

    (Note that this is the non-PKCE flow, for server-side apps. For the PKCE flow, for client-side apps, a code challenge/verifier is used instead of the app secret.)

    Then you can make a client using the resulting credentials:

    var client = new DropboxClient(appKey: AppKey,
                          appSecret: AppSecret,
                          oauth2AccessToken: tokenResult.AccessToken,
                          oauth2RefreshToken: tokenResult.RefreshToken,
                          oauth2AccessTokenExpiresAt: tokenResult.ExpiresAt.Value);

    The SDK will automatically perform the refresh process for you when needed when using a client with the necessary credentials like this.

  • Greg-DB's avatar
    Greg-DB
    Icon for Dropbox Staff rankDropbox Staff

    Use of a redirect URI is optional, and you can still request offline access to get a refresh token back without using a redirect URI. When not using a redirect URI, the user would just need to manually copy/paste the authorization code into the app.

     

    You can do that like this:

     

    First, get the authorization URL, requesting offline access, like:

    var authorizeUri = DropboxOAuth2Helper.GetAuthorizeUri(oauthResponseType:OAuthResponseType.Code,
    													   clientId: AppKey,
    													   redirectUri: (String)null,
    													   state: state,
    													   tokenAccessType: TokenAccessType.Offline,
    													   scopeList: null,
    													   includeGrantedScopes: IncludeGrantedScopes.None);

     Open that in the user's browser, such as like in the example:

    System.Diagnostics.Process.Start(authorizeUri.ToString());

    Have the user copy/paste the code into your app. This can be via your UI, but for the sake of example, this is how a console app might do this:

    var code = Console.ReadLine();

    Finish the process by exchanging the authorization code:

    var tokenResult = await DropboxOAuth2Helper.ProcessCodeFlowAsync(code: code, appKey: AppKey, appSecret: AppSecret, redirectUri: null);

    (Note that this is the non-PKCE flow, for server-side apps. For the PKCE flow, for client-side apps, a code challenge/verifier is used instead of the app secret.)

    Then you can make a client using the resulting credentials:

    var client = new DropboxClient(appKey: AppKey,
                          appSecret: AppSecret,
                          oauth2AccessToken: tokenResult.AccessToken,
                          oauth2RefreshToken: tokenResult.RefreshToken,
                          oauth2AccessTokenExpiresAt: tokenResult.ExpiresAt.Value);

    The SDK will automatically perform the refresh process for you when needed when using a client with the necessary credentials like this.

    • dotNET_Guy's avatar
      dotNET_Guy
      Explorer | Level 3

      Thank you very much Greg. It now works for my Windows console app!

       

      (The redirect code snippets in the OauthBasic and OAuthPKCE examples had thrown me off).


      So there is some level of manual intervention still required during the authentication process, i.e. Visit a Dropbox web page, then copy & paste the authentication code.


      After this it should all the automated, e.g. the refresh token should last forever (unless revoked), and the .NET SDK would automatically fetch subsequent short-lived (sl-) access tokens behind-the-scenes.


      For anyone programming with .NET (I'm using the most recent version .NET 5), I found the following line gave an exception (file specified could not be found):

      System.Diagnostics.Process.Start(authorizeUri.ToString());
      

       

      I had to include the executable WITH a fully qualified path to launched a browser:

      System.Diagnostics.Process.Start(@"C:\Program Files\Mozilla Firefox\firefox.exe", authorizeUri.ToString());


      And Greg, I knew you would be answering this thread. Thanks for all the hard work you do in answering posts, it is much appreciated!