如何静默获取用户订阅 Azure Batch 的访问令牌?

How to silently get access token to user subscription Azure Batch?

我正在做一个项目,我们在 Azure Batch 上以用户订阅模式提供 运行 计算服务(因为我们使用的是自定义图像)。现在我的代码已完全运行,但它需要每次启动都提供用户凭据以登录到 Azure Active Directory 应用程序,然后才能创建批处理池等。因为它将 运行 作为后台服务,所以我需要与一些提供的用户静默登录,而不需要弹出窗口要求用户登录。

我已经在 Azure 中注册了本机应用程序并设置了它对 Azure Batch 服务的访问权限,创建了 Azure AD 用户,并从中获取了所有 ID 和名称。

这是我现在使用的代码。

private const string AuthorityUri = "https://login.microsoftonline.com/common";
private const string BatchResourceUri = "https://batch.core.windows.net";

private const string BatchAccountEndpoint = "https://<BATCH SERVICE NAME>.westeurope.batch.azure.com";
private const string ClientId = "<AZURE APP GUID ID>";

...

public static async Task<string> GetAuthenticationTokenAsync()
{
    var authContext = new AuthenticationContext(AuthorityUri);

    //here it will throw exception about no token found in cache and to call AquireToken
    var authResult = await authContext.AcquireTokenSilentAsync(BatchResourceUri, ClientId, new UserIdentifier("<AD USER GUID ID>", UserIdentifierType.UniqueId));

    //this works fine, but show popup dialog for login
    /*var authResult = await authContext.AcquireTokenAsync(BatchResourceUri,
                                                            ClientId,
                                                            new Uri(RedirectUri),
                                                            new PlatformParameters(PromptBehavior.Auto));*/

    return authResult.AccessToken;
}

...

Func<Task<string>> tokenProvider = () => GetAuthenticationTokenAsync();


using (BatchClient batchClient = await BatchClient.OpenAsync(new BatchTokenCredentials(BatchAccountEndpoint, tokenProvider)))
{
    ...
}

带有用于登录的弹出窗口的 AquireToken 的经典方式工作正常。我尝试使用 AquireTokenSilent(如代码中所示),但我收到关于没有令牌缓存的错误,需要调用 AquireToken。

UserIdentifier 中使用的 ID 是从 Azure Active Directory 用户 blade 中获取的用户 ID guid。

有谁知道如何更新我的代码,以便我能够以指定用户静默登录 Azure Batch,这是否可能?

感谢您的帮助。

AcquireTokenSilent 不适用于此用例。它将尝试从先前由 AcquireTokenAsync.

存储的缓存中获取令牌

并且 AcquireTokenAsync 会弹出一个登录对话框,因此您也不能在批处理应用程序中使用它。

看看使用 certificate or with username/password 进行身份验证。

在第一个示例中,您需要创建一个 ClientAssertionCertificate

certCred = new ClientAssertionCertificate(clientId, cert);

然后用于 AcquireTokenAsync:

result = await authContext.AcquireTokenAsync(todoListResourceId, certCred);

另一个示例创建了 UserPasswordCredential

var uc = new UserPasswordCredential(user, password);

然后还以稍微不同的方式将其与 AcquireTokenAsync 一起使用:

authContext.AcquireTokenAsync(todoListResourceId, clientId, uc);

使用基于两种不同身份验证方法的令牌可以执行的操作存在一些限制。例如,使用 EWS 模拟的访问令牌需要使用证书方法。