azure-active-directory - 调用 .\auth\refresh 端点后 Azure 应用服务身份验证令牌未刷新
问题描述
我有一个托管在一个 azure windows 应用程序服务中的 Angular 应用程序和一个托管在另一个中的 asp.net 核心 api,两者都使用应用程序服务身份验证功能进行保护。我正在使用目前有两台服务器的应用服务计划。我正在使用令牌存储,它正在使用文件系统来存储令牌。
当 Angular 应用程序调用 api 时,它需要在授权标头中传递访问令牌。通过在 \.auth\me 端点上执行 GET 并将 AppServiceAuthSession cookie 作为凭据发送来检索访问令牌。然后将返回的令牌缓存在会话存储中并用于后续请求,直到令牌过期。当令牌过期时,我调用 \.auth\refresh 端点(并发送 AppServiceAuthSession cookie),然后调用 \.auth\me 以获取刷新的令牌。
所有这些在一台服务器上运行时运行良好,但是当应用服务计划扩展到 2 台或更多台服务器时,对 \.auth\refresh 的调用会成功,但随后对 .auth\me 端点的调用会获得一个已过期的令牌。我可以通过检查内部 exp 声明来判断令牌已过期,并且当它通常会成功时,对 api 的调用也会失败并显示 401 Unauthorized。
如果我缩减到一台服务器,问题就会消失,如果我启用 ARR 亲和性,问题就会消失,但我不想仅仅为了解决这个问题而启用亲和性。
解决方案
当它通常会成功时,对 api 的调用也会失败,并显示 401 Unauthorized。
您不应该调用/.auth/refresh
API 应用程序。身份验证令牌是在 WEB 应用程序上生成的, 因此 您需要/.auth/refresh
在WEB 应用程序上调用。
如果您需要不记名令牌的替代品,您可以使用客户端请求中的AppServiceAuthSession cookie 到/.auth/refresh
.
然后将返回的令牌缓存在会话存储中并用于后续请求,直到令牌过期。当令牌过期时,我调用 .auth\refresh 端点(并发送 AppServiceAuthSession cookie),然后调用 .auth\me 以获取刷新的令牌。
为了确保正确捕获上下文,我们有一个面向用户的 Web 应用程序,该应用程序反过来调用 API 后端,该后端又调用 MSFT 图。我们期望在每个阶段都有不同的 AAD 注册:
- Web应用注册(API应用权限)
- API 应用注册(获得Microsoft Graph的许可)
因为这似乎与添加图形权限有关,所以我们的第一个猜测是用户尚未对 Microsoft Graph 授权。如果您只是刷新现有令牌,则没有机会获得该同意,因为不涉及用户。您必须让用户使用明确的同意提示重新登录,这可以通过 /.auth/login/aad?prompt=consent
调用来实现。但是,我们不希望这会导致过期错误。缓存的过期值可能被用作该权限错误的后备,但我猜。康纳将不得不在那里权衡。
另一条很好的信息是来自实际身份验证/授权层本身的日志,尤其是在出现错误消息的情况下。要获取这些日志:
- 从门户中的应用程序(API 应用程序是我最感兴趣的):“平台功能”>“诊断日志”。将“应用程序日志记录(文件系统)”更改为“开启”并将级别设置为“详细”。点击保存。
- 返回“平台功能”>“日志流”并在重现问题时保持该窗口打开(在这种情况下,调用 API 应用程序)
实际上,问题在于/.auth/refresh
API 不适用于 AAD 不记名令牌。相反,您需要使用会话 cookie ( AppServiceAuthSession cookie) 或会话令牌 ( x-zumo-auth标头),它们是登录操作的输出。有关更多信息 - 请参阅此处#refreshing-the-access-tokens
推荐阅读
- azure - 远程创建 azure devops windows 自托管代理
- attributes - NUnit 属性来模拟基于条件的 Assert.Inconclusive 与自定义消息文本
- html - 如何在不使用网格的情况下使用 css 创建 3 列布局(即 10 兼容性)
- excel - 列表框按所选项目移动滚动
- typescript - 复合类型中的 TypeScript 字符串联合类型推断问题
- react-native - 如何使用 detox 处理纯原生元素
- javascript - 如何使用 Javascript 获取按钮,当用户点击它时,在两个按钮中执行 myFunction
- solr - 字典中不存在给定的键。- 异常 Solrnet 和 CommonServicelocator
- scala - Spark 中 col("*") 中的星号有什么作用?
- c# - 我想将一个布尔列表绑定到 DataGridRows(除了真实数据),一个项目到一个网格行以使用数据触发器