Friday, March 9, 2012

Using Windows Azure Access Control Services for Windows Live Authentication using Live Id SDK – Part 2

Ok, in part 1, we saw how ADFS authentication gives us profile information in the forms of claims which we don’t receive in case of using Live ID authentication.
To receive profile information we need to use Windows Live SDK. First we need to create an application on Live ID connect API’s portal. Browse to the following link, https://manage.dev.live.com/, login with your Live ID credentials and then create an application as shown below –
Click on Create Application link. Then provide application name [samplewebrole in my case] and language as English. Then under API settings specify, redirect URL.



This is the URL to which access token will be sent by Live ID. Then we will use this access token to receive profile information in Callback.aspx. Here in Redirect URL I am specifying the URL which will be online when application will be deployed to cloud. You can specify any other URL like – www.litware.com or anything of your choice.
Right now my redirect URL – http://--.cloudapp.net/ does not exists. However, live ID sends token only to this URL as it has been configured as Redirect URL on live SDK portal. So we need to redirect this URL to our localhost cloud URL which is – http://127.0.0.1/ so that token can be received by my application. To do this open host file from location C:\Windows\System32\drivers\etc\ and specify following information –



Now we will use SDK REST API to login to windows Live and to receive profile information. I will have to make these REST API calls on “windows Live ID” button click of ACS login page. However I don’t have login page of ACS. So I need to create a custom login page along with my button of Live Id. On click on my live id button we will make these REST calls. Also the code of ACS will be required so that ADFS button and other ACS stuff will work without any problem.
On ACS Azure portal, under Application Integration system tab in left hand panel, you can download ACS login page. This page is in HTML so I will convert to aspx page and add my own custom button named as “Live ID”. And click on this button I will make Live ID REST API calls.



Copy complete <HTML></HTML> of ACS HTML page and paste in <HTML> section of your login page. I have named it as Login.aspx. Then add your button under <div id="IdentityProvidersList"></div> as shown below –



Now we need to make our custom login page as startup page of the application. If you make your custom login page as startup page by right clicking on solution explorer and run the application; you will be still redirected to ACS login page and not your custom login page. To overcome on this problem we will need to specify “Forms Authentication” tag in web config of web role. So our application will become combination of Federated authentication (using ADFS) and Forms authentication (using Live ID connect).
By default federated authentication makes <authentication mode="None" />
Therefore comment above line from web config file and add following lines under <system.web> tag –
<httpRuntime maxRequestLength="1048576" executionTimeout="120" requestValidationMode="2.0" />
<authentication mode="Forms"><forms loginUrl="Login.aspx" defaultUrl="~/Callback.aspx" timeout="10" /></authentication>
Then add following tag parallel to <system.web> tag and not inside it; that is following tag will go under <configuration> tag –
<location path="Login.aspx">
    <system.web>
      <authorization>
        <allow users="*" />
      </authorization>
    </system.web>
  </location>
  <location path="Callback.aspx">
    <system.web>
      <authorization>
        <allow users="*" />
      </authorization>
    </system.web>
  </location>


Add following keys in ServiceConfiguration.local.cscfg file –
<Setting name="LiveIdClientID" value="your Cline ID received from application created in live id SDK portal" />
      <Setting name="LiveIdRedirectURL" value="http://Your redirect URL/Callback.aspx" />
      <Setting name="LiveIdClientSecret" value="your client secret" />
      <Setting name="LiveIdOAuthURL" value="https://oauth.live.com/token" />

