How do I return the return URL correctly again after loading the login page from Azure ACS?

The Azure training kit includes a lab called IntroToACS2. In it, you create WebRole and enable ACS so that you can log in using your Google, Live, or Yahoo ID. The second part of the lab will guide you through the process of loading a sample login page from ACS so that you can customize it to fit the style of your site.

Before doing this last part, deep binding worked fine. Meaning: I can request a secure page, such as http: //localhost/acsdemo/securepage.aspx , and ACS will intercept the request, redirect me to the login page, and then return me http: //localhost/acsdemo/securepage.aspx but now it just brings me back to the default page http: //localhost/acsdemo/default.aspx .

What needs to be done to restore deep links after loading the login page from Azure ACS?

+3
source share
2 answers

The return URL for securepage.aspx is usually stored in the context parameter when redirecting to login. Both the ACS login page and the user download version have javascript that requests ACS for the list of identifier providers and then creates login links for each IP address. The version supported by ACS is different in that it will also collect the wctx provided to it and configure each IP login URL to maintain this context. In this way, ACS knows where to redirect the user back after authentication is complete.

The user downloadable login page, however, does not save this context, so you get this behavior, ACS simply redirects you to the return URL that you specified in the ACS configuration, in this case default.aspx.

But you can change your login page to insert this missing parameter. The complication is that this context is conveyed differently depending on the protocol. For LiveID ( WS-Federation ), the incoming wctx can be retransmitted in the outgoing wctx in the liveID login link, but in the "cx" box. Below is some javascript that I added to the CreateIdentityProviderButton () function, which achieves this.

... //Creates a stylized link to an identity provider 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)); ... 

For Yahoo or Google ( OpenID ), this context is returned to openid.return_to as the context request parameter. Thus, on your login page, you can also edit openid.return_to in your account:

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

You can write the code for the special case that you are referring to based on the identity provider name you see in the ACS IdentityProvider.js json response.

+2
source

Here's how I worked with deeplinks:

After downloading a sample login page from Azure, I copied its contents to an aspx page called Login.aspx, and then added C # code to update the reply_to address.

Find the script tag in Login.aspx and change '& reply_to =' to '& reply_to = <% = returnUrl%>' as shown below:

 <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> 

Then add the following code to 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); } } } 

Now, here's how to create a login link / button:

Do not create a link like this because it will not work:

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

Instead, create a deep link to a page that can only be accessed after authentication, for example:

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

I only tested this with a Google ID, but I expect it to work for other identity providers.

+2
source

Source: https://habr.com/ru/post/921967/


All Articles