Alik Levin's

Clarity, Technology, and Solving Problems | PracticeThis.com 

September, 2010

  • Alik Levin's

    Windows Identity Foundation (WIF) By Example Part II – How To Migrate Existing ASP.NET Web Application To Claims Aware

    • 0 Comments

    In this post I outline the steps I needed to complete in order to migrate ASP.NET site from using Windows Integrated authentication to using Windows Identity Foundation.

    Summary of steps:

    • Step 1 – Create simple ASP.NET application
    • Step 2 – Configure and test the application for Windows Integrated authentication
    • Step 3 – Review prerequisites for using Windows Identity Foundation (WIF)
    • Step 4 – Download and run SelfSTS
    • Step 5 – Secure ASP.NET application With Windows Identity Foundation
    • Step 6 – Consume Claims in code and test your work

    The rest of the post is detailed explanation for each step followed by resources in the end.

    Step 1 – Create simple ASP.NET application

    • Run Visual Studio under administrative privileges. It’s not required for this step but it will be required when using Windows Identity Foundation.
    • From the menu choose New Project and then point to ASP.NET Empty Web Application. Give it a name, for example, MigrateWindowsAuthentiactionToWIF. Click OK.
    • In Solution Explorer right click on the MigrateWindowsAuthentiactionToWIF solution and add new Web Form, give it a name, for example, Default.aspx.
    • Drag Literal User Control from the Toolbox and place it between <form> tags in Default.aspx. Give it a name, for example, UserID. The markup should look similar to this:

    <body>
        <form id="form1" runat="server">
        <asp:Literal ID="UserID" runat="server"></asp:Literal>
        </form>
    </body>

    • Switch to Default.aspx.cs - the code behind of Default.aspx – and add the code that identifies current user and prints it out to the Literal User Control, the code should look similar to this:

    protected void Page_Load(object sender, EventArgs e)
    {
        UserID.Text = User.Identity.Name;
    }

    • Compile the application to make sure there are no compilation errors.

    Step 2 – Configure and test the application for Windows Integrated authentication

    • Open web.config file and make sure that the application requires Windows Integrated authentication, the configuration should look similar to the following:

    <authentication mode="Windows"/>

    • Test your application by right clicking on the Default.aspx page in Solution Explorer and choosing View in Browser option. You should see the page displaying your user name in format similar to domain\username or computer\username. Here is what I have got:

    Windows Integrated Authentication ASP.NET

    In the previous steps I have created an ASP.NET web application that utilizes Windows Integrated Authentication.

    In the next section I will accomplish steps to migrate my ASP.NET web application to using Windows Identity Foundation for authentication.

    Step 3 – Review prerequisites for using Windows Identity Foundation (WIF)

    There are several prerequisite in order to work with Windows Identity Foundation. Short list is as follows:

    More info here Windows Identity Foundation (WIF) By Example Part I – How To Get Started.

    Step 4 – Download and run SelfSTS

    To make ASP.NET application Claims Aware there is a need for STS (Security Token Service). Download and use SelfSTS utility that emulates minimal behavior of STS. It’s available here http://code.msdn.microsoft.com/SelfSTS.

    NOTE. SelfSTS utility is for development and testing purposes only. It’s insecure in any possible way. Do not use it for production purposes.

    • Download and run the utility. No installation needed. It’s simple exe. Optionally, click on Edit Claims Types and Values and provide your own. Here is how mine looks:

    Claims and Values in SelfSTS

    • Click save. Then click green Start button, it should turn red.

    SelfSTS for WIF

    • Copy the URL in Metadata textbox – it’s needed when converting the ASP.NET application to claims aware which is next step.

    Step 5 – Secure ASP.NET application With Windows Identity Foundation

    • Switch back to Visual Studio.
    • In Solution Explorer right click on the solution and click on Add STS Reference... option.
    • Type the URL to your ASP.NET application in Application URI text box, here is mine:

    FedUtil Application URI

    • Click Next. You should be presented with warning similar to the following:

    WIF - insecure connection

    • Click Yes to continue. NOTE, this exercise is for development and testing purposes only. For production purposes always use HTTPS.
    • On Security Token Service page of the wizard chose Use an existing STS option and paste the URL to metadata exposed by SelfSTS to STS WS-Federation metadata document location textbox similar as depicted below, click Next.

    SelfSTS metadata in FedUtil

    • You should be presented with a warning that security endpoint exposed over insecure connection. Click Yes to continue. NOTE, exposing the end point over insecure connection is suitable only for development and test purposes, but never for production.

    image

    • Click Next [Disable certificate chain validation option] on STS signing certificate  chain validation error page of the wizard. Another insecure option suitable only for development.
    • Click Next [No Encryption option] on Security Token encryption page of the wizard.  One more insecure option.
    • Click Next on Offered claims page of the wizard.
    • Click Finish on Summary page of the wizard. You should be presented with a dialog “Federation Utility completed successfully”. Click OK.
    • Review the structure of the solution – FederationMetadata folder was added.
    • Review web.config – multiple entries were added. Notice that authentication mode is set to None in web.config. It is interesting to note that authorization section set to deny unauthenticated users. Oxymoron? ;)

    Step 6 – Consume Claims in code and test your work

    • Add reference to Microsoft.IdentityModel.
    • Add using Microsoft.IdentityModel.Claims; declaration.
    • Open Default.aspx.cs and add the code that consumes claims populated in the application context and specifically in User variable, similar to the following:

    IClaimsPrincipal claimsPrincipal = Page.User as IClaimsPrincipal;
    IClaimsIdentity claimsIdentity = (IClaimsIdentity)claimsPrincipal.Identity;
    foreach (var claim in claimsIdentity.Claims )
    {
        Response.Write(claim.ClaimType + " = " + claim.Value + "<BR/>");
    }           

    • Compile your application and browse to the Default.aspx page. You should receive the following exception:

    image

    • Open web.config and loosen the security by adding the following entries inside system.web node. validateRequest is by no means the ultimate security feature, it’s been known for several weaknesses. So even when it’s on, thorough input validation must be performed. Turning it off lowers security bar. Be aware of it. In production this must be addressed.

    <httpRuntime requestValidationMode="2.0"/>
    <pages validateRequest="false"/>

    • Try navigating to Default.aspx.cs again. The result should be similar to the following (except the values would be different), here is how mine looks:

    ASP.NET application protected by WIF

    • Congratulations! Your application is Claims Aware and protected by Windows Identity Foundation.

    More Info

    Related Books

  • Alik Levin's

    Windows Identity Foundation (WIF) By Example Part III – How To Implement Claims Based Authorization For ASP.NET Application

    • 0 Comments

    This post is based on what I am reading now in Vittorio’s new book Programming Windows Identity Foundation (Dev - Pro).

    To complete this example I assume you have working claims aware ASP.NET application. If you do not – complete one of these before you proceed (15 minutes or less):

    The rest of the post is a step-by-step walkthrough of creating claims based authorization for existing claims aware ASP.NET Web Application. Summary of steps:

    • Step 1 – Implement Claims Authorization Library
    • Step 2 – Configure ASP.NET Application to use the Claims Authorization Library
    • Step 3 – Configure Authorization Policy
    • Step 4 – Test your work

    Step 1 – Implement Claims Authorization Library

    • Make sure you run Visual Studio in Administrator mode.
    • Right click on the solution in Solution Explorer and add new Class Library project. Give it a name, for example, MyClaimsAuthorizationManager.
    • Delete default Class1.cs.
    • Add new class and give it a name, for example, ZipClaimsAuthorizationManager. I will implement an authorization based on postal codes.
    • Add reference to Microsoft.IdentityModel and to System.Web assemblies.
    • Add the following using declarations

    using System.IO;
    using System.Xml;
    using Microsoft.IdentityModel.Claims;
    using Microsoft.IdentityModel.Configuration;

    • Extend  ClaimsAuthorizationManager  class overriding its AccessCheck method and implementing a constructor to your ZipClaimsAuthorizationManager class. Your code should look similar to this:

    namespace MyClaimsAuthorizationManager
    {
        class ZipClaimsAuthorizationManager : ClaimsAuthorizationManager
        {
            private static Dictionary<string, int> m_policies = new Dictionary<string, int>();

           
    public ZipClaimsAuthorizationManager(object config)
            {
                XmlNodeList nodes = config as XmlNodeList;
                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 = new XmlTextReader(new StringReader(node.OuterXml));
                        reader.MoveToContent();
                        string resource = reader.GetAttribute("resource");
                        reader.Read();
                        string claimType = reader.GetAttribute("claimType");
                        if (claimType.CompareTo(ClaimTypes.PostalCode) == 0)
                        {
                            throw new ArgumentNullException("Zip Authorization is not specified in policy in web.config");
                        }
                        int zip = -1;
                        bool success = int.TryParse(reader.GetAttribute("Zip"),out zip);
                        if (!success)
                        {
                            throw new ArgumentException("Specified Zip code is invalid - check your web.config");
                        }
                        m_policies[resource] = zip;
                    }
                }
            }

            public override bool CheckAccess(AuthorizationContext context)
            {
                //GET THE IDENTITY
                //FIND THE POSTALCODE CLAIM'S VALUE IN IT
                //COMPARE WITH THE POLICY
                int allowedZip = -1;
                int requestedZip = -1;
                Uri webPage = new Uri(context.Resource.First().Value);
                IClaimsPrincipal principal = (IClaimsPrincipal)HttpContext.Current.User;
                if (principal == null)
                {
                    throw new InvalidOperationException("Princiapl is not populate in the context - check configuration");
                }
                IClaimsIdentity identity = (IClaimsIdentity)principal.Identity;
                if (m_policies.ContainsKey(webPage.PathAndQuery))
                {
                    allowedZip = m_policies[webPage.PathAndQuery];
                    requestedZip = -1;
                    int.TryParse((from c in identity.Claims
                                            where c.ClaimType == ClaimTypes.PostalCode
                                            select c.Value).FirstOrDefault(), out requestedZip);
                }
                if (requestedZip!=allowedZip)
                {
                    return false;
                }
                return true;
            }
        }
    }

    • Compile the solution to make sure there is no compilation errors.
    • Locate the compiled library, in my case MyClaimsAuthorizationManager.dll. It will need to be dropped into bin folder of the ASP.NET web application.

    Step 2 – Configure ASP.NET Application to use the Claims Authorization Library

    To proceed further you need to to have working Claims Aware ASP.NET application. Consider these walkthroughs to quickly build one:

    Next steps are performed in your ASP.NET web application. Do not add reference to your Claims Authorization Manager library you created in previous step. Your ASP.NET web application should be “unaware” of it except web.config.

    • Configure your ASP.NET web application to include WIF’s ClaimsAuthorizationModule in its pipeline by adding the following entry to HttpModules section in web.config (valid for development web server that ships with Visual Studio, for IIS7 it is modules section under system.webServer node)

    <add name="ClaimsAuthorizationModule"
         type="Microsoft.IdentityModel.Web.ClaimsAuthorizationModule, Microsoft.IdentityModel, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />

    Step 3 – Configure Authorization Policy

    SelfSTS used for ASP.NET claims based authoprization

    • Click save and then click on big green Start button so it turns red.
    • Configure the ASP.NET application to use your newly developed authorization manager by adding the following section to  service node that is located inside microsoft.identityModel node.
    • Add authorization policy to express what Zip code is allowed to access the site, the result should look similar to this:

    <claimsAuthorizationManager type="MyClaimsAuthorizationManager.ZipClaimsAuthorizationManager, MyClaimsAuthorizationManager" >
      <policy resource="/default.aspx">
        <claim claimType="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/postalcode" Zip="11111" />
      </policy>
    </claimsAuthorizationManager>

    Step 4 – Test your work

    • Notice that in previous step the claim that’s being issued for me by SelfSTS has the value of 12345 and the policy requires Zip’s value of 11111.
    • Run the application by pressing Ctrl+F5.
    • Assuming that the start page is default.aspx you should get blank screen.
    • Now configure either the policy in web.config or the postalcode claim issued by SelfSTS to the same value and run the application once again, you should see the default.aspx page code executed and produces expected results, similar to the following:

    Claims Based AAuthorization for ASP.NET application in action

    Notice, this exercise is not complete authorization solution – it only showcases the technology and how its pieces worlk altogether.

    More Info

    Related Books

  • Alik Levin's

    Protocols Supported By Windows Identity Foundation (WIF)

    • 3 Comments

    Some information in this post is based on Vittorio’s new book Programming Windows Identity Foundation (Dev - Pro).

    Protocols supported by Windows Identity Foundation (WIF):

    • WS-Federation
    • WS-Trust
    • WS-Security
    • WS-SecurityPolicy
    • WS-Addressing

    SAML-P protocol is not supported by WIF. SAML 1.1 and SAML 2.0 tokens can be used with WIF (see Claims Extracted by Windows Identity Foundation from Different Token Types). Sharepoint 2010 claims authentication uses WIF thus does not support SAML-P protocol neither. ADFS 2.0 is a Microsoft product that supports  SAML-P protocol.  Use ADFS V2.0 to allow SAML 2.0 bsed federation for Sharepoint 2010, here is how - Configuring SharePoint 2010 and ADFS v2 End to End.

    Good overview for both ADFS 2.0 and WIF - Security Talk: Azure Federated Identity Security Using ADFS 2.0, another good overview that covers Azure AppFabric Access Control Service (ACS) and ADFS 2.0 integration here - Access Control Service & ADFS v2.0 Integration

    There are 3rd parties that offer SAML federation capabilities extending WIF similar to Safewhere’s SAML 2.0 for Windows Identity Foundation and Componentsoft's ASP.NET SAML Component - SAML 1.1 & SAML 2 for C#, VB.NET & ASP.NE

    Case study how Microsoft IT used WIF and ADFS to provide federation with 3rd parties - MSIT Showcase Enhancing Federation Services for Internal and External Partners.

    More Info

    Related Books

Page 1 of 3 (7 items) 123