Quantcast
Viewing all articles
Browse latest Browse all 36188

Securing Dynamic Data ASP.NET SQL Azure Published Web Site with ACS and Facebook as an Identity Provider

The Scenario

I wanted to implement an Azure web site that is using the Azure Access Control Service and integrates with an external identity provider to authenticate and authorize users. At first I thought of using Windows Live ID but it has a problem that the only claim offered by WLID is the unique identified which is simply a number and represents nothing from the user. Then I thought why not make things more interesting and use Facebook. I think things got more interesting than I thought. J

I wanted to implement a Dynamic database access web site so that it generates the views on top of an existing SQL Azure database and lets the end user manipulate the database tables and filter them. This is using Linq-to-SQL classes.

I am using Visual Studio 2012 latest version.

The Steps highlights

The steps at a glance of how to get this up and going are as below:

1-     Create your project:

a.      Create your database.

b.      Create a new Dynamic ASP.NET project.

c.      Add a Linq-To-SQL model to your database.

d.      Change the Framework version of the project.

e.      Set the “ScaffoldAllTables” to true.

2-     Download the latest “Identity and access tool”

3-     Create a new Azure web site and download the publishing settings.

4-     Setup your identify provider:

a.      Create a new Azure ACS namespace

b.      Create a new Facebook application

c.      Configure your Facebook application.

d.      Add your Facebook application as an identity provider.

e.      Configure you claims rules

5-     Set the ACS settings in the “Identity and access tool”

6-     Implement your custom claims authorization manager

7-     Complete the web.config configuration

8-     Publish your web site.

Solution Walkthrough and description

Create your project

This is the first step and as I described I wanted to create a dynamic ASP.NET site based on a custom database.

Create the Database

First I created the database in SQL Azure.

Image may be NSFW.
Clik here to view.
clip_image002

Created a new SQL server and provided the administrator permissions and allowed Azure services access to this server.

Image may be NSFW.
Clik here to view.
clip_image004

Then I allowed access to my IP to this database to allow me to manage it.

Image may be NSFW.
Clik here to view.
clip_image006

Then I started to design my database (this can be either done online or using Visual Studio)

Image may be NSFW.
Clik here to view.
clip_image008

Image may be NSFW.
Clik here to view.
clip_image010

Or from Visual Studio 2012

Image may be NSFW.
Clik here to view.
clip_image012

Image may be NSFW.
Clik here to view.
clip_image014

Once the database is created and ready to be used then you will go to the next step.

Create the Dynamic ASP.NET project

Open visual Studio and click on new project. You will need to switch to .net framework 4.0 to see the dynamic data ASP.NET SQL template.

Image may be NSFW.
Clik here to view.
clip_image016

Image may be NSFW.
Clik here to view.
clip_image018

Image may be NSFW.
Clik here to view.
clip_image020

Image may be NSFW.
Clik here to view.
clip_image022

Change the “Global.ascx” file to uncomment the line to connect to the classes to be as follows

DefaultModel.RegisterContext(typeof(TestDbDataClassesDataContext), newContextConfiguration() { ScaffoldAllTables = true });

Change the .net Framework version to be 4.5 to be able to see the Identity and Access tool link.

Image may be NSFW.
Clik here to view.
clip_image024

Download the Identity and Access tool

From the visual studio tools menu click on the “Extensions and updates”

Image may be NSFW.
Clik here to view.
clip_image025

Search for the “Identity and Access tool” and install it and restart your Visual Studio.

Image may be NSFW.
Clik here to view.
clip_image027

Create the Azure Web Site

Open the Azure management site and click on new web site.

Image may be NSFW.
Clik here to view.
clip_image028

Click on “Download the publish profile”

Image may be NSFW.
Clik here to view.
clip_image030

Save this file on your Hard disk. Now in Visual Studio click on the project and then Publish

Image may be NSFW.
Clik here to view.
clip_image031

Click on “Import”

Image may be NSFW.
Clik here to view.
clip_image033

Now select the publish settings file already downloaded.

Complete the publishing and test that the application is now published and working.

Image may be NSFW.
Clik here to view.
clip_image034

Now the next step is to configure the Facebook as an identity provider.

Setup Facebook as an Identity Provider

Create the Facebook application

Logon to your Facebook account and then open the link http://developers.facebook.com

Register yourself as a developer.

Image may be NSFW.
Clik here to view.
clip_image036

Now click on Apps and then create a new App

Image may be NSFW.
Clik here to view.
clip_image038

Give your application a name

Image may be NSFW.
Clik here to view.
clip_image039

Take note of your application ID and secret.

Also enter the URL of the ACS namespace you will create on the Azure ACS web site in the next step (It is better to create that namespace first and then return to this step later).

Image may be NSFW.
Clik here to view.
clip_image041

Click save Changes.

Create Your ACS Namespace

Open the Azure portal and click new to create a new ACS names space.

Image may be NSFW.
Clik here to view.
clip_image043

Once created you can click on the Manage link to start managing it.

Image may be NSFW.
Clik here to view.
clip_image045

Configure your ACS service

Start by adding the Facebook application as an identity provider. Click on identity providers and then “Add”

Image may be NSFW.
Clik here to view.
clip_image046

Image may be NSFW.
Clik here to view.
clip_image048

Enter the application ID and secret and click “Save”

Image may be NSFW.
Clik here to view.
clip_image050

Configure Your Project to Link ACS Service

While on the ACS management site click on “Management service” so see all management links required to be able to communicate with ACS.

Image may be NSFW.
Clik here to view.
clip_image052

Image may be NSFW.
Clik here to view.
clip_image054

Image may be NSFW.
Clik here to view.
clip_image056

