来自 Web 应用的 Azure 异步身份验证令牌

Azure Async Authentication Token from Web App

我正在尝试从 Azure AD 系统检索身份验证令牌。我尝试了多种不同的方法来配置异步方法和 await 命令,但每次我都收到错误 "A Task was cancelled".

我的 aspx 页面中有 async="true"。

想知道我需要做哪些不同的事情才能获得成功的请求并检索令牌。

相同的代码在控制台应用程序中工作,因此,我假设问题与异步操作的发生方式有关。

我的代码如下:

protected async void Login_click(object sender, EventArgs e)
{
    response1.Text = "Started";
    var tentantID = ConfigurationManager.AppSettings["tenantID"];
    var clientId = ConfigurationManager.AppSettings["applicationID"];
    var secret = ConfigurationManager.AppSettings["secret"];

    await Authorize(tentantID , clientId, secret);
}
private async Task<AuthenticationResult> GetToken(string clientId, string tenantDomain, string clientSecret)
{
    AuthenticationResult result = null;

    var context = new AuthenticationContext("https://login.microsoftonline.com/" + tenantDomain);

    try
    {
        ClientCredential clientCredential = new ClientCredential(clientId, clientSecret);
        return result = await context.AcquireTokenAsync("https://management.core.windows.net/", clientCredential).ConfigureAwait(false);

    }   
    catch (AdalException ae)
    {
        //Error code
        return null;
    }
    catch (Exception e)
    {
        //Error code
        return null;
    }
}

private async Task Authorize(string tenant, string clientId, string clientSecret)
{
    var authenticationResult = await GetToken(clientId, tenant, clientSecret).ConfigureAwait(false);

    string token = authenticationResult.AccessToken;
}

编辑... 我更新的代码:

protected void Login_click(object sender, EventArgs e)
{
    response1.Text = "Started";

    RegisterAsyncTask(new PageAsyncTask(Authorize));
}  
public async Task Authorize()
{

    var tentantID = ConfigurationManager.AppSettings["tenantID"];
    var clientId = ConfigurationManager.AppSettings["applicationID"];
    string myKey = ConfigurationManager.AppSettings["myKey"];
    var tenantDomain = ConfigurationManager.AppSettings["tenantDomain"];

    var context = new AuthenticationContext("https://login.microsoftonline.com/" + tenantDomain, false);

    try
    {
        ClientCredential clientCredential = new ClientCredential(clientId, myKey);
        var result = context.AcquireTokenAsync("https://management.core.windows.net/", clientCredential).ConfigureAwait(false);

        AuthenticationResult resVal = await result;
        token = resVal.AccessToken;
    }
    catch (AdalException ae)
    {
        //error code
        token = ae.InnerException.Message;
    }
}

async void 方法在 ASP.NET 中不是一件好事。有关它的一些信息,请参阅 https://www.hanselman.com/blog/TheMagicOfUsingAsynchronousMethodsInASPNET45PlusAnImportantGotcha.aspx

我相信您的 Login_Click 方法应该使用此行异步调用 Authorize

RegisterAsyncTask(new PageAsyncTask(Authorize(tentantID, clientId, secret)));

然后 Login_Click 应该只是 return void 而没有 async 关键字。

根据你的描述,我已经通过在 .NET Framework 4.5 上创建我的 Web Form 应用程序目标并引用 Active Directory Authentication Library 3.13.8. Based on your code, it could work as expected on my side and deployed to Azure Web App. Here is my git sample 测试了这个问题,你可以参考它并尝试找出它是否可以作为预期。