How to silently get access token to user subscript

2019-09-14 16:37发布

i am working on project, where we have service that run computation on Azure Batch in user subscription mode (because we are using custom image). I have now my code fully working, but it requires every launch to provide user credentials to log into Azure Active Directory app before it can create Batch pools and so on. Because it will run as background service, i need to log in silently with some provided user without popup asking user to log in.

I have registered native app in Azure and set its access to Azure Batch service, created Azure AD user, and got all ids and names from it.

Here is my code i am using now.

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)))
{
    ...
}

Classic way with AquireToken with popup for login is working fine. I have tried to use AquireTokenSilent (as is shown in code), but i am getting error about no token cache and need to call AquireToken.

Id used in UserIdentifier is user id guid taken from Azure Active Directory user blade.

Does anybody know, how to update my code so i will be able to silently log into Azure Batch with specified user and is this even possible?

Thanks for help.

1条回答
Summer. ? 凉城
2楼-- · 2019-09-14 17:11

AcquireTokenSilent is not meant for this use case. It will try to get the token from the cache where it was previously stored by AcquireTokenAsync.

And AcquireTokenAsync will pop up a login dialog, so you can't use that in your batch app either.

Take a look at either authenticating with a certificate or with username/password.

In the first sample, you need to create a ClientAssertionCertificate with

certCred = new ClientAssertionCertificate(clientId, cert);

this is then used for AcquireTokenAsync:

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

The other sample creates a UserPasswordCredential with

var uc = new UserPasswordCredential(user, password);

and then also uses it with AcquireTokenAsync in a slightly different way:

authContext.AcquireTokenAsync(todoListResourceId, clientId, uc);

There are some limitations as to what you can do with the tokens that are based on the two different authentication methods. For example, using the access token for EWS Impersonation requires using the certificate method.

查看更多
登录 后发表回答