如何同步等待’AuthenticationContext.AcquireTokenAsync()’?

首先,我不确定这是否重要,但由于@ Simon Mourier他回答中提到的原因,我正在使用ADAL的EXPERIMENTAL版本, 这个


在下面的代码中,我想同步检索AuthenticationResult ,因此,我将等待AcquireTokenAsync方法以同步方式完成身份validation的AcquireTokenAsync

这是因为在授权完成后应该设置一个布尔标志( isAuthorized = true ),但是tg需要以同步的方式发生,因为如果没有,那么我可以调用该类的其他方法,这将引发一个空引用,因为对AcquireTokenAsync的调用没有完成,因此对象为null。

以下代码不起作用,该方法永远不会返回,因为对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 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(Func<Task> func) { return Task.Run(func).Result; } 

如何同步等待’AuthenticationContext.AcquireTokenAsync()’?

我怀疑这个问题是由在UI线程中调用异步方法引起的。 目前,我的解决方法是将调用包装为新的工作线程。

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

如何同步等待’AuthenticationContext.AcquireTokenAsync()’?

AcquireTokenAsync()返回“任务”。 你只需要使用“.Wait()”等待它。 在您的主程序中,您只需要这样做:

 Task res = authContext.AcquireTokenAsync(resourceUri, clientID, new Uri(redirectUri), new PlatformParameters(PromptBehavior.Auto)); res.Wait(); Console.WriteLine(res.Result.AccessToken); 

我在Xamarin.Android上解决了这个问题2天。 它永远不会从AquireTokenAsync方法返回。 答案几乎是滑稽的。 您需要在MainActivity.cs中添加以下内容:

  protected override void OnActivityResult(int requestCode, Result resultCode, Intent data) { base.OnActivityResult(requestCode, resultCode, data); AuthenticationAgentContinuationHelper.SetAuthenticationAgentContinuationEventArgs(requestCode, resultCode, data); } 

有趣的是,它实际上说ContinuationHelper …… smh。