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);
}
}
You can change the code to create AuthenticationContext
everytime and noneed to keep it as static
on Constants
class