3

Azure 培训工具包包括一个名为“IntroToACS2”的实验室。您可以在其中创建一个 WebRole 并启用 ACS,以便您可以使用您的 Google、Live 或 Yahoo id 登录。实验的第二部分将引导您完成从 ACS 下载示例登录页面的过程,以便您可以使用自定义它来匹配您网站的样式。

在做这最后一部分之前,深度链接工作正常。含义:我可以请求一个安全页面,例如http://localhost/acsdemo/securepage.aspx,ACS会拦截该请求,将我重定向到登录页面,然后将我返回到http://localhost/acsdemo/securepage.aspx,但现在它只是将我返回到默认页面http://localhost/acsdemo/default.aspx

从 Azure ACS 下载登录页面后,需要做什么才能让深层链接再次工作?

4

2 回答 2

2

当您重定向登录时,securepage.aspx 的返回 URL 通常存储在上下文参数中。在 ACS 托管登录页面和自定义可下载页面中,都有 javascript 查询 ACS 以获取身份提供者列表,然后为每个 IP 生成登录链接。ACS 托管版本的特殊之处在于它还会收集给它的 wctx 并自定义每个 IP 登录 url 以保留此上下文。这样 ACS 就知道在身份验证完成后将用户重定向回何处。

然而,自定义可下载登录页面不保留此上下文,这就是您获得此行为的原因,ACS 只是将您重定向到您在 ACS 配置中指定的返回 URL,在本例中为 default.aspx。

但是您可以更改您的自定义登录页面以插入此缺少的参数。这里的复杂之处在于,此上下文的通信方式因协议而异。对于 LiveID ( WS-Federation ),传入的 wctx 可以在 liveID 登录链接中的传出 wctx 中重新传输,但采用盒装形式“cx”。下面是我添加到实现此目的的 CreateIdentityProviderButton() 函数中的一些 javascript。

    ...

    //Creates a stylized link to an identity provider's login page
    function CreateIdentityProviderButton(identityProvider) {

        // Some code I stole from fellow stackoverflow  member for extracting query parameters =)
        var urlParams = {};
        (function () {
                var e,
                    a = /\+/g,  // Regex for replacing addition symbol with a space
                    r = /([^&=]+)=?([^&]*)/g,
                    d = function (s) { return decodeURIComponent(s.replace(a, " ")); },
                    q = window.location.search.substring(1);

                while (e = r.exec(q))
                    urlParams[d(e[1])] = d(e[2]);
            })();

        var cx = "&cx=" + encodeURIComponent(urlParams.wctx);
        var idpList = document.getElementById("IdentityProvidersList");
        var button = document.createElement("button");
        button.setAttribute("name", identityProvider.Name);
        button.setAttribute("id", identityProvider.LoginUrl + encodeURIComponent(cx));

        ...

对于 Yahoo 或 Google ( OpenID ),此上下文在openid.return_to中作为“上下文”查询参数返回。因此,在您的登录页面中,您可以类似地编辑登录链接中的 openid.return_to ,如下所示:

... openid.return_to=https://youracstenant.accesscontrol.windows.net:443/v2/openid?context=<value of the wctx extracted from javascript above> ...

您可以根据您在 ACS IdentityProvider.js json 响应中看到的身份提供者名称编写代码来特殊情况下您的登录链接。

于 2012-03-30T01:30:09.593 回答
2

以下是我如何让深层链接工作:

从 Azure 下载示例登录页面后,我将其内容复制到名为 Login.aspx 的 aspx 页面中,然后添加了一些 C# 代码来更新 reply_to 地址。

在 Login.aspx 中找到 script 标签,将 '&reply_to=' 更改为 '&reply_to=<%=returnUrl%>' 如下图:

<script src="https://sample.accesscontrol.windows.net:443/v2/metadata/IdentityProviders.js?protocol=wsfederation&realm=http%3a%2f%2flocalhost%2fSample&reply_to=<%=returnUrl%>&context=&request_id=&version=1.0&callback=ShowSigninPage" type="text/javascript"></script>

接下来,将以下代码添加到 Login.aspx.cs

using System;
using System.Web;

namespace Sample
{
    public partial class Login : System.Web.UI.Page
    {
        protected string returnUrl = "";
        protected void Page_Load(object sender, EventArgs e)
        {            
            var wctx = Request.QueryString["wctx"];
            var wreply = Request.QueryString["wreply"];
            if (wctx == null || wreply == null) return;
            var queryString = HttpUtility.ParseQueryString(wctx);
            var ru = queryString["ru"];
            if (ru == null) return;
            returnUrl = Server.UrlEncode(wreply + ru);
        }
    }
}

现在,这是创建登录链接/按钮的方法:

不要创建这样的链接,因为它不起作用:

<a href="Login.aspx">Login</a>

而是创建一个指向只有在身份验证后才能访问的页面的深层链接,如下所示:

<a href="SecurePage.aspx">Login</a>

到目前为止,我只使用 Google Id 对此进行了测试,但我希望它适用于其他身份提供者。

于 2012-04-02T15:28:47.653 回答