Appendix A: Creating the Sample Claims-Aware Application
Updated: November 15, 2007
Applies To: Windows Server 2008
You can use the claims-aware application in this appendix to test which claims a Federation Service sends in Active Directory Federation Services (AD FS) security tokens. This appendix includes instructions for setting up a sample claims-aware application on your Web server. By using this sample claims-aware application and the supporting instructions in Step 3: Configuring the Web Server, you can prepare the application for testing on the client computer and complete the Web server setup process.
The sample claims-aware application is made up of the following three files:
-
Default.aspx
-
Web.config
-
Default.aspx.cs
For this application to function correctly, you must use the following procedures to create each of the required files in order. After you create the files, move them to the C:\inetpub\wwwroot\claimapp directory on the adfsweb computer.
Use the following procedure to create the Default.aspx file.
-
Start Notepad.
-
Copy and paste the following code into a new Notepad file:
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %><%@ OutputCache Location="None" %><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"><html xmlns="http://www.w3.org/1999/xhtml" ><head><meta http-equiv="Content-Language" content="en-us"><meta http-equiv="Content-Type" content="text/html; charset=windows-1252"><title>Claims-aware Sample Application</title><style><!--.pagetitle { font-family: Verdana; font-size: 18pt; font-weight: bold;}.propertyTable td { border: 1px solid; padding: 0px 4px 0px 4px}.propertyTable th { border: 1px solid; padding: 0px 4px 0px 4px; font-weight: bold; background-color: #cccccc ; text-align: left }.propertyTable { border-collapse: collapse;}td.l{ width: 200px }tr.s{ background-color: #eeeeee }.banner { margin-bottom: 18px }.propertyHead { margin-top: 18px; font-size: 12pt; font-family: Arial; font-weight: bold; margin-top: 18}.abbrev { color: #0066FF; font-style: italic }--></style></head><body><form ID="Form1" runat=server><div class=banner><div class=pagetitle>SSO Sample</div>[ <asp:HyperLink ID=SignOutUrl runat=server>Sign Out</asp:HyperLink> | <a href="<%=Context.Request.Url.GetLeftPart(UriPartial.Path)%>">Refresh without viewstate data</a>]</div><div class=propertyHead>Page Information</div><div style="padding-left: 10px; padding-top: 10px"><asp:Table runat=server ID=PageTable CssClass=propertyTable><asp:TableHeaderRow><asp:TableHeaderCell>Name</asp:TableHeaderCell><asp:TableHeaderCell>Value</asp:TableHeaderCell><asp:TableHeaderCell>Type</asp:TableHeaderCell></asp:TableHeaderRow></asp:Table></div><div class=propertyHead>User.Identity</div><div style="padding-left: 10px; padding-top: 10px"><asp:Table CssClass="propertyTable" ID=IdentityTable runat=server><asp:TableHeaderRow><asp:TableHeaderCell>Name</asp:TableHeaderCell><asp:TableHeaderCell>Value</asp:TableHeaderCell><asp:TableHeaderCell>Type</asp:TableHeaderCell></asp:TableHeaderRow></asp:Table></div><div class=propertyHead>(IIdentity)User.Identity</div><div style="padding-left: 10px; padding-top: 10px"><asp:Table CssClass="propertyTable" ID=BaseIdentityTable runat=server><asp:TableHeaderRow><asp:TableHeaderCell>Name</asp:TableHeaderCell><asp:TableHeaderCell>Value</asp:TableHeaderCell><asp:TableHeaderCell>Type</asp:TableHeaderCell></asp:TableHeaderRow></asp:Table></div><div class=propertyHead>(SingleSignOnIdentity)User.Identity</div><div style="padding-left: 10px; padding-top: 10px"><asp:Table CssClass="propertyTable" ID=SSOIdentityTable runat=server><asp:TableHeaderRow><asp:TableHeaderCell>Name</asp:TableHeaderCell><asp:TableHeaderCell>Value</asp:TableHeaderCell><asp:TableHeaderCell>Type</asp:TableHeaderCell></asp:TableHeaderRow></asp:Table></div><div class=propertyHead>SingleSignOnIdentity.SecurityPropertyCollection</div><div style="padding-left: 10px; padding-top: 10px"><asp:Table CssClass="propertyTable" ID=SecurityPropertyTable runat=server><asp:TableHeaderRow><asp:TableHeaderCell>Uri</asp:TableHeaderCell><asp:TableHeaderCell>Claim Type</asp:TableHeaderCell><asp:TableHeaderCell>Claim Value</asp:TableHeaderCell></asp:TableHeaderRow></asp:Table></div><div class=propertyHead>(IPrincipal)User.IsInRole(...)</div><div style="padding-left: 10px; padding-top: 10px"><asp:Table CssClass="propertyTable" ID=RolesTable runat=server></asp:Table><div style="padding-top: 10px"><table><tr><td>Roles to check (semicolon separated):</td></tr><tr><td><asp:TextBox ID=Roles Columns=55 runat=server/></td><td align=right><asp:Button UseSubmitBehavior=true ID=GetRoles runat=server Text="Check Roles" OnClick="GoGetRoles"/></td></tr></table></div></div></form></body></html> -
Save the Notepad file as Default.aspx in the C:\inetpub\wwwroot\claimapp directory.
Use the following procedure to create the Web.config file.
-
Start Notepad.
-
Copy and paste the following code into a new Notepad file:
<?xml version="1.0" encoding="utf-8" ?><configuration><configSections><sectionGroup name="system.web"><section name="websso"type="System.Web.Security.SingleSignOn.WebSsoConfigurationHandler, System.Web.Security.SingleSignOn, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, Custom=null" /></sectionGroup></configSections><system.web><sessionState mode="Off" /><compilation defaultLanguage="c#" debug="true"><assemblies><add assembly="System.Web.Security.SingleSignOn, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, Custom=null"/><add assembly="System.Web.Security.SingleSignOn.ClaimTransforms, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, Custom=null"/></assemblies></compilation><customErrors mode="Off"/><authentication mode="None" /><httpModules><addname="Identity Federation Services Application Authentication Module"type="System.Web.Security.SingleSignOn.WebSsoAuthenticationModule, System.Web.Security.SingleSignOn, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, Custom=null" /></httpModules><websso><authenticationrequired /><eventloglevel>55</eventloglevel><auditsuccess>2</auditsuccess><urls><returnurl>https://adfsweb.treyresearch.net/claimapp/</returnurl></urls><cookies writecookies="true"><path>/claimapp</path><lifetime>240</lifetime></cookies><fs>https://adfsresource.treyresearch.net/adfs/fs/federationserverservice.asmx</fs></websso></system.web><system.diagnostics><switches><add name="WebSsoDebugLevel" value="0" /> <!-- Change to 255 to enable full debug logging --></switches><trace autoflush="true" indentsize="3"><listeners><add name="LSLogListener" type="System.Web.Security.SingleSignOn.BoundedSizeLogFileTraceListener, System.Web.Security.SingleSignOn, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, Custom=null"initializeData="c:\logdir\claimapp.log" /></listeners></trace></system.diagnostics></configuration> -
Save the Notepad file as Web.config in the C:\inetpub\wwwroot\claimapp directory.
Use the following procedure to create the Default.aspx.cs file.
-
Start Notepad.
-
Copy and paste the following code into a new Notepad file:
using System;using System.Data;using System.Collections.Generic;using System.Configuration;using System.Reflection;using System.Web;using System.Web.Security;using System.Web.UI;using System.Web.UI.WebControls;using System.Web.UI.WebControls.WebParts;using System.Web.UI.HtmlControls;using System.Security;using System.Security.Principal;using System.Web.Security.SingleSignOn;using System.Web.Security.SingleSignOn.Authorization;public partial class _Default : System.Web.UI.Page{const string NullValue = "<span class=\"abbrev\" title=\"Null Reference, or not applicable\"><b>null</b></span>";static Dictionary<string, string> s_abbreviationMap;static _Default(){s_abbreviationMap = new Dictionary<string, string>();//// Add any abbreviations here. Make sure that prefixes of// replacements occur *after* the longer replacement key.//s_abbreviationMap.Add("System.Web.Security.SingleSignOn.Authorization", "SSO.Auth");s_abbreviationMap.Add("System.Web.Security.SingleSignOn", "SSO");s_abbreviationMap.Add("System", "S");}protected void Page_Load(object sender, EventArgs e){SingleSignOnIdentity ssoId = User.Identity as SingleSignOnIdentity;//// Get some property tables initialized.//PagePropertyLoad();IdentityLoad();BaseIdentityLoad();SSOIdentityLoad(ssoId);SecurityPropertyTableLoad(ssoId);//// Filling in the roles table// requires a peek at the viewstate// since we have a text box driving this.//if (!IsPostBack){UpdateRolesTable(new string[] { });}else{GoGetRoles(null, null);}//// Get the right links for SSO//if (ssoId == null){SignOutUrl.Text = "Single Sign On isn't installed...";SignOutUrl.Enabled = false;}else{if (ssoId.IsAuthenticated == false){SignOutUrl.Text = "Sign In (you aren't authenticated)";SignOutUrl.NavigateUrl = ssoId.SignInUrl;}elseSignOutUrl.NavigateUrl = ssoId.SignOutUrl;}}void SecurityPropertyTableLoad(SingleSignOnIdentity ssoId){Table t = SecurityPropertyTable;if (ssoId == null){AddNullValueRow(t);return;}//// Go through each of the security properties provided.//bool alternating = false;foreach (SecurityProperty securityProperty in ssoId.SecurityPropertyCollection){t.Rows.Add(CreateRow(securityProperty.Uri, securityProperty.Name, securityProperty.Value, alternating));alternating = !alternating;}}void UpdateRolesTable(string[] roles){Table t = RolesTable;t.Rows.Clear();bool alternating = false;foreach (string s in roles){string role = s.Trim();t.Rows.Add(CreatePropertyRow(role, User.IsInRole(role), alternating));alternating = !alternating;}}void IdentityLoad(){Table propertyTable = IdentityTable;if (User.Identity == null){AddNullValueRow(propertyTable);}else{propertyTable.Rows.Add(CreatePropertyRow("Type name", User.Identity.GetType().FullName));}}void SSOIdentityLoad(SingleSignOnIdentity ssoId){Table propertyTable = SSOIdentityTable;if (ssoId != null){PropertyInfo[] props = ssoId.GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.DeclaredOnly);AddPropertyRows(propertyTable, ssoId, props);}else{AddNullValueRow(propertyTable);}}void PagePropertyLoad(){Table propertyTable = PageTable;string leftSidePath = Request.Url.GetLeftPart(UriPartial.Path);propertyTable.Rows.Add(CreatePropertyRow("Simplified Path", leftSidePath));}void BaseIdentityLoad(){Table propertyTable = BaseIdentityTable;IIdentity identity = User.Identity;if (identity != null){PropertyInfo[] props = typeof(IIdentity).GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.DeclaredOnly);AddPropertyRows(propertyTable, identity, props);}else{AddNullValueRow(propertyTable);}}void AddNullValueRow(Table table){TableCell cell = new TableCell();cell.Text = NullValue;TableRow row = new TableRow();row.CssClass = "s";row.Cells.Add(cell);table.Rows.Clear();table.Rows.Add(row);}void AddPropertyRows(Table propertyTable, object obj, PropertyInfo[] props){bool alternating = false;foreach (PropertyInfo p in props){string name = p.Name;object val = p.GetValue(obj, null);propertyTable.Rows.Add(CreatePropertyRow(name, val, alternating));alternating = !alternating;}}TableRow CreatePropertyRow(string propertyName, object propertyValue){return CreatePropertyRow(propertyName, propertyValue, false);}TableRow CreatePropertyRow(string propertyName, object value, bool alternating){if (value == null)return CreateRow(propertyName, null, null, alternating);elsereturn CreateRow(propertyName, value.ToString(), value.GetType().FullName , alternating);}TableRow CreateRow(string s1, string s2, string s3, bool alternating){TableCell first = new TableCell();first.CssClass = "l";first.Text = Abbreviate(s1);TableCell second = new TableCell();second.Text = Abbreviate(s2);TableCell third = new TableCell();third.Text = Abbreviate(s3);TableRow row = new TableRow();if (alternating)row.CssClass = "s";row.Cells.Add(first);row.Cells.Add(second);row.Cells.Add(third);return row;}private string Abbreviate(string s){if (s == null)return NullValue;string retVal = s;foreach (KeyValuePair<string, string> pair in s_abbreviationMap){//// We only get one replacement per abbreviation call.// First one wins.//if (retVal.IndexOf(pair.Key) != -1){string replacedValue = string.Format("<span class=\"abbrev\" title=\"{0}\">{1}</span>", pair.Key, pair.Value);retVal = retVal.Replace(pair.Key, replacedValue);break;}}return retVal;}//// ASP.NET server side callback//protected void GoGetRoles(object sender, EventArgs ea){string[] roles = Roles.Text.Split(';');UpdateRolesTable(roles);}} -
Save the file as Default.aspx.cs in the C:\inetpub\wwwroot\claimapp directory.