Add following code in code behind of custom login page –
protected void Page_Load(object sender, EventArgs e)
        {
            //if return url is not null means user coming from windows live ID else coming from ADFS
            if (Request.QueryString["ReturnUrl"] != null)
            {
                if (Session["EmailAddress"] != null)
                {
                    IClaimsIdentity identity = User.Identity as ClaimsIdentity;
                    ClaimCollection collection = identity.Claims;

                    string emailAddress = Convert.ToString(Session["EmailAddress"]);
                    //retrieve name without domain
                    string userName = emailAddress.Split(new char[] { '@' })[0];
                    FormsAuthentication.RedirectFromLoginPage(userName, true);
                }
            }
        }

        protected void btnLiveIDLogin_Click(object sender, EventArgs e)
        {
            string LiveConnectAuthUri = "https://oauth.live.com/authorize?client_id=<clientId>&scope=wl.signin%20wl.basic%20wl.emails&response_type=code&redirect_uri=<redirect_uri>";

            //read client id and redirection url from config file
            string clientID = RoleEnvironment.GetConfigurationSettingValue("LiveIdClientID");
            string redirectionURL = RoleEnvironment.GetConfigurationSettingValue("LiveIdRedirectURL");

            //create url
            string authorizedRestCall = LiveConnectAuthUri.Replace("<clientId>", clientID).Replace("<redirect_uri>", redirectionURL);

            //redirect to login page
            Response.Redirect(authorizedRestCall);
        }


Now we need to add callback.aspx page to handle the tokens and receive profile information in it. The complete code for Callback.aspx is here – Callback.aspx.
My final project structure is as follows –



Now run the application, your login page will appear as follows –



Click on out custom Live Id button. You will be redirected to login page of windows Live. After successful login, you may be asked for allowing access to the profile information. Click YES. Then code in Callback.aspx will be executed and email ID will be retrieved. This email ID I am adding to the session which is then populated on Default.aspx as shown –



Hope it helps.
Cheers…
Happy Programming!!!

5 comments:

  1. Hi

    I get the below error and I want to fix this asap. Please help with your valuable input.


    Oops, there was a problem

    The provided value for the input parameter 'redirect_uri' is not valid. The value must be an absolute URL whose scheme is http:// or https://.

    ReplyDelete
  2. Hi Anonymous,
    The error is clear, the redirect URI you specified is not valid. The redirect URI is the one which you specify in your application on live ID account. Same uri needs to be specified in configuration. However does that URL exists? Are you able to view the URL in IE by directly browsing it?

    Hope it helps...

    ReplyDelete
    Replies
    1. Hi Saganak,

      Thanks for the immediate reply. There was an error in the config file under the indentity section i have fixed it and now i am in getting redirected to the url mentioned in the Live ID account. I have mentioned "http://sreeni1979.cloudapp.net" in the Live ID account. There is no such site available. I have the below entry in the hosts file


      127.0.0.1 sreeni1979.cloudapp.net

      I have the LiveIdRedirectURL set to "http://sreeni1979.cloudapp.net/Callback.aspx"

      I am expecting the breakpoint in my Callback.aspx page in dev environment to be hit. However it does not happen.

      Please let me know what could be the mistake here.

      Delete
    2. Make sure that you are running your application on port 80 as you have specified redirect URL that way. Check if you get the correct return URL in the query string. Also instead of running cloud app, make web role as start project for the time being and let the ASP.NET development server start. It should start on port 80. (make sure you have Default web site in IIS stopped so that 80 port will be available to ASP.NET dev server. Once done, browse above callback.aspx page directly in the browser and see if breakpoint in page load of callabck.aspx gets hit.

      Delete
  3. Hi Sanganak,

    Thanks for your immediate response.

    I am specifying http://sreeni1979.cloudapp.net/ in the live ID dev account. I am specifying the same in the settings file against the LiveIdRedirectURL. However http://sreeni1979.cloudapp.net is not an existing site. It cannot be browsed in IE. I have also added the below entry in my hosts file

    127.0.0.1:81 sreeni1979.cloudapp.net

    I am trying to debug my application from my local machine so the code runs in the dev fabric and has the url http://127.0.0.1:81/Login.aspx

    I am sure there some mistake from my part on the configuration. Please help me fix this issue. Appreciate your help in advance.

    ReplyDelete