How do I login to OneDrive (after the initial time) without seeing the permissions screen

后端 未结 2 1302
不思量自难忘°
不思量自难忘° 2021-01-24 06:10

I have just started working with the OneDrive API and the sample program that comes with it (OneDriveApiBrowser).

As expected, the first time I logged in (using \"Sign I

相关标签:
2条回答
  • 2021-01-24 06:31

    After doing some more poking around, I finally found out how to do this. My explanation here will be in the context of the sample program mentioned in the original question above.

    In the program, in the SignIn method, there was some setup being done which included calling OneDriveClient.GetMicrosoftAccountClient(...), then calling the following:

    if (!this.oneDriveClient.IsAuthenticated)
    {
        await this.oneDriveClient.AuthenticateAsync();
    }
    

    So, two things needed to be done. We need the save the result from the code above, then save the RefreshToken value somewhere safe... (It's just a very long string).

    if (!this.oneDriveClient.IsAuthenticated)
    {
        AccountSession accountSession = await this.oneDriveClient.AuthenticateAsync();
        // Save accountSession.RefreshToken somewhere safe...
    }
    

    Finally, I needed to put an if around the OneDriveClient.GetMicrosoftAccountClient(...) call and only call it if the saved refresh token has not been saved yet (or as been deleted due to code added to the logout call...) If we have a saved refresh token, we call `OneDriveClient.GetSilentlyAuthenticatedMicrosoftAccountClient(...) instead. The entire SignIn method looks like this when I am done.

    private async Task SignIn(ClientType clientType)
    {
        string refreshToken = null;
        AccountSession accountSession;
    
        // NOT the best place to save this, but will do for an example...
        refreshToken = Properties.Settings.Default.RefreshToken;
    
        if (this.oneDriveClient == null)
        {
            if (string.IsNullOrEmpty(refreshToken))
            {
                this.oneDriveClient = clientType == ClientType.Consumer
                            ? OneDriveClient.GetMicrosoftAccountClient(
                                FormBrowser.MsaClientId,
                                FormBrowser.MsaReturnUrl,
                                FormBrowser.Scopes,
                                webAuthenticationUi: new FormsWebAuthenticationUi())
                            : BusinessClientExtensions.GetActiveDirectoryClient(FormBrowser.AadClientId, FormBrowser.AadReturnUrl);
            }
            else
            {
                this.oneDriveClient = await OneDriveClient.GetSilentlyAuthenticatedMicrosoftAccountClient(FormBrowser.MsaClientId,
                        FormBrowser.MsaReturnUrl,
                        FormBrowser.Scopes, 
                        refreshToken);
            }
        }
    
        try
        {
            if (!this.oneDriveClient.IsAuthenticated)
            {
                accountSession = await this.oneDriveClient.AuthenticateAsync();
                // NOT the best place to save this, but will do for an example...
                Properties.Settings.Default.RefreshToken = accountSession.RefreshToken;
                Properties.Settings.Default.Save();
            }
    
            await LoadFolderFromPath();
    
            UpdateConnectedStateUx(true);
        }
        catch (OneDriveException exception)
        {
            // Swallow authentication cancelled exceptions
            if (!exception.IsMatch(OneDriveErrorCode.AuthenticationCancelled.ToString()))
            {
                if (exception.IsMatch(OneDriveErrorCode.AuthenticationFailure.ToString()))
                {
                    MessageBox.Show(
                        "Authentication failed",
                        "Authentication failed",
                        MessageBoxButtons.OK);
    
                    var httpProvider = this.oneDriveClient.HttpProvider as HttpProvider;
                    httpProvider.Dispose();
                    this.oneDriveClient = null;
                }
                else
                {
                    PresentOneDriveException(exception);
                }
            }
        }
    }
    

    For completeness, I updated the logout code

    private async void signOutToolStripMenuItem_Click(object sender, EventArgs e)
    {
        if (this.oneDriveClient != null)
        {
            await this.oneDriveClient.SignOutAsync();
            ((OneDriveClient)this.oneDriveClient).Dispose();
            this.oneDriveClient = null;
    
            // NOT the best place to save this, but will do for an example...
            Properties.Settings.Default.RefreshToken = null;
            Properties.Settings.Default.Save();
        }
    
        UpdateConnectedStateUx(false);
    }
    
    0 讨论(0)
  • 2021-01-24 06:32

    The wl.offline_access scope is required by applications to save the user consent information and refresh the access token without a UI prompt.

    For more details on the scopes that you can use in your application see https://dev.onedrive.com/auth/msa_oauth.htm#authentication-scopes

    0 讨论(0)
提交回复
热议问题