Search code examples
c#azureasp.net-web-apiadalautorest

ADAL native application token expires after 12 hours


I've created the .net console application which is the client of my web api. Both apps are registered in azure. I want my console app to run without user interaction. Console app checks the message queue and if the message arrives, it does some calculation and sends back the data to my web api. I use adal to authenticate my connection. I authenticate by secret key. Since my client uses generated code by AutoRest I added DelegatingHandler to catch every request and add the authorization header before i send it:

public class ClientHandler : DelegatingHandler
{
    protected async override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
    {
        AuthenticationContext authContext = Constants.authContext;
        ClientCredential clientCredential = Constants.clientCredential;
        string apiId = Constants.apiId;
        string tokenType = Constants.tokenType;

        // ADAL includes token in memory cache, so this call will only send a message to the server if the cached token is expired.
        var result = await authContext.AcquireTokenAsync(apiId, clientCredential);
        request.Headers.Authorization = new AuthenticationHeaderValue(tokenType, result.AccessToken);

        return await base.SendAsync(request, cancellationToken);
    }
}

As you can see I am using already defined authorization context. Thanks to code above I can get the token without user interaction. And this work just fine! However after 12 hours the application starts returning Unauthorized error. The question is how do I prevent it? I thought that AcquireToken method takes care of the token expiration. Am I missing something?

EDIT: Constant class:

public static class Constants
{
    public static string aadInstance = ConfigurationManager.AppSettings["aadInstance"];
    public static string tenant = ConfigurationManager.AppSettings["aadTenantName"];
    // this application id
    public static string clientId = ConfigurationManager.AppSettings["clientApi:ClientId"];
    // the key which it can be authenticated
    public static string appKey = ConfigurationManager.AppSettings["clientApi:AppKey"];
    // the id of the api
    public static string apiId = ConfigurationManager.AppSettings["apiId"];
    public static string authority = String.Format(CultureInfo.InvariantCulture, aadInstance, tenant);
    public static string tokenType = ConfigurationManager.AppSettings["TokenType"];
    public static AuthenticationContext authContext = null;
    public static ClientCredential clientCredential = null;

    public static async Task<TokenCredentials> Authenticate()
    {
        authContext = new AuthenticationContext(authority);
        clientCredential = new ClientCredential(clientId, appKey);
        var result = await authContext.AcquireTokenAsync(apiId, clientCredential);
        return new TokenCredentials(result.AccessToken, tokenType);
    }
}

Solution

  • You can change the code to create AuthenticationContext everytime and noneed to keep it as static on Constants class