我创建了.net控制台应用程序,它是我的web api的客户端。这两个应用都是在azure中注册的。我想我的控制台应用程序无需用户交互即可运行。控制台应用程序检查消息队列,如果消息到达,它会进行一些计算并将数据发送回我的web api。我使用adal来验证我的连接。我通过密钥进行身份验证。由于我的客户端使用AutoRest生成的代码,我添加了DelegatingHandler以捕获每个请求并在发送之前添加授权标头:
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);
}
}
正如您所看到的,我正在使用已定义的授权上下文。感谢上面的代码我可以在没有用户交互的情况下获得令牌。这项工作就好了! 然而 12小时后,应用程序开始返回Unauthorized
错误。问题是我该如何预防呢?我认为AcquireToken
方法负责令牌过期。我错过了什么吗?
修改 常数类:
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);
}
}
答案 0 :(得分:1)
您可以更改代码以便每次创建AuthenticationContext
而无需将其保留为static
类Constants
答案 1 :(得分:0)
问题是如何防止它?
根据官方document,访问令牌生命周期介于10分钟到1天之间。因此,我们可以将访问令牌生命周期延长至1天,但我们无法阻止其到期。我们还可以从document了解如何在Azure Active Directory中配置令牌生存期。
获得访问令牌的恶意行为者可以在其生命周期内使用它。调整访问令牌生存期是在提高系统性能和增加客户端在禁用用户帐户后保留访问权限的时间之间的权衡。
当前访问令牌到期时,我们可以使用刷新令牌来保留新访问/新令牌。并且刷新令牌默认到期14天。所以我们不需要为每个请求调用所有azure服务器。当我们获得访问令牌时,我们也可以根据ExpiresOn获取。如果访问令牌未过期,则我们无需获取访问令牌。
var result = await authContext.AcquireTokenAsync(apiId, clientCredential)
;