Deploying social oauth2 claims-aware websites to Azure using Git

Learn how to deploy a Azure Website using Git and being claims aware by allowing users to identify themself with ouath2 from Facebook, LiveId or Google Accounts.

Creating a Claims-Aware MVC4 Project

I will show you how you can enable your ASP.NET site to be claims-aware in the context of letting users identify themself using either Google, Facebook or Live ID over Oauth2. I will be using a few dependencies for handing the claims-awareness (with a few modifications of my own that I will try getting pushed to the original Github).

We will first create and deploy a standard MVC4 Site to Azure using Git. 

Select a Basic Template, and then select Git as your Source Control when prompted. If you haven’t installed the extension, Visual Studio Tools for Git, you should do so now. You should now have a site that looks like this in your solution explorer.

For the controller, we will add a HomeController. You can download it from Github, HomeController.cs. This is also the fork that we will be using a little later for adding claims support. Brock Allen made the original lib, where I made a few modifications for moving the registration out of the controller and into AppSettings, such the id and secret can be set from Azure Websites configuration page. For now you can find his package in the Nuget Package Manager: BrockAllen.OAuth2. Add the needed namespaces (ctrl+.) on OAuth2Client and use the one from Brock Allen. 

    public class HomeController : Controller
    {
        static HomeController()
        {
            RegisterOAuth2Clients();
        }

        static void RegisterOAuth2Clients()
        {
            OAuth2Client.Instance.RegisterProvider(
                ProviderType.Google,
                "421418234584-3n8ub7gn7gt0naghh6sqeu7l7l45te1c.apps.googleusercontent.com",
                "KDJt_7Rm6Or2pJulBdy0gvpx");

            OAuth2Client.Instance.RegisterProvider(
                ProviderType.Facebook, 
                "195156077252380",
                "39b565fd85265c56010555f670573e28");
            
            OAuth2Client.Instance.RegisterProvider(
                ProviderType.Live, 
                "00000000400DF045",
                "4L08bE3WM8Ra4rRNMv3N--un5YOBr4gx");
        }

        public ActionResult Index()
        {
            return View();
        }
        
        public ActionResult Login(ProviderType type)
        {
            // 1st param is which OAuth2 provider to use
            // 2nd param is what URL to send the user once all the login magic is done
            return new OAuth2ActionResult(type, Url.Action("Index"));
        }
    }

Next, you should also add a view and then we are ready to hit ctrl+f5. Add a Home folder under views and add the view Index.cshtml with the following content:

@{
    ViewBag.Title = "Index";
}

<h2>Login With:</h2>
<ul>
    <li>@Html.ActionLink("Google", "Login", new { type = BrockAllen.OAuth2.ProviderType.Google })</li>
    <li>@Html.ActionLink("Live", "Login", new { type = BrockAllen.OAuth2.ProviderType.Live})</li>
    <li>@Html.ActionLink("Facebook", "Login", new { type = BrockAllen.OAuth2.ProviderType.Facebook})</li>
</ul>
@{
    var id = System.Security.Claims.ClaimsPrincipal.Current;
    if (id.Identity.IsAuthenticated)
    {
        <h2>Claims</h2>
        <dl>
            @foreach (var claim in id.Claims)
            {
                <dt>@claim.Type</dt>
                <dd>@claim.Value</dd>
                <dd>@claim.Issuer</dd>
            }
        </dl>
    }
}

Adding OAuth2Client.AutoRegisterOAuthCallbackUrl = true; before AreaRegistration.RegisterAllAreas(); sets up the callback url. If you have set up a Facebook/Google or Live ID "App", then you can add the clientId and client secret and see that it works on your localhost. Only Google allows you to add multiply callback urls from what I have found, so I suggest you to start there as you can reuse it when we move to azure.

Deployment to Azure Websites

Assuming you did install the git tools, you should be able to right click the solution and click commit. After the initial Commit, we can specify a remote origin. If you are a Github user, you could create a empty project and put the url.git and push your project to Github. In this demo, we will configure a Azure Website as the remote origin and push our solution directly to Azure and it will be build automatic and deploy our site.

Now locate the deployments tab at your Azure Website and copy the url.git to Visual Studio Publish to Remote Repository.

If you haven't committed your initial commit yet, do so now. Then click View Commits and push it to the remote origin. When it is complete, you can go back to the Azure Manager and it should pop up.

Do note that the image is from my second commit, I got a deployment error on my first commit as a result of it not able to find the BrockAllen.OAuth2 dll. Right clicking the solution and Enabling Nuget Package Restore, followed by right click again and commit and lastly view commits and push. About 10 seconds later it had uploaded the solution, deployed it and it was available at https://oauthclaimsdemo.azurewebsites.net/.

The missing parts.

You can use the above steps to deploy any site to Azure Websites, really fast and easy. To get this sample working, we need a few more baby steps. The good thing about this setup is that when we do changes in visual studio, we can push them fast to Azure without having to wait for deployments.

The 3 sites you want to visit to create a clientId and clientSecred are:

After updating the HomeController with the information, you should commit and push it off to azure. I only added google if you visit https://oauthclaimsdemo.azurewebsites.net/. At this point, everything should work, but for our site to store the information that it get back from the oauth providers, we need to configure SAM in the web.config. 

    <modules>
      <remove name="FormsAuthentication" />
      <add name="SessionAuthenticationModule"
           type="System.IdentityModel.Services.SessionAuthenticationModule, System.IdentityModel.Services, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
           preCondition="managedHandler" />
    </modules>

Above code should be under system.webServer.

<section name="system.identityModel"
             type="System.IdentityModel.Configuration.SystemIdentityModelSection, System.IdentityModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089" />
    <section name="system.identityModel.services"
             type="System.IdentityModel.Services.Configuration.SystemIdentityModelServicesSection, System.IdentityModel.Services, Version=4.0.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089" /> 

Above code is in configSections

  <system.identityModel>
    <identityConfiguration>
      <securityTokenHandlers>
        <remove type="System.IdentityModel.Tokens.SessionSecurityTokenHandler, System.IdentityModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
        <add type="System.IdentityModel.Services.Tokens.MachineKeySessionSecurityTokenHandler, System.IdentityModel.Services, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
      </securityTokenHandlers>
    </identityConfiguration>
  </system.identityModel>
  <system.identityModel.services>
    <federationConfiguration>
      <cookieHandler requireSsl="false"></cookieHandler>
    </federationConfiguration>
  </system.identityModel.services>

Moreover, the last snippet need to be in the root element, configuration. To make it work in a Web Farm scenario as Azure Websites, we must use the machine key for protecting the tokens.

Adding the settings from the Azure Portal

I am working on a project that I intend to put on Github for open source transparency, who does not love when you can see the code running behind the scene. At the same time I do not want to expose the keys/secrets in the public code.

I could of cause make different config files and swap them in and out, but this means more work for me. Instead I forked Brock Allens code and modified it to read all the keys and secrets from AppSettings automatic. The good thing about this is that i can alter them in the Azure Management Portal. Any keys and connection strings are simply replaced at runtime if specified at the portal.

As this post is getting long already, I will simply show the result and you can take my fork at GitHub until I convince Brock to accept my pull request. Fork it and build it and add it as a reference, (it is compatible with Brocks). Remember that you have to include it in a folder called bin in your visual studio project to get it committed and pushed to Azure. Else, it will be missing the dll when it build.


Go visit https://oauthclaimsdemo.azurewebsites.net/ and press the google/live login and see what claims it returns for you. No data is logged and you can verify the code at Github. All links are at the demo site.





comments powered by Disqus