如何同步等待'AuthenticationContext.AcquireTokenAsync()'?
How to wait for 'AuthenticationContext.AcquireTokenAsync()' synchronouslly?
首先,我不确定这是否重要,但由于@Simon Mourier在 , I'm using the EXPERIMENTAL build of ADAL, this one[中提到的原因=42=].
在下面的代码中,我想同步检索一个AuthenticationResult
,所以,我将以同步方式等待AcquireTokenAsync
方法完成身份验证。
这是因为在授权完成后应该设置一个布尔标志 (isAuthorized = true
),但是 tgis 需要以同步方式发生,因为如果没有,那么我可以调用 class 将抛出空引用,因为对 AcquireTokenAsync
的调用未完成,因此对象为空。
下面的代码不起作用,该方法永远不会return,因为对AcquireTokenAsync
方法的调用似乎无限期地冻结了线程。
C#(可能由于在线翻译语法错误):
public void Authorize() {
// Use the 'Microsoft.Experimental.IdentityModel.Clients.ActiveDirectory' Nuget package for auth.
this.authContext = new AuthenticationContext(this.authUrl, this.cache);
this.authResult = this.authContext.AcquireTokenAsync({ "https://outlook.office.com/mail.readwrite" },
null, this.clientIdB, this.redirectUriB,
new PlatformParameters(PromptBehavior.Auto, this.windowHandleB)).Result;
// Use the 'Microsoft.Office365.OutlookServices-V2.0' Nuget package from now on.
this.client = new OutlookServicesClient(new Uri("https://outlook.office.com/api/v2.0"), () => Task.FromResult(this.authResult.Token));
this.isAuthorizedB = true;
}
VB.NET:
Public Sub Authorize()
' Use the 'Microsoft.Experimental.IdentityModel.Clients.ActiveDirectory' Nuget package for auth.
Me.authContext = New AuthenticationContext(Me.authUrl, Me.cache)
Me.authResult =
Me.authContext.AcquireTokenAsync({"https://outlook.office.com/mail.readwrite"},
Nothing, Me.clientIdB, Me.redirectUriB,
New PlatformParameters(PromptBehavior.Auto, Me.windowHandleB)).Result
' Use the 'Microsoft.Office365.OutlookServices-V2.0' Nuget package from now on.
Me.client = New OutlookServicesClient(New Uri("https://outlook.office.com/api/v2.0"),
Function() Task.FromResult(Me.authResult.Token))
Me.isAuthorizedB = True
End Sub
我做了一些研究并尝试了其他两种选择,但还是一样..
第一名:
ConfiguredTaskAwaitable<AuthenticationResult> t = this.authContext.AcquireTokenAsync(scopeUrls.ToArray(), null, this.clientIdB, this.redirectUriB, new PlatformParameters(PromptBehavior.Auto, this.windowHandleB)).ConfigureAwait(false);
this.authResult = t.GetAwaiter.GetResult();
第二名:
this.authResult == RunSync(() => { return this.authContext.AcquireTokenAsync(scopeUrls.ToArray(), null, this.clientIdB, this.redirectUriB, new PlatformParameters(PromptBehavior.Auto, this.windowHandleB)); })
private AuthenticationResult RunSync<AuthenticationResult>(Func<Task<AuthenticationResult>> func)
{
return Task.Run(func).Result;
}
How to wait for 'AuthenticationContext.AcquireTokenAsync()' synchronouslly?
我怀疑这个问题是在UI线程中调用async方法引起的。目前,我的解决方法是将调用封装到一个新的工作线程中。
private void button1_Click(object sender, EventArgs e)
{
Authorize().Wait();
}
private Task Authorize()
{
return Task.Run(async () => {
var authContext = new AuthenticationContext("https://login.microsoftonline.com/common");
var authResult = await authContext.AcquireTokenAsync
(new string[] { "https://outlook.office.com/mail.readwrite" },
null,
"{client_id}",
new Uri("urn:ietf:wg:oauth:2.0:oob"),
new PlatformParameters(PromptBehavior.Auto, null));
});
}
How to wait for 'AuthenticationContext.AcquireTokenAsync()' synchronouslly?
AcquireTokenAsync() returns "Task"。您只需要使用“.Wait()”等待它。在你的主程序中你只需要这样做:
Task<AuthenticationResult> res = authContext.AcquireTokenAsync(resourceUri, clientID, new Uri(redirectUri), new PlatformParameters(PromptBehavior.Auto));
res.Wait();
Console.WriteLine(res.Result.AccessToken);
我在 Xamarin.Android 上与这个问题斗争了 2 天。它永远不会来自 AquireTokenAsync 方法 returns。答案几乎是可笑的。您需要在 MainActivity.cs 中添加以下内容:
protected override void OnActivityResult(int requestCode, Result resultCode, Intent data)
{
base.OnActivityResult(requestCode, resultCode, data);
AuthenticationAgentContinuationHelper.SetAuthenticationAgentContinuationEventArgs(requestCode, resultCode, data);
}
有趣的是,它实际上说 ContinuationHelper... smh.
首先,我不确定这是否重要,但由于@Simon Mourier在
在下面的代码中,我想同步检索一个AuthenticationResult
,所以,我将以同步方式等待AcquireTokenAsync
方法完成身份验证。
这是因为在授权完成后应该设置一个布尔标志 (isAuthorized = true
),但是 tgis 需要以同步方式发生,因为如果没有,那么我可以调用 class 将抛出空引用,因为对 AcquireTokenAsync
的调用未完成,因此对象为空。
下面的代码不起作用,该方法永远不会return,因为对AcquireTokenAsync
方法的调用似乎无限期地冻结了线程。
C#(可能由于在线翻译语法错误):
public void Authorize() {
// Use the 'Microsoft.Experimental.IdentityModel.Clients.ActiveDirectory' Nuget package for auth.
this.authContext = new AuthenticationContext(this.authUrl, this.cache);
this.authResult = this.authContext.AcquireTokenAsync({ "https://outlook.office.com/mail.readwrite" },
null, this.clientIdB, this.redirectUriB,
new PlatformParameters(PromptBehavior.Auto, this.windowHandleB)).Result;
// Use the 'Microsoft.Office365.OutlookServices-V2.0' Nuget package from now on.
this.client = new OutlookServicesClient(new Uri("https://outlook.office.com/api/v2.0"), () => Task.FromResult(this.authResult.Token));
this.isAuthorizedB = true;
}
VB.NET:
Public Sub Authorize()
' Use the 'Microsoft.Experimental.IdentityModel.Clients.ActiveDirectory' Nuget package for auth.
Me.authContext = New AuthenticationContext(Me.authUrl, Me.cache)
Me.authResult =
Me.authContext.AcquireTokenAsync({"https://outlook.office.com/mail.readwrite"},
Nothing, Me.clientIdB, Me.redirectUriB,
New PlatformParameters(PromptBehavior.Auto, Me.windowHandleB)).Result
' Use the 'Microsoft.Office365.OutlookServices-V2.0' Nuget package from now on.
Me.client = New OutlookServicesClient(New Uri("https://outlook.office.com/api/v2.0"),
Function() Task.FromResult(Me.authResult.Token))
Me.isAuthorizedB = True
End Sub
我做了一些研究并尝试了其他两种选择,但还是一样..
第一名:
ConfiguredTaskAwaitable<AuthenticationResult> t = this.authContext.AcquireTokenAsync(scopeUrls.ToArray(), null, this.clientIdB, this.redirectUriB, new PlatformParameters(PromptBehavior.Auto, this.windowHandleB)).ConfigureAwait(false);
this.authResult = t.GetAwaiter.GetResult();
第二名:
this.authResult == RunSync(() => { return this.authContext.AcquireTokenAsync(scopeUrls.ToArray(), null, this.clientIdB, this.redirectUriB, new PlatformParameters(PromptBehavior.Auto, this.windowHandleB)); })
private AuthenticationResult RunSync<AuthenticationResult>(Func<Task<AuthenticationResult>> func)
{
return Task.Run(func).Result;
}
How to wait for 'AuthenticationContext.AcquireTokenAsync()' synchronouslly?
我怀疑这个问题是在UI线程中调用async方法引起的。目前,我的解决方法是将调用封装到一个新的工作线程中。
private void button1_Click(object sender, EventArgs e)
{
Authorize().Wait();
}
private Task Authorize()
{
return Task.Run(async () => {
var authContext = new AuthenticationContext("https://login.microsoftonline.com/common");
var authResult = await authContext.AcquireTokenAsync
(new string[] { "https://outlook.office.com/mail.readwrite" },
null,
"{client_id}",
new Uri("urn:ietf:wg:oauth:2.0:oob"),
new PlatformParameters(PromptBehavior.Auto, null));
});
}
How to wait for 'AuthenticationContext.AcquireTokenAsync()' synchronouslly?
AcquireTokenAsync() returns "Task"。您只需要使用“.Wait()”等待它。在你的主程序中你只需要这样做:
Task<AuthenticationResult> res = authContext.AcquireTokenAsync(resourceUri, clientID, new Uri(redirectUri), new PlatformParameters(PromptBehavior.Auto));
res.Wait();
Console.WriteLine(res.Result.AccessToken);
我在 Xamarin.Android 上与这个问题斗争了 2 天。它永远不会来自 AquireTokenAsync 方法 returns。答案几乎是可笑的。您需要在 MainActivity.cs 中添加以下内容:
protected override void OnActivityResult(int requestCode, Result resultCode, Intent data)
{
base.OnActivityResult(requestCode, resultCode, data);
AuthenticationAgentContinuationHelper.SetAuthenticationAgentContinuationEventArgs(requestCode, resultCode, data);
}
有趣的是,它实际上说 ContinuationHelper... smh.