Click on “Show Key” and then copy the symmetric key generated.

These will be the namespace and the management key of the namespace.

Right click on your project and then click “Identity and Access tool”

Image may be NSFW.
Clik here to view.
clip_image057

Configure your ACS with the namespace and the key already copied before after selecting “Use the Windows Azure Access Control Service”.

Image may be NSFW.
Clik here to view.
clip_image059

Image may be NSFW.
Clik here to view.
clip_image061

 

Now select the settings as below

Image may be NSFW.
Clik here to view.
clip_image063

Finally click “Ok”. This will configure your ACS service and the relying party application with the required pass-through rule for all provider claims as shown below.

Image may be NSFW.
Clik here to view.
clip_image065

The next steps are to create and implement the Claims authorization manager and configure your web.config.

Implement a Custom Claims Authorization Manager

Since we are using .Net framework 4.5 this is a little different than what we used to do in 3.5 since now the WIF is totally integrated in the framework.

Add reference to the System.IdentityModel assembly

Image may be NSFW.
Clik here to view.
clip_image067

Add and implement the new class “MyAuthorizationManager

This is done so that the code of the file would be as follows.

using System.IO;

using System.Xml;

using System.Collections.Generic;

using System;

using System.Web;

using System.Linq;

using System.Security.Claims;

 

namespace TestDbWebApplication

{

    publicclassMyAuthorizationManager : ClaimsAuthorizationManager

    {

        privatestaticDictionary<string, string> m_policies = newDictionary<string, string>();

 

        public MyAuthorizationManager()

        {

        }

        publicoverridevoid LoadCustomConfiguration(XmlNodeList nodes)

        {

            foreach (XmlNode node in nodes)

            {

                {

                    //FIND ZIP CLAIM IN THE POLICY IN WEB.CONFIG AND GET ITS VALUE

                    //ADD THE VALUE TO MODULE SCOPE m_policies

                    XmlTextReader reader = newXmlTextReader(newStringReader(node.OuterXml));

                    reader.MoveToContent();

                    string resource = reader.GetAttribute("resource");

                    reader.Read();

                    string claimType = reader.GetAttribute("claimType");

                    if (claimType.CompareTo(ClaimTypes.Name) != 0)

                    {

                        thrownewArgumentNullException("Name Authorization is not specified in policy in web.config");

                    }

                    string name = "";

                    name = reader.GetAttribute("Name");

                    m_policies[resource] = name;

                }

            }

        }

        publicoverridebool CheckAccess(AuthorizationContext context)

        {

            //GET THE IDENTITY

            //COMPARE WITH THE POLICY

            string allowednames = "";

            string requestingname = "";

            Uri webPage = newUri(context.Resource[0].Value);

            ClaimsPrincipal principal = (ClaimsPrincipal)HttpContext.Current.User;

            if (principal == null)

            {

                thrownewInvalidOperationException("Principal is not populate in the context - check configuration");

            }

            ClaimsIdentity identity = (ClaimsIdentity)principal.Identity;

            if (m_policies.ContainsKey(webPage.PathAndQuery))

            {

                allowednames = m_policies[webPage.PathAndQuery];

                requestingname = ((from c in identity.Claims

                                        where c.Type == ClaimTypes.Name

                                        select c.Value).FirstOrDefault());

            }

            elseif (m_policies.ContainsKey("*"))

            {

                allowednames = m_policies["*"];

                requestingname = ((from c in identity.Claims

                                   where c.Type == ClaimTypes.Name

                                   select c.Value).FirstOrDefault());

            }

            if (allowednames.ToLower().Contains(requestingname.ToLower()))

            {

                returntrue;

            }

            returnfalse;

        }

    }

}

This would authorize users based on their login name reported by the identity provider (Facebook).

Configure the Authorization manager in the Web.Config

The required steps are to add the following lines:

  <system.webServer>

    <modules>

      <addname="ClaimsAuthorizationModule"type="System.IdentityModel.Services.ClaimsAuthorizationModule, System.IdentityModel.Services, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"preCondition="managedHandler" />

    </modules>

  </system.webServer>

Please note the yellow highlighted section above as this is key to make this work.

<system.identityModel>

  <identityConfiguration>

    <securityTokenHandlers>

      <removetype="System.IdentityModel.Tokens.SessionSecurityTokenHandler,System.IdentityModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />

      <addtype="System.IdentityModel.Services.Tokens.MachineKeySessionSecurityTokenHandler,System.IdentityModel.Services, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />

    </securityTokenHandlers>

  </identityConfiguration>

</system.identityModel>


Please note the highlighted section as publishing to Azure web site will not work without these lines.

Finally the claims authorization manager configuration.

<system.identityModel>

  <identityConfiguration>

    <claimsAuthorizationManagertype="TestDbWebApplication.MyAuthorizationManager, TestDbWebApplication">

      <policyresource="*">

        <claimclaimType="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name"Name="Mohamed Malek" />

      </policy>

    </claimsAuthorizationManager>

  </identityConfiguration>

</system.identityModel>

Publish and test your site

Now you have completed the site configuration publish it and you should be able to authenticate using Facebook and authorize the application to use your Facebook settings, and finally authorize the user.

Image may be NSFW.
Clik here to view.
clip_image068

Image may be NSFW.
Clik here to view.
clip_image070

 

Logon to Facebook as usual.

Image may be NSFW.
Clik here to view.
clip_image072

The app would request user permissions to give the user details to the ACS service.

Image may be NSFW.
Clik here to view.
clip_image074

Web site will work as required.

Image may be NSFW.
Clik here to view.
clip_image076

Happy coding J

Image may be NSFW.
Clik here to view.

Viewing all articles
Browse latest Browse all 36188

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>