如何在 ADFS 环境中通过 Javascript 在 Sharepoint 中调用外部 ADFS 安全 WCF 服务?
How to call external ADFS secured WCF Service within Sharepoint via Javascript in an ADFS environment?
之前在我们的小型 Sharepoint 环境中:我们对所有内容都使用了集成的 windows 身份验证。在我们的一些 Sharepoint 站点上,我们集成了一些调用非 Sharepoint WCF 服务的自定义 javascript 应用程序逻辑,该服务也由 IIS 中的 windows 集成身份验证保护。它刚刚起作用,因为当前 Sharepoint 用户的 windows 身份被传递到 javascript AJAX 请求并传递到 WCF 服务。 WCF 服务使用标识信息执行某些逻辑并返回调用。
然后我们使用 ADFS 3.0 设置 Sharepoint,这破坏了我们的 javascript 应用程序代码,因为 windows 集成身份验证不再有效。我的问题:解决这个问题的正确方法是什么?很明显,我们必须修改外部 WCF 服务以支持基于 ADFS 声明的身份验证。我们甚至考虑过使用 ActiveDirectoryFederationServices BearerAuthentication 将 WCF 服务迁移到 .NET Web api。
但是在javascript这边,如何用当前登录的用户调用那个服务呢?我知道 Sharepoint 保留了一个 "FedAuth" cookie,其中包含有关当前用户的信息。我可以将该令牌用于外部 Web 服务吗?感谢任何帮助。
更新:这不起作用,因为 FedAuth cookie 受 HttpOnly 保护,无法在 javscript 中访问。所以我们放弃了整个想法并创建了一个直接托管在 Sharepoint 中的代理网络服务。看起来这是可行的,但它很难看...
我们是这样解决的:
我们查看了 Sharepoint STS 的源代码,尤其是在他们创建 FedAuth cookie 和创建令牌签名的地方。您可以在 dll Microsoft.Sharepoint.IdentityModel.
的 SPSessionSecurityTokenCookieValue class 中找到它
//excerpt from the ValidateSignature method
RSACryptoServiceProvider key = (RSACryptoServiceProvider) SPSecurityTokenServiceManager.Local.LocalLoginProvider.SigningCertificate.PublicKey.Key;
CspParameters parameters = new CspParameters {
ProviderType = 0x18,
KeyNumber = (int) key.CspKeyContainerInfo.KeyNumber
};
if (key.CspKeyContainerInfo.MachineKeyStore)
{
parameters.Flags = CspProviderFlags.UseMachineKeyStore;
}
using (RSACryptoServiceProvider provider2 = new RSACryptoServiceProvider(0x800, parameters))
{
provider2.ImportCspBlob(key.ExportCspBlob(false));
string s = this.BuildValueToSign(options);
byte[] buffer = Convert.FromBase64String(signature);
flag = provider2.VerifyData(this.m_EncodingScheme.GetBytes(s), this.m_SigningScheme, buffer);
}
我们在 WCF 服务中复制了此方法,现在可以验证 FedAuth cookie 的值。当然,您需要拥有 Sharepoint 用于其令牌服务的相同证书(例如,通过 MMC 提取它)。
现在我们可以通过 javascript 调用 WCF 服务,传递用户当前 FedAuth cookie 中的值,并通过验证 cookie 的签名来确认用户的身份。然后我们可以在我们的应用程序逻辑中安全地使用 cookie 的 UserKey/UserName 值。
之前在我们的小型 Sharepoint 环境中:我们对所有内容都使用了集成的 windows 身份验证。在我们的一些 Sharepoint 站点上,我们集成了一些调用非 Sharepoint WCF 服务的自定义 javascript 应用程序逻辑,该服务也由 IIS 中的 windows 集成身份验证保护。它刚刚起作用,因为当前 Sharepoint 用户的 windows 身份被传递到 javascript AJAX 请求并传递到 WCF 服务。 WCF 服务使用标识信息执行某些逻辑并返回调用。
然后我们使用 ADFS 3.0 设置 Sharepoint,这破坏了我们的 javascript 应用程序代码,因为 windows 集成身份验证不再有效。我的问题:解决这个问题的正确方法是什么?很明显,我们必须修改外部 WCF 服务以支持基于 ADFS 声明的身份验证。我们甚至考虑过使用 ActiveDirectoryFederationServices BearerAuthentication 将 WCF 服务迁移到 .NET Web api。
但是在javascript这边,如何用当前登录的用户调用那个服务呢?我知道 Sharepoint 保留了一个 "FedAuth" cookie,其中包含有关当前用户的信息。我可以将该令牌用于外部 Web 服务吗?感谢任何帮助。
更新:这不起作用,因为 FedAuth cookie 受 HttpOnly 保护,无法在 javscript 中访问。所以我们放弃了整个想法并创建了一个直接托管在 Sharepoint 中的代理网络服务。看起来这是可行的,但它很难看...
我们是这样解决的:
我们查看了 Sharepoint STS 的源代码,尤其是在他们创建 FedAuth cookie 和创建令牌签名的地方。您可以在 dll Microsoft.Sharepoint.IdentityModel.
的 SPSessionSecurityTokenCookieValue class 中找到它//excerpt from the ValidateSignature method
RSACryptoServiceProvider key = (RSACryptoServiceProvider) SPSecurityTokenServiceManager.Local.LocalLoginProvider.SigningCertificate.PublicKey.Key;
CspParameters parameters = new CspParameters {
ProviderType = 0x18,
KeyNumber = (int) key.CspKeyContainerInfo.KeyNumber
};
if (key.CspKeyContainerInfo.MachineKeyStore)
{
parameters.Flags = CspProviderFlags.UseMachineKeyStore;
}
using (RSACryptoServiceProvider provider2 = new RSACryptoServiceProvider(0x800, parameters))
{
provider2.ImportCspBlob(key.ExportCspBlob(false));
string s = this.BuildValueToSign(options);
byte[] buffer = Convert.FromBase64String(signature);
flag = provider2.VerifyData(this.m_EncodingScheme.GetBytes(s), this.m_SigningScheme, buffer);
}
我们在 WCF 服务中复制了此方法,现在可以验证 FedAuth cookie 的值。当然,您需要拥有 Sharepoint 用于其令牌服务的相同证书(例如,通过 MMC 提取它)。
现在我们可以通过 javascript 调用 WCF 服务,传递用户当前 FedAuth cookie 中的值,并通过验证 cookie 的签名来确认用户的身份。然后我们可以在我们的应用程序逻辑中安全地使用 cookie 的 UserKey/UserName 值。