WIF 通过 AJAX 到一个单独的域

Posted

技术标签:

【中文标题】WIF 通过 AJAX 到一个单独的域【英文标题】:WIF to a separate domain via AJAX 【发布时间】:2013-08-01 16:54:31 【问题描述】:

我们的网站在两个独立的域中运行,一个是安全 API,另一个是前端网站。 我们希望能够使用当前登录的用户凭据从网站向 API 发出 ajax 请求。

为此,我完成了所有必要的 CORS 位,以便能够将我们的 cookie 传递给 API,但是当 API 尝试处理 cookie 时,它​​无法解密它。我的理解是,这是因为领域不正确匹配。

我尝试执行此操作时遇到的错误如下:

InvalidOperationException:ID1073:尝试使用 ProtectedData API 解密 cookie 时发生 CryptographicException(有关详细信息,请参阅内部异常)。如果您使用的是 IIS 7.5,这可能是由于应用程序池上的 loadUserProfile 设置设置为 false。

如果我使用 :1444 领域的 cookie 手动发出相同的请求,一切正常(所以我认为 loadUserProfile 的东西是红鲱鱼)。

我认为问题在于我不能将此 cookie 重复用于另一个领域。但如果是这种情况,我该如何在 javascript 中执行此委托?实际上是否有可能不将用户重定向到 STS 以获取另一个领域的 cookie?有没有更好的方法来处理这个 javascript 委托?

有用的支持数据:

我们API端的WIF配置:

    <modules runAllManagedModulesForAllRequests="true">
        <add name="WSFederationAuthenticationModule" type="Microsoft.IdentityModel.Web.WSFederationAuthenticationModule, Microsoft.IdentityModel, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" preCondition="managedHandler" />
        <add name="SessionAuthenticationModule" type="Microsoft.IdentityModel.Web.SessionAuthenticationModule, Microsoft.IdentityModel, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" preCondition="managedHandler" />
    </modules>

...

<microsoft.identityModel>
    <service>
        <securityTokenHandlers>
            <add type="Microsoft.IdentityModel.Tokens.SessionSecurityTokenHandler, Microsoft.IdentityModel, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35">
                <sessionTokenRequirement lifetime="1:00" />
            </add>
        </securityTokenHandlers>
        <audienceUris>
            <add value="http://localhost:1444/" />
        </audienceUris>
        <federatedAuthentication>
            <wsFederation passiveRedirectEnabled="true" issuer="http://localhost:1339/account/sign-in" realm="http://localhost:1444/" requireHttps="false" persistentCookiesOnPassiveRedirects="false" />
            <cookieHandler requireSsl="false" path="/" name="TheCookieMonster" persistentSessionLifetime="60" />
        </federatedAuthentication>
        <applicationService>
            <claimTypeRequired>
                <!--This claim gets mapped to the User.Identity.Name-->
                <claimType type="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name" optional="false" />
                <!--Some Other Custom claims-->
            </claimTypeRequired>
        </applicationService>
        <issuerNameRegistry type="Microsoft.IdentityModel.Tokens.ConfigurationBasedIssuerNameRegistry, Microsoft.IdentityModel, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35">
            <trustedIssuers>
                <add thumbprint="a_thumbprint_key_for_our_cert" name="http://localhost:1339/" />
            </trustedIssuers>
        </issuerNameRegistry>
    </service>
</microsoft.identityModel>

网站端WIF的配置:

(相同但带有 :1337)

    <modules runAllManagedModulesForAllRequests="true">
        <add name="WSFederationAuthenticationModule" type="Microsoft.IdentityModel.Web.WSFederationAuthenticationModule, Microsoft.IdentityModel, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" preCondition="managedHandler" />
        <add name="SessionAuthenticationModule" type="Microsoft.IdentityModel.Web.SessionAuthenticationModule, Microsoft.IdentityModel, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" preCondition="managedHandler" />
    </modules>

...

<microsoft.identityModel>
    <service>
        <securityTokenHandlers>
            <add type="Microsoft.IdentityModel.Tokens.SessionSecurityTokenHandler, Microsoft.IdentityModel, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35">
                <sessionTokenRequirement lifetime="1:00" />
            </add>
        </securityTokenHandlers>
        <audienceUris>
            <add value="http://localhost:1337/" />
        </audienceUris>
        <federatedAuthentication>
            <wsFederation passiveRedirectEnabled="true" issuer="http://localhost:1339/account/sign-in" realm="http://localhost:1337/" requireHttps="false" persistentCookiesOnPassiveRedirects="false" />
            <cookieHandler requireSsl="false" path="/" name="TheCookieMonster" persistentSessionLifetime="60" />
        </federatedAuthentication>
        <applicationService>
            <claimTypeRequired>
                <!--This claim gets mapped to the User.Identity.Name-->
                <claimType type="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name" optional="false" />
                <!--Some Custom claims-->
            </claimTypeRequired>
        </applicationService>
        <issuerNameRegistry type="Microsoft.IdentityModel.Tokens.ConfigurationBasedIssuerNameRegistry, Microsoft.IdentityModel, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35">
            <trustedIssuers>
                <add thumbprint="a_thumbprint_key_for_our_cert" name="http://localhost:1339/" />
            </trustedIssuers>
        </issuerNameRegistry>
    </service>
</microsoft.identityModel>

net 标签的样子:

我认为这已被取消,因为 JS 检测到某种安全废话正在发生。

机器密钥在两个站点之间共享 两者都运行 WIF 3.5

【问题讨论】:

搞清楚了吗?我今天开始获取 ID1073 值。但仅限于 Internet Explorer 9。 @user2141723 我们在所有浏览器(不仅仅是 IE)中都遇到了这个问题,但我们通过升级到最新的 WIF 解决了这个问题。我不太确定根本原因或如何解决它。 哈哈,有道理。尤其是当我们不得不将客户端站点回滚到 4.0 时,我的所有困难都开始了,因为 dotcom 团队对升级到 4.5 感到不安全。 C'est le vie。 :) 【参考方案1】:

我们确实设法通过升级到 WIF 4.5 来解决这个问题,该版本无需特殊修改即可完美运行。我不太确定 3.5 中的根本原因是什么,但这已经解决了我的问题。如果有人想要它,我可以将这个工作的示例发布到 GitHub

【讨论】:

嘿卢克我知道这是一个旧线程,但你能分享你的解决方案吗?我正在尝试做一件非常相似的事情。谢谢! @user959729 抱歉,这是很久以前的事了,我想我已经丢失了这个特定的代码示例。从内存中只需要运行 4.5 并在 webapi 中指定正确的 cors 标头就足够了。

以上是关于WIF 通过 AJAX 到一个单独的域的主要内容,如果未能解决你的问题,请参考以下文章

使用 WIF 和 jquery ajax 请求时 ASP.NET MVC 3 中的会话 Cookie 过期处理

Laravel CSRF 保护下的 JQuery AJAX 跨站请求

转JS跨域(ajax跨域iframe跨域)解决方法及原理详解(jsonp)

域转移后 AWS Route 53 上的域传播错误

SecurityException 1000,即使使用相同的域

Laravel 将数据从 ajax 传递到位于单独文件中的模态视图,导致模态视图无法呈现