【问题标题】:Azure ACS custom Identity Provider Single SignOutAzure ACS 自定义身份提供程序单一注销
【发布时间】:2013-05-01 11:42:20
【问题描述】:

我正在基于 Thinktecture 代码实现我自己的身份提供程序。这是 Azure ACS 在使用单点注销功能时的一种奇怪行为,它对于 google/live 和我自己的身份提供者有所不同。

登出网址(realm 与站点名称完全相同):

mysite.accesscontrol.windows.net/v2/wsfederation?wa=wsignout1.0&wreply=http%3a%2f%2flocalhost%2fAdministration.Frontend.Web%2f&wtrealm=http%3a%2f%2flocalhost%2fAdministration.Frontend.Web %2f

这是一个注销的伪代码:

//clear FedAuth cookies
FormsAuthentication.SignOut();
FederatedAuthentication.WSFederationAuthenticationModule.SignOut(true);

//call Single SignOut
var signoutRequestMessage = new SignOutRequestMessage(new Uri(signOutUrl));
return Redirect(signoutRequestMessage.WriteQueryString());

这是示例流程(我使用隐私浏览和 Fiddler 来查看所有内容):

1) 我正在使用 google 帐户登录我的应用程序。

2) 单击注销,结果我在 ACS 上获得一个带有此代码的页面:

function on_completion() 
  {window.location = 'http://localhost/Administration.Frontend.Web/';}

<iframe src="https://www.google.com/accounts/Logout" style="visibility: hidden"">/iframe>
<iframe src="http://localhost/Administration.Frontend.Web/?wa=wsignoutcleanup1.0" style="visibility: hidden"></iframe>

结果:我已从我的应用程序和 google 中注销。

3) 登录到我的身份提供商,单击注销,重定向到 ACS 上与上一步相同的 URL,但现在我得到 302 结果并重定向到

https://localhost/IdentityProvider/issue/wsfed?wa=wsignout1.0&amp;wreply=https%3a%2f%2fmysite.accesscontrol.windows.net%2fv2%2fwsfederation%3fredirectUrl%3dhttp%3a%2f%2flocalhost%2fAdministration.Frontend.Web%2f

结果:我已从我的应用程序和身份提供者中注销。

4) 再次尝试使用google,输入凭据成功登录,但如果失败则注销。我已从应用程序中注销,但未从谷歌登录。而且我还看到我没有使用 iframe 获取页面,而是 ACS 再次尝试将我重定向到

https://localhost/IdentityProvider/issue/wsfed?wa=wsignout1.0 

(然后返回 mysite.accesscontrol.windows.net,最后返回我的应用程序)

两个主要问题:

  1. 为什么调用 ACS 注销会给我带有附加的 iframe 页面 wa=wsignoutcleanup1.0 用于 google/live 但 302 重定向到我的 身份提供者,可能是我错过了什么 联邦元数据.xml?
  2. 看起来第 3 步之后的 ACS 没有 了解我已成功从身份提供者注销 从这一刻开始,一次又一次地尝试这样做,如何告诉他们 阻止它?

【问题讨论】:

  • 您能否提供 ACS 页面(只是路径,在 .accesscontrol.windows.net/??? 之后),您正在被重定向并且行为不明确 - 首先呈现一些 JS + iframe 的页面,但接下来只呈现 302 响应。
  • 另外,您使用的是 ACS 托管的领域发现登录页面,还是您自己的登录页面?我认为它是 ACS 托管的。请移至自托管登录页面,然后重试。
  • 这里提供的答案stackoverflow.com/questions/14932241/… 提供了更准确的信息

标签: azure claims-based-identity acs


【解决方案1】:

这是你必须做的。

首先,在使用联合身份验证时,请始终使用 HTTPS!有时协议协商会因为它是纯 HTTP 而失败。有时浏览器会阻止非安全流量,这对于注销过程至关重要。所以,请始终使用 HTTPS!

现在,要实现单点注销的形式,您需要做更多的工作。

您的退出网址:

mysite.accesscontrol.windows.net/v2/wsfederation?wa=wsignout1.0&amp;wreply=http%3a%2f%2flocalhost%2fAdministration.Frontend.Web%2f&amp;wtrealm=http%3a%2f%2flocalhost%2fAdministration.Frontend.Web%2f

请勿将其用作构造 SignOutRequestMessage 的参数。直接用return Redirect(signOutUrl)

你必须在两个主要的地方实现退出!

首先是您的一般注销操作方法(假设您使用的是 MVC)与您已有的类似但有一个重要变化的东西:

FormsAuthentication.SignOut();
var signoutProtocolLocation = "https://[your_acs_namespace].accesscontrol.windows.net:443/v2/wsfederation?wa=wsignout1.0&wtrealm=[realm]&wreply=[reply]";
FederatedAuthentication.WSFederationAuthenticationModule.SignOut(signoutProtocolLocation);

请注意,这里我使用 string 参数的重载将结果重定向到 ACS SSO 位置!

现在ACS SSO 位置将生成上面提到的带有 JS 和几个 iframe 元素的 HTML 页面。其中之一将类似于:

<iframe src="http://localhost/Administration.Frontend.Web/?wa=wsignoutcleanup1.0" style="visibility: hidden"></iframe>

现在,特定位置 http://localhost/Administration.Frontend.Web/?wa=wsignoutcleanup1.0 是您代码中实现 SSO 的第二个位置。此请求必须重定向到登录页面,而是必须正确处理并返回 200 或 301 响应(这反过来将返回 200!)!为简单起见,我将仅粘贴此处使用的代码:

 if(Request.QueryString.AllKeys.Contains("wa")
                && Request.QueryString["wa"].Equals("wsignoutcleanup1.0"))
            {
                FederatedAuthentication.WSFederationAuthenticationModule.SignOut(true);
                return RedirectToAction("Index");
            }

只有在请求 wsignoutcleanup 操作时才使用 true 调用 SignOut(true) 重载,这一点非常重要。而不是在您对用户进行常规注销时。

请尝试所有提到的更改,如果能解决您的问题,请告诉我!

【讨论】:

    猜你喜欢
    • 2013-02-12
    • 2020-07-29
    • 1970-01-01
    • 2013-11-15
    • 2017-12-13
    • 2018-11-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多