如何同步等待"AuthenticationContext.AcquireTokenAsync()"? [英] How to wait for 'AuthenticationContext.AcquireTokenAsync()' synchronouslly?

查看:124
本文介绍了如何同步等待"AuthenticationContext.AcquireTokenAsync()"?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

首先,我不确定这是否重要,但出于@ Simon Mourier 这一个 .

First of all, I'm not sure if this is important, but for the reasons mentioned by @Simon Mourier in him answer, I'm using the EXPERIMENTAL build of ADAL, this one.

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

In the code below, I would like to retrieve an AuthenticationResult synchronouslly, so, I will wait for completition of the authentication by AcquireTokenAsync method in a synchronous manner.

这是因为应该在授权完成后设置布尔标志(isAuthorized = true),但是tgis必须以同步方式发生,因为如果没有,那么我可以调用该类的其他方法来抛出一个空引用,因为对AcquireTokenAsync的调用未完成,因此该对象为空.

This is because a boolean flag should be set after the authorization is done (isAuthorized = true), but tgis need to happen in a synchronous way, because if not, then I can call other methods of the class that will throw a null reference because the call to AcquireTokenAsync didn't finished so the object is null.

以下代码不起作用,该方法将永远不会返回,因为对AcquireTokenAsync方法的调用似乎无限期地冻结了线程.

The following code does not work, the method will never return, because the call to AcquireTokenAsync method seems that indefinitely freezes the thread.

C#(由于在线翻译,语法可能不正确):

C# (maybe wrong syntax due to online translation):

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

我做了一些研究,并尝试了其他两种选择,但是发生的情况相同.

I researched a little bit and I tried other two alternatives, but happens the same..

第一:

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

推荐答案

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

How to wait for 'AuthenticationContext.AcquireTokenAsync()' synchronouslly?

我怀疑此问题是由在UI线程中调用async方法引起的.目前,我的解决方法是将调用包装为新的工作线程.

I suspect this issue is caused by calling the async method in the UI thread. Currently, my workaround is wrapping the call a new work thread.

    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()"?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