解决 Microsoft Entra 应用程序代理中的跨域资源共享问题

跨域资源共享(CORS) 可能会对通过 Microsoft Entra 应用程序代理发布的应用和 API 带来挑战。 本文讨论Microsoft Entra 应用程序代理 CORS 问题和解决方案。

浏览器安全性通常阻止网页向另一个域发出请求。 此限制称为同域策略。 该策略可防止恶意站点从另一个站点读取敏感数据。 但是,有时你可能希望让其他网站调用 Web API。 CORS 是一种 W3C 标准,它指示服务器允许某些跨源请求并拒绝其他请求。

识别 CORS 问题

如果两个 URL 具有相同的方案、主机和端口(注释请求(RFC)6454,则具有相同的源,如以下示例所示:

  • http://contoso.com/foo.html
  • http://contoso.com/bar.html

这些 URL 的源与前两个 URL 不同:

  • http://contoso.net:不同域名
  • http://contoso.com:9000/foo.html:不同端口
  • https://contoso.com/foo.html:不同的方案
  • http://www.contoso.com/foo.html:不同的子域

同源策略阻止应用从其他源访问资源,除非它们使用正确的访问控制标头。 如果 CORS 标头不存在或不正确,则跨源请求会失败。

可以使用浏览器调试工具识别 CORS 问题:

  1. 打开浏览器并转到 Web 应用。
  2. 选择 F12 键以在 DevTools 中打开调试控制台。
  3. 尝试重现事务,并查看控制台消息。 CORS 违规使控制台出现关于来源的错误。

在以下屏幕截图中,选择 “试用”按钮导致出现 CORS 错误消息,指出在 https://corswebclient-contoso.msappproxy.net 标头中无法找到 Access-Control-Allow-Origin

显示 CORS 问题示例的屏幕截图。

应用代理中的 CORS 挑战

以下示例演示了典型的 Microsoft Entra 应用程序代理 CORS 方案。 内部服务器承载一个 CORSWebService web API 控制器,以及一个调用 CORSWebServiceCORSWebClient。 从 CORSWebClientCORSWebService 发出异步 JavaScript 和 XML (AJAX) 请求。

显示本地同源请求的屏幕截图。

CORSWebClient 应用在本地工作,但在通过 Microsoft Entra 应用程序代理发布时失败或显示错误。 如果 CORSWebClientCORSWebService 发布为单独的应用,则它们托管在不同的域中。 不同的域从 CORSWebClientCORSWebService 跨域发出 AJAX 请求,导致它们失败。

显示应用程序代理 CORS 请求的屏幕截图。

应用程序代理 CORS 问题的解决方案

可以通过多种方式解决上述 CORS 问题。

选项 1:设置自定义域

使用 Microsoft Entra 应用程序代理 自定义域 从同一源发布,而无需对应用源、代码或标头进行任何更改。

选项 2:发布父目录

发布这两个应用的父目录。 如果 Web 服务器上只有两个应用,则此解决方案特别有效。 与其单独发布每个应用,不如发布公共的父目录,这样可以共享相同的来源。

以下示例显示了 CORSWebClient 应用的 Microsoft Entra 应用程序代理页。 当内部 URL 设置为 contoso.com/CORSWebClient 时,应用无法成功地向 contoso.com/CORSWebService 目录发出请求,因为它们是跨源的。

显示单独发布应用的屏幕截图。

相反,请设置 内部 URL 的值以发布父目录,其中包括 CORSWebClientCORSWebService 目录:

显示发布父目录的屏幕截图。

生成的应用 URL 有效地解决了 CORS 问题:

  • https://corswebclient-contoso.msappproxy.net/CORSWebService
  • https://corswebclient-contoso.msappproxy.net/CORSWebClient

选项 3:更新 HTTP 标头

若要匹配源请求,请在 Web 服务上添加自定义 HTTP 响应标头。 在 Internet Information Services(IIS)中运行的网站使用 IIS 管理器修改标头。

显示在 IIS 管理器中添加自定义响应标头的屏幕截图。

修改不需要任何代码更改。 您可以在 Fiddler 跟踪中验证此内容。

**Post the Header Addition**\
HTTP/1.1 200 OK\
Cache-Control: no-cache\
Pragma: no-cache\
Content-Type: text/plain; charset=utf-8\
Expires: -1\
Vary: Accept-Encoding\
Server: Microsoft-IIS/8.5 Microsoft-HTTPAPI/2.0\
**Access-Control-Allow-Origin: https://corswebclient-contoso.msappproxy.net**\
X-AspNet-Version: 4.0.30319\
X-Powered-By: ASP.NET\
Content-Length: 17

选项 4:修改应用程序

可以通过添加 Access-Control-Allow-Origin 具有适当值的标头来更改应用程序以支持 CORS。 添加标头的方式取决于应用程序的代码语言。 更改代码需要付出最大的努力。

选项 5:延长访问令牌的生存期

无法解决某些 CORS 问题。 例如,应用程序重定向到 login.microsoftonline.com 进行身份验证,访问令牌过期。 然后 CORS 调用失败。 此方案的一种解决方法是延长访问令牌的生存期,以防止在用户会话期间过期。 有关详细信息,请参阅 Microsoft Entra ID 中的可配置令牌生存期。

选项 6:复杂应用程序

对于包含多个独立 Web 应用程序且使用预检(OPTIONS)请求的应用,可以使用复杂应用特性来发布这些应用程序。 有关详细信息,请参阅 了解 Microsoft Entra 应用程序代理中的复杂应用程序。