2

我有一个 SharePoint 提供程序托管的应用程序,它公开了一个 Web API 端点。我使用此端点作为中间人来调用安全的外部 Web 服务。我想通过我的主机 Web 中的 SharePoint 页面(发布页面)中的 javascript 调用我的 Web API 端点。由于这是一个跨域调用,因此我使用了 SharePoint 的跨域库 (SP.RequestExecutor.js)。我按照本文中的步骤创建了跨域库所需的自定义代理页面。一切正常。我可以毫无问题地通过 SP.RequestExecutor 调用我的服务。现在,我只想要求身份验证才能访问 Web API 端点。

我引用的文章指出我负责身份验证机制。我似乎无法想出一个真正安全的方法,而且网络上几乎没有示例。我真的很想以某种方式利用 SharePoint 用户的身份,因为只有 SharePoint 用户会访问 Web API 端点,我只是不知道怎么做。SP.RequestExecutor 在访问端点时不允许我传递 SPHostUrl 查询字符串参数,这就是为什么我不能使用 SharePoint 和远程应用程序之间的信任关系。在这种情况下,是否有人对身份验证有一些想法,在使用 SP.RequestExecutor 调用我的端点时效果很好?

4

1 回答 1

1

总而言之,您有以下场景:

  • 您有一个 SharePoint 插件(SharePoint 应用程序)。
  • add in web (app web) 上的页面需要调用外部服务。
  • 您有一个使用 ASP.NET Web Api 实现的外部服务。
  • 外部服务需要身份验证。

您需要解决的第一个问题是Same Origin Policy。为解决此问题,Microsoft 文档描述了您所知道的三个选项:

但是,我认为最好的选择是使用CORS,因为它是W3C 推荐的,它更简单、更容易使用、全面、无黑客攻击,特别是:ASP.NET Web API 2 支持 CORS

另一个需要解决的问题是身份验证。不幸的是,Microsoft 文档没有提供任何示例或提示,它只是告诉您这是您的责任。搜索网络也没有提供任何示例或提示。所以我得出结论:您需要发明一种身份验证机制。一些身份验证协议基于 NTLM 身份验证等挑战。电子邮件地址验证也使用挑战,它挑战您阅读发送到电子邮件地址的电子邮件。我向您建议一种基于相同范式的机制。我要求用户在 SharePoint 应用程序 Web 上创建一个特定的列表项(加载项)。因此,我们需要在 App WebAutenticationChalenges上使用以下字段调用一个列表:

  • ID:内置字段的自动增量。
  • ChanlengeValue: 单行文本。
  • CreatedBy:用户内置字段。

认证过程有以下步骤:

1.- 应用网页上的 JavaScripthttps://myexternalservice.mycompay.com/create-chalenge使用以下负载调用 web api 端点:

{
    "UserId": "3432" // the SharePoint UserId
    "AppWebUrl": "https://mysharpointonline-e849d5bbe0ddc2.sharepoint.com/MySharePointApp"
    "HostWebUrl": "https://mysharepointonline.sharepoint.com/MySharePointApp"
}

2.- 外部服务器生成两个 16-32 字节的随机值:ChalengeValueCorrelationToken,并将它们与有效负载一起插入到一些存储中,如下所示:

CREATE SEQUENCE authentication_chalenges_authentication_chalenge_id_seq
START WITH 1;

CREATE TABLE authentication_chalenges
(
    authentication_chalenge_id int NOT NULL DEFAULT NEXT VALUE FOR authentication_chalenges_authentication_chalenge_id_seq
    CONSTRAINT authentication_chalenges_authentication_chalenge_id_seq PRIMARY KEY,
    user_id int NOT NULL,
    correlation_token binary(16) NOT NULL,
    chalenge_value binary(16) NOT NULL,
    app_web_url varchar(4000) NOT NULL,
    host_web_url varchar(4000) NULL,
    created_timestamp datetime NOT NULL
)

然后,服务器返回以下结果:

{
    "ChalengeId": 31232, // the value of authentication_chalenge_id column of the table
    "CorrelationToken" : "95AE040FE6844345B36B5E33BE03437F",
    "ChalengeValue" : "E38A022B7F744D3BA8C676259AECD607"

}

3.- App 网页上的 JavaScript 将一个项目插入AuthenticationChanlenges列表设置ChalengeValue列 =并使用以下负载"E38A022B7F744D3BA8C676259AECD607"调用web api 端点:https://myexternalservice.mycompay.com/login

{
    "ChalengeItemId" : 4133, // the ID column of the AuthenticationChalenges SharePoint list
    "ChalengeId" : 31232,
    "CorrelationToken" : "95AE040FE6844345B36B5E33BE03437F",
    "ChalengeValue" : "E38A022B7F744D3BA8C676259AECD607"
}

4.- 外部服务服务器查找挑战表中的行:

SELECT * FROM authentication_chalenges WHERE authentication_chalenge_id = 31232 

如果查询返回一行并且CorrelationToken匹配ChanlengeValue,并且它还没有过期,则服务器连接到共享点以查找列表中的项目,ID = 4133AuhenticationChalenges检查ChalengeValue是否等于E38A022B7F744D3BA8C676259AECD607,最后检查CreatedBy用户 id 是否等于3432。如果所有检查都成功,那么它会以 ok 响应进行响应并设置身份验证 cookie。如果任何检查失败,则它会以 401 结果响应。

于 2015-08-28T07:53:28.780 回答