如何在没有看到权限屏幕的情况下login到OneDrive(在初始时间之后)

我刚开始使用OneDrive API和随附的示例程序(OneDriveApiBrowser)。

正如所料,我第一次login(使用“login到MSA …”,我被要求提供凭据,我的双因素代码,最后是一个权限屏幕,询问我是否同意应用程序要访问的权限我的OneDrive帐户。

但是,我退出程序并重新启动后,我没有login。我再次要“login到MSA …”,我不再提示input凭据(如我所料),但我提示权限屏幕再次。

有没有一种方式让应用程序login而不总是提示用户许可?

为了学习如何使用OneDrive API,我只使用了微软提供的示例代码作为位于https://github.com/OneDrive/onedrive-sdk-csharp/tree/master/samples/OneDriveApiBrowser的API的一部分。 该代码不能直接从那里下载,但在这个项目的根源, https://github.com/OneDrive/onedrive-sdk-csharp 。 这将下载API的来源以及示例代码和unit testing。

在做了更多的探索后,我终于找到了如何做到这一点。 我在这里的解释将在上面原始问题中提到的示例程序的上下文中。

在程序中,在SignIn方法中,有一些设置已经完成,包括调用OneDriveClient.GetMicrosoftAccountClient(...) ,然后调用以下内容:

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

所以,需要做两件事情。 我们需要保存上面代码的结果,然后将RefreshToken值保存在安全的地方…(这只是一个非常长的字符串)。

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

最后,我需要在OneDriveClient.GetMicrosoftAccountClient(...)调用周围放一个if ,只有当保存的刷新标记尚未保存(或者由于代码添加到注销调用而被删除OneDriveClient.GetMicrosoftAccountClient(...)时才调用它。如果我们一个保存的刷新标记,则我们调用`OneDriveClient.GetSilentlyAuthenticatedMicrosoftAccountClient(…)。 当我完成时,整个SignIn方法看起来像这样。

 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); } } } } 

为了完整,我更新了注销代码

 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); } 

应用程序需要使用wl.offline_access作用域来保存用户同意信息,并在不提示UI提示的情况下刷新访问令牌。

有关您可以在应用程序中使用的作用域的更多详细信息,请参阅https://dev.onedrive.com/auth/msa_oauth.htm#authentication-scopes