Search code examples
asp.netdropboxsharpbox

401 System.UnauthorizedAccessException when access Dropbox With SharpBox API


The code

config = CloudStorage.GetCloudConfigurationEasy(nSupportedCloudConfigurations.DropBox) 
    as DropBoxConfiguration;
//config.AuthorizationCallBack = new Uri("http://localhost:61926/DBoxDemo.aspx");

requestToken = DropBoxStorageProviderTools.GetDropBoxRequestToken(config, "KEY", "SECRET");
//Session["requestToken"] = requestToken;

string AuthoriationUrl = DropBoxStorageProviderTools.GetDropBoxAuthorizationUrl(
    config, requestToken);
Process.Start(AuthoriationUrl);
accessToken = DropBoxStorageProviderTools.ExchangeDropBoxRequestTokenIntoAccessToken(
    config, "xxxxxxxxxxxxx", "xxxxxxxxxxxxx", requestToken);

CloudStorage dropBoxStorage = new CloudStorage();

var storageToken = dropBoxStorage.Open(config, accessToken);
var publicFolder = dropBoxStorage.GetFolder("/");

// upload a testfile from temp directory into public folder of DropBox
String srcFile = Environment.ExpandEnvironmentVariables(@"C:\Test\MyTestFile.txt");
var rep = dropBoxStorage.UploadFile(srcFile, publicFolder);
MessageBox.Show("Uploaded Successfully..");

**dropBoxStorage.DownloadFile("/MyTestFile.txt",
Environment.ExpandEnvironmentVariables("D:\\test"));**

MessageBox.Show("Downloaded Successfully..");
dropBoxStorage.Close();

This is the Error shown in Visual Studio.

Screenshot


Solution

  • SharpBox has a bug that only occurs in .NET 4.5, because the behavior of the class System.Uri has changed from 4.0 to 4.5.

    The method GetDownloadFileUrlInternal() in DropBoxStorageProviderService.cs generates an incorrect URL, because it changes a slash in %2f. In .NET 4.0, this URL will be converted correctly back through the System.Uri object in the method GenerateSignedUrl() in OAuthUrlGenerator.cs.

    I have changed the method GetDownloadFileUrlInternal() from this...

    public static String GetDownloadFileUrlInternal(IStorageProviderSession session, ICloudFileSystemEntry entry)
    {
        // cast varibales
        DropBoxStorageProviderSession dropBoxSession = session as DropBoxStorageProviderSession;
    
        // gather information
        String rootToken = GetRootToken(dropBoxSession);
        String dropboxPath = GenericHelper.GetResourcePath(entry);
    
        // add all information to url;
        String url = GetUrlString(DropBoxUploadDownloadFile, session.ServiceConfiguration) + "/" + rootToken;
    
        if (dropboxPath.Length > 0 && dropboxPath[0] != '/')
            url += "/";
    
        url += HttpUtilityEx.UrlEncodeUTF8(dropboxPath);
    
        return url;
    } 
    

    ...to this...

    public static String GetDownloadFileUrlInternal(IStorageProviderSession session, ICloudFileSystemEntry entry)
    {
        // cast varibales
        DropBoxStorageProviderSession dropBoxSession = session as DropBoxStorageProviderSession;
    
        // gather information
        String rootToken = GetRootToken(dropBoxSession);
    
        // add all information to url;
        String url = GetUrlString(DropBoxUploadDownloadFile, session.ServiceConfiguration) + "/" + rootToken;
    
        ICloudFileSystemEntry parent = entry.Parent;
        String dropboxPath = HttpUtilityEx.UrlEncodeUTF8(entry.Name);
    
        while(parent != null)
        {
            dropboxPath = HttpUtilityEx.UrlEncodeUTF8(parent.Name) + "/" + dropboxPath;
            parent = parent.Parent;
        }
    
        if (dropboxPath.Length > 0 && dropboxPath[0] != '/')
            url += "/";
    
        url += dropboxPath;
    
        return url;
    }
    

    and currently it works with .NET 4.5. It may exist a better way to fix the problem, but currently no misconduct noticed.