You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Microsoft Graph API:配置用于资源长期访问的刷新令牌

问题场景

我在C#桌面应用中实现了代表用户请求令牌的逻辑,使用的NuGet包如下:

<PackageReference Include="Azure.Identity" Version="1.10.3" />    
<PackageReference Include="Microsoft.Graph" Version="5.34.0" />

使用的scopes为presence.read.all、offline_access,并实现了令牌缓存,核心代码如下:

if (!File.Exists(AUTH_RECORD_PATH))
{
    // 配置TokenCachePersistenceOptions确保令牌缓存持久化到磁盘,可指定缓存名称避免被其他应用清理
    interactiveBrowserCredential = new InteractiveBrowserCredential(
        new InteractiveBrowserCredentialOptions
        {
            ClientId = clientId,
            TenantId = tenantId,
            RedirectUri = new Uri("http://localhost"),
            TokenCachePersistenceOptions = new TokenCachePersistenceOptions
            {
                Name = TOKEN_CACHE_NAME,
            }
        });

    // 获取新的AuthenticationRecord
    authenticationRecord = await interactiveBrowserCredential.AuthenticateAsync(new TokenRequestContext(scopes));

    // 将AuthenticationRecord序列化到磁盘,方便跨会话复用
    using FileStream authRecordStream = new FileStream(AUTH_RECORD_PATH, FileMode.Create, FileAccess.Write);
    await authenticationRecord.SerializeAsync(authRecordStream);
}
else
{
    // 从磁盘加载并反序列化之前的AuthenticationRecord
    using FileStream authRecordStream = new FileStream(AUTH_RECORD_PATH, FileMode.Open, FileAccess.Read);
    authenticationRecord = await AuthenticationRecord.DeserializeAsync(authRecordStream);

    // 基于已有的AuthenticationRecord和缓存配置构造Credential
    interactiveBrowserCredential = new InteractiveBrowserCredential(
        new InteractiveBrowserCredentialOptions
        {
            ClientId = clientId,
            TenantId = tenantId,
            TokenCachePersistenceOptions = new TokenCachePersistenceOptions { Name = TOKEN_CACHE_NAME },
            AuthenticationRecord = authenticationRecord
        });
}

return interactiveBrowserCredential;

我存在以下疑问:

  1. 官方文档提到offline_access表示应用需要刷新令牌以实现长期访问资源,但本地存储的令牌(或刷新令牌)是永久有效,还是会在1天、1周、1个月或1年后过期?
  2. 查看本地生成的认证记录文件,内容如下,里面没有密钥、哈希或OAuth令牌等敏感内容,这和预期不符,为什么?
{
    "username": "some@upn.com",
    "authority": "login.microsoftonline.com",
    "homeAccountId": "7f3283e3-f2e9-4070-a3d6-21e621442fc3.cf44c34e-c137-4175-9201-126baf8a9eb8",
    "tenantId": "536c1e89-823c-4204-a466-5c56ca24f873",
    "clientId": "0c9d7e7f-8b0c-4f97-ab31-ba6d0424ba80",
    "version": "1.0"
}
  1. 如何查询当前“长期访问”的实际时长?能否自定义时长(例如设置30天后过期)?
  2. 在Microsoft Entra管理中心的应用设置中未找到令牌生命周期配置,该如何处理?
解答

1. 刷新令牌的默认过期时长

offline_access授予的刷新令牌默认有效期为90天,同时存在以下规则:

  • 每次使用刷新令牌获取新访问令牌时,刷新令牌会被轮换(返回新的刷新令牌),有效期重新计算90天。
  • 若刷新令牌连续90天未被使用,会永久失效;用户更改密码、撤销应用权限,或管理员手动撤销令牌时,刷新令牌也会立即失效。

2. 本地认证记录不含敏感内容的原因

你本地存储的是AuthenticationRecord,它仅作为账户身份标识,并非实际的令牌缓存:

  • 访问令牌、刷新令牌等敏感内容,由TokenCachePersistenceOptions负责存储,默认会存入操作系统的安全存储(如Windows的凭据管理器、macOS的Keychain、Linux的libsecret),不会明文保存在你指定的文件中。
  • AuthenticationRecord的作用是告知InteractiveBrowserCredential要关联哪个用户的令牌缓存,因此仅包含账户基本标识信息,无敏感数据。

3. 查询与自定义长期访问时长

查询实际时长

  • 调用GetTokenAsync获取令牌后,可解析返回的AccessToken(JWT格式),其中的exp字段为过期时间戳,转换后即可得到实际过期时长。
  • 若使用Microsoft Graph查询,需具备AuditLog.Read.All权限,调用/auditLogs/signIns接口查看相关会话的过期信息。

自定义时长

  • 桌面应用属于公共客户端,无法直接自定义刷新令牌有效期,该时长由Microsoft Entra的默认策略控制。
  • 企业租户管理员可通过令牌生命周期策略调整,但该功能仅适用于机密客户端(如Web应用),公共客户端暂不支持自定义。

4. Entra管理中心找不到令牌生命周期配置的处理

  • 令牌生命周期策略不在应用注册的常规设置中,需通过以下方式访问:
    1. 进入Microsoft Entra管理中心,搜索并进入令牌生命周期策略页面(可从“Identity”>“Applications”下的“Enterprise applications”入口查找,或直接搜索)。
    2. 注意:该功能需要Azure AD Premium P1/P2许可证,且仅对机密客户端生效,公共客户端(如你的桌面应用)无法通过此方式调整刷新令牌有效期。
  • 若没有Premium许可证,只能使用默认的90天刷新令牌有效期,无法自定义。

内容的提问来源于stack exchange,提问作者DominikAmon

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 11:10:58