<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/" version="2.0">
  <channel>
    <title>topic Re: Dropbox .net SDK, automatic refresh of access token not working in Dropbox API Support &amp; Feedback</title>
    <link>https://www.dropboxforum.com/t5/Dropbox-API-Support-Feedback/Dropbox-net-SDK-automatic-refresh-of-access-token-not-working/m-p/565389#M26558</link>
    <description>&lt;P&gt;I've managed to sort the issue. Debugging through the SDK source code, I could see that I wasn't setting the AppSecret, though from the comments in the SDK, it appears that this is not critical. However when I changed the code I use to create the Dropbox client and used the overload that includes the AppSecret, the SDK was able to retrieve a refresh token.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;It would be useful if the proper error messages received from the server is returned from the API call. For example when the RefreshAccessToken method is called in the DropboxRequestHandler, the call to&amp;nbsp;response.EnsureSuccessStatusCode() (on line 288) throws an exception which causes the method to only return the basic information, in this case BadRequest provided by that exception. Instead, what you really should be doing is creating some custom code to handle a non Success status code then if possible, you need to be parsing the Content of the response like you do for a successful request i.e.&amp;nbsp;&amp;nbsp;var json = JObject.Parse(await response.Content.ReadAsStringAsync()) which will then provide you with additional error information that you can pass on to the user which will at least give them a clue, in my case it was the "No auth function available for given request" message which provided a bit of a clue.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;For example, something a bit like this.....&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;LI-CODE lang="csharp"&gt;string Error = null;

try
{
response.EnsureSuccessStatusCode();
}
catch (Exception ex)
{
Error = ex.Message
}

var json = JObject.Parse(await response.Content.ReadAsStringAsync());

if (!string.IsNullOrEmpty(Error)
{
// Do something with the decoded json data and then maybe throw a new exception with this data
}


            if (response.IsSuccessStatusCode)
            {
                var json = JObject.Parse(await response.Content.ReadAsStringAsync());
                string accessToken = json["access_token"].ToString();
                DateTime tokenExpiration = DateTime.Now.AddSeconds(json["expires_in"].ToObject&amp;lt;int&amp;gt;());
                this.options.OAuth2AccessToken = accessToken;
                this.options.OAuth2AccessTokenExpiresAt = tokenExpiration;
                return true;
            }

            return false;&lt;/LI-CODE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Also, since in this case it was the lack of AppSecret that was causing the issue, an error reflecting this would be very useful.&lt;/P&gt;</description>
    <pubDate>Tue, 21 Dec 2021 10:44:53 GMT</pubDate>
    <dc:creator>Dame1701</dc:creator>
    <dc:date>2021-12-21T10:44:53Z</dc:date>
    <item>
      <title>Dropbox .net SDK, automatic refresh of access token not working</title>
      <link>https://www.dropboxforum.com/t5/Dropbox-API-Support-Feedback/Dropbox-net-SDK-automatic-refresh-of-access-token-not-working/m-p/565367#M26553</link>
      <description>&lt;P&gt;Hi there,&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;I'm using the latest (6.22.0) version of the .net API. However it seems that the access token is not being automatically refreshed causing a bad request error to be thrown when I try to access any part of the SDK, for example&amp;nbsp;Users.GetCurrentAccountAsync(). I checked the supplied OAuth2 data, I am storing the AccessToken, RefreshToken and the AccessTokenExpiry time. Examining the stored values, I can see that the AccessTokenExpiry time has passed and therefore the access token is no longer valid.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;From what I understand, the .net SDK is supposed to get a new access token automatically if it discovers that the supplied token has expired. However this does not appear to be happening. If I update the AccessToken and RefreshToken by relinking to my Dropbox account, everything starts working again. I am creating the SDK client in the following way:&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;var config = new DropboxClientConfig("ContentAgentDropboxPlugin")&lt;BR /&gt;{&lt;BR /&gt;HttpClient = httpClient&lt;BR /&gt;};&lt;/P&gt;
&lt;P&gt;&lt;BR /&gt;m_dropboxAPIClient = new Dropbox.Api.DropboxClient(Settings.AccessToken, Settings.RefreshToken, (DateTime)Settings.AccessTokenExpiry, AppKey, config);&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;The values for AccessToken, RefreshToken and AccessTokenExpiry are all retrieved using the correct OAuth2 authentication flow (which redirects to a website hosted by our company which supplies the data passed to it by the Dropbox authentication system to our app).&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Does anyone have any idea what might be going wrong?&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Many thanks,&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Damien&lt;/P&gt;</description>
      <pubDate>Tue, 21 Dec 2021 14:31:27 GMT</pubDate>
      <guid>https://www.dropboxforum.com/t5/Dropbox-API-Support-Feedback/Dropbox-net-SDK-automatic-refresh-of-access-token-not-working/m-p/565367#M26553</guid>
      <dc:creator>Dame1701</dc:creator>
      <dc:date>2021-12-21T14:31:27Z</dc:date>
    </item>
    <item>
      <title>Re: Dropbox .net SDK, automatic refresh of access token not working</title>
      <link>https://www.dropboxforum.com/t5/Dropbox-API-Support-Feedback/Dropbox-net-SDK-automatic-refresh-of-access-token-not-working/m-p/565374#M26554</link>
      <description>&lt;P&gt;I've noticed that calling the method&amp;nbsp;RefreshAccessToken(ScopeList) on the Dropbox client also results in a BadRequest error. Currently there seems to be no way to resolve this without sending the user right back through the whole OAuth2 authentication process.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;There are also no error details provided with the BadRequest error, but reauthenticating causes everything to start working again.&lt;/P&gt;</description>
      <pubDate>Tue, 21 Dec 2021 09:55:36 GMT</pubDate>
      <guid>https://www.dropboxforum.com/t5/Dropbox-API-Support-Feedback/Dropbox-net-SDK-automatic-refresh-of-access-token-not-working/m-p/565374#M26554</guid>
      <dc:creator>Dame1701</dc:creator>
      <dc:date>2021-12-21T09:55:36Z</dc:date>
    </item>
    <item>
      <title>Re: Dropbox .net SDK, automatic refresh of access token not working</title>
      <link>https://www.dropboxforum.com/t5/Dropbox-API-Support-Feedback/Dropbox-net-SDK-automatic-refresh-of-access-token-not-working/m-p/565383#M26556</link>
      <description>&lt;P&gt;I've managed to debug into the .net source code and the error returned by the DropBox API is "No auth function available for given request". It seems that the SDK does not have the facility to pass on the data retrieved from the API, once it fails to pass EnsureSuccessStatusCode() it will simply return the status code with no additional data.&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Tue, 21 Dec 2021 10:22:29 GMT</pubDate>
      <guid>https://www.dropboxforum.com/t5/Dropbox-API-Support-Feedback/Dropbox-net-SDK-automatic-refresh-of-access-token-not-working/m-p/565383#M26556</guid>
      <dc:creator>Dame1701</dc:creator>
      <dc:date>2021-12-21T10:22:29Z</dc:date>
    </item>
    <item>
      <title>Re: Dropbox .net SDK, automatic refresh of access token not working</title>
      <link>https://www.dropboxforum.com/t5/Dropbox-API-Support-Feedback/Dropbox-net-SDK-automatic-refresh-of-access-token-not-working/m-p/565385#M26557</link>
      <description>&lt;LI-CODE lang="csharp"&gt;public async Task&amp;lt;string&amp;gt; GetAccessToken(string LicenseServerAddress = null)
        {
            try
            {
                // Short lived ID that allows us to identify ourselves to the casoftkeywebsite
                string SessionID = Guid.NewGuid().ToString("N");

                var redirect = DropboxOAuth2Helper.GetAuthorizeUri(OAuthResponseType.Code, AppKey, RedirectUri, SessionID, false, false, null, false, TokenAccessType.Offline, ScopeList, IncludeGrantedScopes.None, null);

                // Take the user through authentiation
                Process.Start(redirect.ToString());

                string ServerAddress = null;

                // Get the code from casoftkey, we store them there after authentication
                if (!string.IsNullOrEmpty(LicenseServerAddress))
                {
                    ServerAddress = LicenseServerAddress;
                }
                else
                {
                    ServerAddress = m_engine.BorregoEngine.GetCCConfigFileValue("LicenseServerAddress");
                }
                
                Root6LicensingRestClient Client = new Root6LicensingRestClient(ServerAddress);

                var TokenResult = await Client.GetToken("ContentAgent", "!~P8+AF&amp;lt;,v$/z~Mp");

                if (!string.IsNullOrEmpty(TokenResult.error))
                {
                    if (!string.IsNullOrEmpty(TokenResult.error_description))
                    {
                        return TokenResult.error + " : " + TokenResult.error_description;
                    }

                    return TokenResult.error;
                }

                Client.SetAuthenticationToken(TokenResult.access_token);
                ServerResult&amp;lt;DropboxOAuth2Info&amp;gt; result = null;

                int Timeout = 60; // 60 seconds to get the code response
                int TimeoutCounter = 0;

                do
                {
                    TimeoutCounter++;
                    result = await Client.GetDropboxCode(SessionID);
                    System.Threading.Thread.Sleep(1000);
                }
                while ((result == null || result.Data == null) &amp;amp;&amp;amp; TimeoutCounter &amp;lt; Timeout &amp;amp;&amp;amp; result.OperationResult != enDatabaseOperationResult.Error);

                if (result !=null)
                {
                    if (result.OperationResult == enDatabaseOperationResult.Error)
                    {
                        return "Error retrieving Dropbox code: " + result.error;
                    }
                }
                else if (TimeoutCounter &amp;gt;= Timeout &amp;amp;&amp;amp; (result == null || result.Data == null))
                {
                    return "Timed out waiting for the user to authenticate with Dropbox";
                }

                OAuth2Response CodeResponse = null;

                if (result.Data.SessionID == SessionID)
                {
                    CodeResponse = await DropboxOAuth2Helper.ProcessCodeFlowAsync(result.Data.Code, AppKey, AppSecret, RedirectUri);


                    Settings.AccessToken = CodeResponse.AccessToken;
                    Settings.RefreshToken = CodeResponse.RefreshToken;

                    if (CodeResponse.ExpiresAt != null)
                    {
                        Settings.AccessTokenExpiry = (DateTime)CodeResponse.ExpiresAt;
                    }
                    else Settings.AccessTokenExpiry = DateTime.MinValue;

                    Settings.UID = CodeResponse.Uid;
                }
                else
                {
                    return "SessionID did not match the ID we submitted";
                }
            }
            catch (Exception e)
            {
                return e.Message;
            }

            return null;
        }&lt;/LI-CODE&gt;&lt;P&gt;This is the code I am using to authenticate with Dropbox, maybe I am doing something wrong here?&lt;/P&gt;</description>
      <pubDate>Tue, 21 Dec 2021 10:25:01 GMT</pubDate>
      <guid>https://www.dropboxforum.com/t5/Dropbox-API-Support-Feedback/Dropbox-net-SDK-automatic-refresh-of-access-token-not-working/m-p/565385#M26557</guid>
      <dc:creator>Dame1701</dc:creator>
      <dc:date>2021-12-21T10:25:01Z</dc:date>
    </item>
    <item>
      <title>Re: Dropbox .net SDK, automatic refresh of access token not working</title>
      <link>https://www.dropboxforum.com/t5/Dropbox-API-Support-Feedback/Dropbox-net-SDK-automatic-refresh-of-access-token-not-working/m-p/565389#M26558</link>
      <description>&lt;P&gt;I've managed to sort the issue. Debugging through the SDK source code, I could see that I wasn't setting the AppSecret, though from the comments in the SDK, it appears that this is not critical. However when I changed the code I use to create the Dropbox client and used the overload that includes the AppSecret, the SDK was able to retrieve a refresh token.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;It would be useful if the proper error messages received from the server is returned from the API call. For example when the RefreshAccessToken method is called in the DropboxRequestHandler, the call to&amp;nbsp;response.EnsureSuccessStatusCode() (on line 288) throws an exception which causes the method to only return the basic information, in this case BadRequest provided by that exception. Instead, what you really should be doing is creating some custom code to handle a non Success status code then if possible, you need to be parsing the Content of the response like you do for a successful request i.e.&amp;nbsp;&amp;nbsp;var json = JObject.Parse(await response.Content.ReadAsStringAsync()) which will then provide you with additional error information that you can pass on to the user which will at least give them a clue, in my case it was the "No auth function available for given request" message which provided a bit of a clue.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;For example, something a bit like this.....&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;LI-CODE lang="csharp"&gt;string Error = null;

try
{
response.EnsureSuccessStatusCode();
}
catch (Exception ex)
{
Error = ex.Message
}

var json = JObject.Parse(await response.Content.ReadAsStringAsync());

if (!string.IsNullOrEmpty(Error)
{
// Do something with the decoded json data and then maybe throw a new exception with this data
}


            if (response.IsSuccessStatusCode)
            {
                var json = JObject.Parse(await response.Content.ReadAsStringAsync());
                string accessToken = json["access_token"].ToString();
                DateTime tokenExpiration = DateTime.Now.AddSeconds(json["expires_in"].ToObject&amp;lt;int&amp;gt;());
                this.options.OAuth2AccessToken = accessToken;
                this.options.OAuth2AccessTokenExpiresAt = tokenExpiration;
                return true;
            }

            return false;&lt;/LI-CODE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Also, since in this case it was the lack of AppSecret that was causing the issue, an error reflecting this would be very useful.&lt;/P&gt;</description>
      <pubDate>Tue, 21 Dec 2021 10:44:53 GMT</pubDate>
      <guid>https://www.dropboxforum.com/t5/Dropbox-API-Support-Feedback/Dropbox-net-SDK-automatic-refresh-of-access-token-not-working/m-p/565389#M26558</guid>
      <dc:creator>Dame1701</dc:creator>
      <dc:date>2021-12-21T10:44:53Z</dc:date>
    </item>
    <item>
      <title>Re: Dropbox .net SDK, automatic refresh of access token not working</title>
      <link>https://www.dropboxforum.com/t5/Dropbox-API-Support-Feedback/Dropbox-net-SDK-automatic-refresh-of-access-token-not-working/m-p/565484#M26566</link>
      <description>&lt;P&gt;Thanks for writing this up. I'm glad to hear you already sorted this out. I'll ask the team to improve the error reporting.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;For reference, there are two ways to request offline access. One requires the app secret when performing a refresh, and one does not:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;using PKCE: This is meant for client-side apps and does not require the app secret. There's &lt;A href="https://github.com/dropbox/dropbox-sdk-dotnet/blob/main/dropbox-sdk-dotnet/Examples/OAuthPKCE/Program.cs" target="_self"&gt;an example here&lt;/A&gt;.&lt;/LI&gt;
&lt;LI&gt;not using PKCE: This is meant for server-side apps and does require the app secret. There's &lt;A href="https://github.com/dropbox/dropbox-sdk-dotnet/blob/main/dropbox-sdk-dotnet/Examples/OauthBasic/Program.cs" target="_self"&gt;an example here&lt;/A&gt;.&lt;/LI&gt;
&lt;/UL&gt;</description>
      <pubDate>Tue, 21 Dec 2021 18:55:52 GMT</pubDate>
      <guid>https://www.dropboxforum.com/t5/Dropbox-API-Support-Feedback/Dropbox-net-SDK-automatic-refresh-of-access-token-not-working/m-p/565484#M26566</guid>
      <dc:creator>Greg-DB</dc:creator>
      <dc:date>2021-12-21T18:55:52Z</dc:date>
    </item>
  </channel>
</rss>

