3

我正在使用带有自定义 STS 的 Windows azure 访问控制服务。我可以通过 ACS 登录到我的应用程序,但我无法使用注销功能。我已经在我的应用程序中尝试过这段代码。

        WSFederationAuthenticationModule fam = FederatedAuthentication.WSFederationAuthenticationModule;

        try
        {
            FormsAuthentication.SignOut();
        }
        finally
        {
            fam.SignOut(true);
        }
        Page.Response.Redirect("default.aspx");

但似乎它从 ACS 中注销了用户,而不是从自定义 STS 中注销。我应该怎么做才能从 STS 注销。应用程序 (RP)、ACS 或 STS 中的问题可能出在哪里?

我认为 ACS 应该要求自定义 STS 注销用户,但它似乎没有这样做。我错过了什么?

4

2 回答 2

5

我创建了一个辅助方法来执行 FederatedSignout,并在代码中添加了我一路上发现的注释(hth)

public static void FederatedSignOut(string reply = null)
{
   WSFederationAuthenticationModule fam = FederatedAuthentication.WSFederationAuthenticationModule;

   // Native FederatedSignOut doesn't seem to have a way for finding/registering realm for singout, get it from the FAM
   string wrealm = string.Format("wtrealm={0}", fam.Realm);

   // Create basic url for signout (wreply is set by native FederatedSignOut)
   string signOutUrl = WSFederationAuthenticationModule.GetFederationPassiveSignOutUrl(fam.Issuer, null, wrealm);

   // Check where to return, if not set ACS will use Reply address configured for the RP
   string wreply = !string.IsNullOrEmpty(reply) ? reply : (!string.IsNullOrEmpty(fam.Reply) ? fam.Reply : null);

   WSFederationAuthenticationModule.FederatedSignOut(new Uri(signOutUrl), !string.IsNullOrEmpty(wreply) ? new Uri(wreply) : null);

   // Remarks! Native FederatedSignout has an option for setting signOutUrl to null, even if the documentation tells otherwise.
   // If set to null the method will search for signoutUrl in Session token, but I couldn't find any information about how to set this. Found some Sharepoint code that use this
   // Michele Leroux Bustamante had a code example (from 2010) that also uses this form.
   // Other examples creates the signout url manually and calls redirect.

   // FAM has support for wsignoutcleanup1.0 right out of the box, there is no need for code to handle this.
   // That makes it even harder to understand why there are no complete FederatedSignOut method in FAM

   // When using native FederatedSignOut() no events for signout will be called, if you need this use the FAM SignOut methods instead.
}

此代码用于我们为带有 ACS 的 Web SSO 创建的标准 RP 库。

于 2013-09-25T10:22:27.983 回答
2

2012 年 12 月的 ACS 更新包括对联合单点注销的支持:

使用 WS-Federation 协议。使用 ACS 启用使用 WS-Federation 协议的身份提供者的单点登录 (SSO) 的 Web 应用程序现在可以利用单点注销功能。当用户退出 Web 应用程序时,ACS 可以自动将用户从身份提供者和使用相同身份提供者的其他依赖方应用程序中退出。

此功能适用于 WS-Federation 身份提供程序,包括 Active Directory Federation Services 2.0 和 Windows Live ID(Microsoft 帐户)。为了启用单点注销,ACS 为 WS-Federation 协议端点执行以下任务:

  • ACS 识别来自身份提供者的 wsignoutcleanup1.0 消息,并通过向依赖方应用程序发送 wsignoutcleanup1.0 消息来响应。

  • ACS 识别来自依赖方应用程序的 wsignout1.0 和 wsignout1.0 消息,并通过向身份提供者发送 wsignout1.0 消息和向依赖方应用程序发送 wsignoutcleanup1.0 消息来响应。

代码示例:ASP.NET MVC 4 with Federated Sign-out 中,实现这样的操作以从 ACS 中注销:

(请注意,Windows Identity Foundation 现在已合并到 .NET 4.5 框架中,这就是下面新命名空间的原因)

using System.IdentityModel.Services;
using System.IdentityModel.Services.Configuration;

public ActionResult Logout()
{
    // Load Identity Configuration
    FederationConfiguration config = FederatedAuthentication.FederationConfiguration;

    // Get wtrealm from WsFederationConfiguation Section
    string wtrealm = config.WsFederationConfiguration.Realm;
    string wreply;

    // Construct wreply value from wtrealm (This will be the return URL to your app)
    if (wtrealm.Last().Equals('/'))
    {
        wreply = wtrealm + "Logout";
    }
    else
    {
        wreply = wtrealm + "/Logout";
    }

    // Read the ACS Ws-Federation endpoint from web.Config
    // something like "https://<your-namespace>.accesscontrol.windows.net/v2/wsfederation"
    string wsFederationEndpoint = ConfigurationManager.AppSettings["ida:Issuer"];

    SignOutRequestMessage signoutRequestMessage = new SignOutRequestMessage(new Uri(wsFederationEndpoint));

    signoutRequestMessage.Parameters.Add("wreply", wreply);
    signoutRequestMessage.Parameters.Add("wtrealm", wtrealm);

    FederatedAuthentication.SessionAuthenticationModule.SignOut();

    string signoutUrl = signoutRequestMessage.WriteQueryString();

    return this.Redirect(signoutUrl);
}
于 2013-03-15T17:26:20.887 回答