我刚开始使用OneDrive API及其附带的示例程序(OneDriveApiBrowser)。
正如预期的那样,我第一次登录时(使用“登录MSA ...”,我被要求提供凭据,我的2因素代码,最后是权限屏幕,询问我是否同意访问权限应用程序想要我的OneDrive帐户。
但是,在我退出程序并重新启动它之后,我没有登录。我重复“登录到MSA ...”并且不再提示我输入凭据(正如我所料),但我<再次使用权限屏幕提示强烈> am 。
有没有办法让应用程序重新登录而不总是提示用户许可?
要了解如何使用OneDrive API,我只使用Microsoft提供的示例代码作为位于https://github.com/OneDrive/onedrive-sdk-csharp/tree/master/samples/OneDriveApiBrowser的API的一部分。代码不能直接从那里下载,而是在这个项目的根目录https://github.com/OneDrive/onedrive-sdk-csharp。这将下载API的源代码以及示例代码和单元测试。
答案 0 :(得分:2)
在做了一些更多的探索之后,我终于找到了如何做到这一点。我在这里的解释将在上述原始问题中提到的示例程序的上下文中。
在程序中,在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...
}
最后,我需要在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);
}
答案 1 :(得分:0)
应用程序需要wl.offline_access
范围来保存用户同意信息并在没有UI提示的情况下刷新访问令牌。
有关可在应用程序中使用的范围的更多详细信息,请参阅https://dev.onedrive.com/auth/msa_oauth.htm#authentication-scopes