ADAL 本机应用程序令牌在 12 小时后过期
ADAL native application token expires after 12 hours
我已经创建了 .net 控制台应用程序,它是我的网络的客户端 api。这两个应用程序都在 azure 中注册。我希望我的控制台应用程序在没有用户交互的情况下 运行。控制台应用程序检查消息 queue,如果消息到达,它会进行一些计算并将数据发送回我的网站 api。我使用 adal 来验证我的连接。我通过密钥进行身份验证。由于我的客户端使用 AutoRest 生成的代码,我添加了 DelegatingHandler 来捕获每个请求并在发送之前添加授权 header:
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
方法负责令牌过期。我错过了什么吗?
编辑:
常量 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);
}
}
The question is how do I prevent it?
根据官方document, Access Token Lifetime is between 10 minutes to 1 day. So we can extend the Access token lifetime up to 1 days, but we can't prevent it expiration. We also can get the way how to Configurable Token Lifetimes in Azure Active Directory from the document.
A malicious actor that has obtained an access token can use it for extent of its lifetime. Adjusting access token lifetime is a trade-off between improving system performance and increasing the amount of time that the client retains access after the user’s account is disabled.
当当前访问令牌过期时,我们可以使用刷新令牌获取新的access/fresh令牌。并且刷新令牌默认有效期为 14 天。所以我们不需要为每个请求调用所有的 azure 服务器。我们也可以在获取access token的时候根据ExpiresOn获取。如果访问令牌没有过期,那么我们就不需要获取访问令牌。
var result = await authContext.AcquireTokenAsync(apiId, clientCredential)
;
您可以更改代码以每次创建 AuthenticationContext
,而无需在 Constants
class
上将其保留为 static
我已经创建了 .net 控制台应用程序,它是我的网络的客户端 api。这两个应用程序都在 azure 中注册。我希望我的控制台应用程序在没有用户交互的情况下 运行。控制台应用程序检查消息 queue,如果消息到达,它会进行一些计算并将数据发送回我的网站 api。我使用 adal 来验证我的连接。我通过密钥进行身份验证。由于我的客户端使用 AutoRest 生成的代码,我添加了 DelegatingHandler 来捕获每个请求并在发送之前添加授权 header:
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
方法负责令牌过期。我错过了什么吗?
编辑: 常量 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);
}
}
The question is how do I prevent it?
根据官方document, Access Token Lifetime is between 10 minutes to 1 day. So we can extend the Access token lifetime up to 1 days, but we can't prevent it expiration. We also can get the way how to Configurable Token Lifetimes in Azure Active Directory from the document.
A malicious actor that has obtained an access token can use it for extent of its lifetime. Adjusting access token lifetime is a trade-off between improving system performance and increasing the amount of time that the client retains access after the user’s account is disabled.
当当前访问令牌过期时,我们可以使用刷新令牌获取新的access/fresh令牌。并且刷新令牌默认有效期为 14 天。所以我们不需要为每个请求调用所有的 azure 服务器。我们也可以在获取access token的时候根据ExpiresOn获取。如果访问令牌没有过期,那么我们就不需要获取访问令牌。
var result = await authContext.AcquireTokenAsync(apiId, clientCredential)
;
您可以更改代码以每次创建 AuthenticationContext
,而无需在 Constants
class
static