【问题标题】:ADAL native application token expires after 12 hoursADAL 本机应用程序令牌在 12 小时后过期
【发布时间】:2017-08-04 13:08:13
【问题描述】:

我创建了 .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);
    }
}

【问题讨论】:

  • 如何在 Constants 中定义 AuthenticationContext?
  • @CuongLe 包含常量类。
  • 每次都创建AuthenticationContext,你不需要在Constant上保持静态
  • @CuongLe 你确定这会有所帮助吗? (你知道我会在 12 小时后确定它是否可以工作,或者也许有一种方法可以更快地测试它?)服务器调用呢?如果我每次都创建AuthorizationContext,这是否意味着重新创建缓存并且每次请求都会调用天蓝色服务器?
  • @CuongLe Creating AuthenticationContext 每次我发送请求时都有帮助(应用程序现在运行 30 小时没有错误)我还检查了正在发送的请求,并且似乎一旦应用程序通过身份验证它不会将请求发送到 azure 服务器 - 这很好。如果需要,您可以创建一个新答案,以便我将其标记为已解决。无论如何,谢谢。

标签: c# azure asp.net-web-api adal autorest


【解决方案1】:

问题是如何预防?

根据官方document,Access Token Lifetime 在 10 分钟到 1 天之间。所以我们可以将访问令牌的生命周期延长至 1 天,但我们无法阻止它过期。我们还可以从document 获取如何在 Azure Active Directory 中配置令牌生命周期。

获得访问令牌的恶意行为者可以在其生命周期内使用它。调整访问令牌生命周期是在提高系统性能和增加用户帐户被禁用后客户端保留访问权限之间的权衡。

当当前访问令牌过期时,我们可以使用刷新令牌来获取新的访问/刷新令牌。并且刷新令牌默认有效期为 14 天。所以我们不需要每次请求都调用所有的天蓝色服务器。当我们获得访问令牌时,我们也可以根据 ExpiresOn 获得。如果访问令牌未过期,则我们无需获取访问令牌。

var result = await authContext.AcquireTokenAsync(apiId, clientCredential);

【讨论】:

    【解决方案2】:

    您可以更改代码以每次都创建AuthenticationContext,并且无需在Constants 类上将其保留为static

    【讨论】:

      猜你喜欢
      • 2017-05-07
      • 2020-06-07
      • 2017-11-15
      • 1970-01-01
      • 2011-06-15
      • 2013-03-03
      • 2018-01-20
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多