我的 Office 加载项中的 Javascript 位于哪个域

On what domain is my Javascript in my Office Add-In

我们在 OWA 中有一个 Outlook 加载项运行。

当我从 JavaScript 中发出调用以响应加载项命令时,我在 ajax 调用中使用格式 https://company.ourdomain.com/api/Controller/Action

我最终遇到了其中一个 CORS 错误(有时是飞行前错误,有时是 CORB)。如果 Javascript 实际上与 Web 服务位于同一域中,为什么我会收到此消息?

我假设我已经通过身份验证,因为我已经登录到我的 Outlook 帐户。

什么给了?

注意: 作为实验,我尝试通过直接输入 URL 来调用 RESTful(不涉及 OWA)。这导致代码针对 Azure AD 进行身份验证。然后我在同一个浏览器会话中登录到 OWA,一切正常。我是否真的需要在 Javascript 中进行身份验证,即使我调用的网络服务位于同一域中?

AJAX 产生错误的调用 请记住,在我通过直接从浏览器

调用我的 Web 服务来进行 RESTful 调用后,它会正常工作
    var apiUri = '/api/People/ShowRecord';


$.ajax({
    url: apiUri,
    type: 'POST',
    data: JSON.stringify(serviceRequest),
    contentType: 'application/json; charset=utf-8',
    dataType: 'json'
}).done(function (response) {
    if (!response.isError) {
        // response to successful call
    }
    else {
        // ... 
    }
}).fail(function (status) {
    // some other response
}).always(function () {

    console.log("Completed");
});

观察 当我从地址栏调用 api 时,下面的代码是 运行。此代码永远不会被 Javascript

调用
[assembly: OwinStartup(typeof(EEWService.AuthStartup))]

namespace EEWService
{
    public partial class AuthStartup
    {
        public void Configuration(IAppBuilder app)
        { app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);
        app.UseCookieAuthentication(new CookieAuthenticationOptions());

        app.UseWsFederationAuthentication(
            new WsFederationAuthenticationOptions
            {

                Notifications = new WsFederationAuthenticationNotifications
                {
                    RedirectToIdentityProvider = (context) =>
                    {
                        context.ProtocolMessage.Whr = "ourdomain.com";
                        return Task.FromResult(0);
                    }
                },

                MetadataAddress = ConfigurationManager.AppSettings["ida:MetadataAddress"],
                Wtrealm = ConfigurationManager.AppSettings["ida:Audience"],

                TokenValidationParameters = new TokenValidationParameters
                {
                    ValidAudiences = new string[] { $"spn:{ConfigurationManager.AppSettings["ida:Audience"]}" }
                }
            });


        app.UseWindowsAzureActiveDirectoryBearerAuthentication(
            new WindowsAzureActiveDirectoryBearerAuthenticationOptions
            {
                Tenant = ConfigurationManager.AppSettings["ida:Tenant"],
                TokenValidationParameters = new TokenValidationParameters
                {
                    ValidAudience = ConfigurationManager.AppSettings["ida:Audience"]
                },
                MetadataAddress = ConfigurationManager.AppSettings["ida:MetadataAddress"],
            });

    }
}

}

我认为这有一些问题。

第一个是您试图在提供代码的同一台服务器上提供静态内容。这通常被认为是一种不好的做法,纯粹是因为没有必要为静态内容浪费那些宝贵的服务器资源。理想情况下,您应该将静态内容上传到 CDN - 并让用户的浏览器向某些超级缓存文件服务器发出请求。但是 - 我知道您现在可能无法使用此选项。这也不是根本原因。

第二个也是真正的问题是,(你认为你是但是)你没有经过身份验证。 Outlook 网络插件中的身份验证默认情况下不会出现,这是您需要处理的事情。当 Outlook 将您的 Web 加载项加载到侧面板时,它会向您提供某些方法,您可以使用这些方法并创建一个伪身份(例如 Office.context.mailbox.userProfile.emailAddress )——但如果您想要真正的身份验证,你需要自己做。

据我所知,有三种方法可以做到这一点。

  1. 第一个是通过Exchange Identity Token
  2. 第二个是通过Single Sign On feature
  3. 第三种——我认为实现起来最方便、逻辑最简单的是使用WebSockets。 (SignalR 可能是您所需要的)。
    • 当用户加载您的第一个页面时,请确保像 window.Unique_ID 这样的 JS 值可供他们使用。这会派上用场的。
    • 在您的 UI 中有一个按钮 - 上面写着 "Authenticate"
    • 当用户单击此按钮时,您会将它们弹出到 url,这将重定向到您的身份验证 URL。 (类似于 https://company.ourdomain.com/redirToAuth)。这将避免您在侧面板中被阻止的麻烦,因为您正在使用 window.open 和您域中的 url。将 Unique_ID 传递给重定向,然后重定向到 OAuth 登录 URL。那应该看起来像 https://login.microsoftonline.com/......&state=Unique_ID
    • 在弹出用户登录 window 之后,在你的主 JS(客户端)中,你打开一个到你的服务器的网络套接字,再次使用那个 Unique_ID 和开始听。
    • 当用户完成身份验证时,OAuth 流程应该 post 返回访问令牌或代码。如果你得到了访问令牌,你可以通过套接字将它发送到前端(使用post-back参数中的Unique_ID)或者如果你有代码,你完成身份验证用户进行服务器到服务器调用,然后以相同的方式传递访问令牌。因此,您使用该唯一 ID 来跟踪用户连接的套接字,并将访问令牌中继到 该用户。