繁体   English   中英

Azure ACS自定义身份提供程序单一注销

[英]Azure ACS custom Identity Provider Single SignOut

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

登出的URL(领域实际上与网站名称相同):

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,通过输入凭据成功登录,但如果失败则注销。 我已从应用程序注销,但未从google登录。 而且我也看到我没有使用iframe获得页面,但是ACS再次尝试将我重定向到

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

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

两个主要问题:

  1. 为什么调用ACS注销给我iframe页面添加了google / live的额外wa = wsignoutcleanup1.0,但302重定向到我的身份提供商,可能是我在FederationMetadata.xml中错过了某些东西?
  2. 看来ACS在第3步之后不了解我是否已成功从身份提供者注销,并且从这一刻起尝试一次又一次地执行操作,如何告诉他们停止操作?

这是您要做的。

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

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

您的登出网址:

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

不要将其用作构造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 paramer`的重载将结果重定向到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)重载。 而不是在您一般注销用户时。

请尝试所有提及的更改,让我知道它是否可以解决您的问题!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM