Contents
Introduction
* ASP.Net 4.5 web application can be secured with ADFS 2.0
* Authentication configuration is done in Web.config file
Generate Initial Web.config
* Use Visual Studio to generate an initial Web.config by pointing to ADFS Federation Metadata URL.
* Click Change Authentication button:
* Enter ADFS federation metadata URL into On-Premises Authority field.
* Click OK buttons to create the initial web application
* Relevant elements in the initial Web.config file:
<?xml version="1.0" encoding="utf-8"?> <configuration> <configSections> <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" /> </configSections> <appSettings> <add key="ida:FederationMetadataLocation" value="https://sts.my.com/federationmetadata/2007-06/federationmetadata.xml" /> <add key="ida:Realm" value="https://localhost:44304/" /> <add key="ida:AudienceUri" value="https://localhost:44304/" /> </appSettings> <system.web> <authentication mode="None" /> <authorization> <deny users="?" /> </authorization> <compilation debug="true" targetFramework="4.5" /> <httpRuntime targetFramework="4.5" requestValidationMode="4.5" /> </system.web> <system.webServer> <modules> <add name="WSFederationAuthenticationModule" type="System.IdentityModel.Services.WSFederationAuthenticationModule, System.IdentityModel.Services, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" preCondition="managedHandler" /> <add name="SessionAuthenticationModule" type="System.IdentityModel.Services.SessionAuthenticationModule, System.IdentityModel.Services, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" preCondition="managedHandler" /> </modules> </system.webServer> <system.identityModel> <identityConfiguration> <audienceUris> <add value="https://localhost:44304/" /> </audienceUris> <securityTokenHandlers> <add type="System.IdentityModel.Services.Tokens.MachineKeySessionSecurityTokenHandler, System.IdentityModel.Services, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" /> <remove type="System.IdentityModel.Tokens.SessionSecurityTokenHandler, System.IdentityModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" /> </securityTokenHandlers> <certificateValidation certificateValidationMode="None" /> <issuerNameRegistry type="System.IdentityModel.Tokens.ValidatingIssuerNameRegistry, System.IdentityModel.Tokens.ValidatingIssuerNameRegistry"> <authority name="urn:my:adfs"> <keys> <add thumbprint="F5ADED8729AF0005FA889CCB913C7B7AEFF96B33" /> </keys> <validIssuers> <add name="urn:my:adfs" /> </validIssuers> </authority> </issuerNameRegistry> </identityConfiguration> </system.identityModel> <system.identityModel.services> <federationConfiguration> <cookieHandler requireSsl="true" /> <wsFederation passiveRedirectEnabled="true" issuer="https://sts.my.com/adfs/ls/" realm="https://localhost:44304/" requireHttps="true" /> </federationConfiguration> </system.identityModel.services> </configuration>
Find Issuer Name
* You can find the Issuer Name, e.g. urn:my:adfs, from the initial Web.config file (see previous section):
<authority name="urn:my:adfs"> ... <validIssuers> <add name="urn:my:adfs" /> </validIssuers> </authority>
* Alternatively, you can find it from ADFS2’s federationmetadata.xml file:
– Point browser to federation metadata page, e.g.: https://sts.my.com/federationmetadata/2007-06/federationmetadata.xml
– Find <entityID> attribute, which is the issuer name, at the beginning of the XML:
<EntityDescriptor ID="xxxx" entityID="urn:my:adfs"
Find Issuer Thumbprint
* You can find the thumbprint from the initial Web.config file (see previous section):
<authority name="urn:my:adfs"> <keys> <add thumbprint="F5ADED8729AF0005FA889CCB913C7B7AEFF96B33" /> </keys>
* Alternatively, you can find thumbprint value from ADFS2’s federationmetadata.xml file:
– Point browser to federation metadata page, e.g.: https://sts.my.com/federationmetadata/2007-06/federationmetadata.xml
– Find <KeyDescriptor use=”signing”> element:
<KeyDescriptor use="signing"> <KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#"> <X509Data> <X509Certificate>xxxxxxxxxxxx</X509Certificate> </X509Data> </KeyInfo> </KeyDescriptor>
– Copy and paste base64 characters between X509Certificate element into a temp file with .cer file name ending, e.g. mysts_signing.cer
– Double click the .cer temp file to open the certificate
– Find thumbprint value
* You still need to prepare the thumbprint value:
– Copy thumbprint value (do NOT copy the first empty space, it contains hidden characters!)
– Remove white spaces
– Upper case whole string, e.g. final value is: F5ADED8729AF0005FA889CCB913C7B7AEFF96B33
* You’ll get “Error ID4175 and ConfigurationBasedIssuerNameRegistry” error if you have the wrong thumbprint value.
– See this post for more details.
Final Web.config
* Initial Web.config generated by Visual Studio is only a starting point.
* Need to modify, e.g.:
– Replace https://localhost:44306/ with actual website URL, e.g. https://asp.my.com
* Following is a working example.
Example Web.config
<?xml version="1.0" encoding="utf-8"?> <!-- For more information on how to configure your ASP.NET application, please visit http://go.microsoft.com/fwlink/?LinkId=169433 --> <configuration> <configSections> <!-- config wif --> <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" /> </configSections> <appSettings> <add key="webpages:Version" value="3.0.0.0" /> <add key="webpages:Enabled" value="false" /> <add key="PreserveLoginUrl" value="true" /> <add key="ClientValidationEnabled" value="true" /> <add key="UnobtrusiveJavaScriptEnabled" value="true" /> <!-- config wif --> <add key="ida:FederationMetadataLocation" value="https://sts.my.com/federationmetadata/2007-06/federationmetadata.xml" /> <add key="ida:Realm" value="https://myappc.my.com/myapp/" /> <add key="ida:AudienceUri" value="https://myappc.my.com/myapp/" /> </appSettings> <system.web> <customErrors mode="Off"/> <compilation targetFramework="4.5" /> <httpRuntime targetFramework="4.5" requestValidationMode="4.5" /> <pages> <namespaces> <add namespace="System.Web.Helpers" /> <add namespace="System.Web.Mvc" /> <add namespace="System.Web.Mvc.Ajax" /> <add namespace="System.Web.Mvc.Html" /> <add namespace="System.Web.Routing" /> <add namespace="System.Web.WebPages" /> </namespaces> </pages> <!-- config wif --> <authorization> <deny users="?" /> </authorization> </system.web> <system.webServer> <validation validateIntegratedModeConfiguration="false" /> <handlers> <remove name="ExtensionlessUrlHandler-Integrated-4.0" /> <remove name="OPTIONSVerbHandler" /> <remove name="TRACEVerbHandler" /> <add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" /> </handlers> <modules> <!-- config wif --> <add name="SessionAuthenticationModule" type="System.IdentityModel.Services.SessionAuthenticationModule, System.IdentityModel.Services, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" preCondition="managedHandler" /> <add name="WSFederationAuthenticationModule" type="System.IdentityModel.Services.WSFederationAuthenticationModule, System.IdentityModel.Services, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" preCondition="managedHandler" /> </modules> </system.webServer> <!-- config wif --> <system.identityModel> <identityConfiguration> <audienceUris> <add value="https://myappc.my.com/myapp/" /> </audienceUris> <issuerNameRegistry type="System.IdentityModel.Tokens.ConfigurationBasedIssuerNameRegistry, System.IdentityModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"> <trustedIssuers> <!-- name is IdP entityID which can be found in federationmetadata.xml file --> <add thumbprint="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" name="urn:my:adfs" /> </trustedIssuers> </issuerNameRegistry> <certificateValidation certificateValidationMode="None" /> <securityTokenHandlers> <add type="System.IdentityModel.Services.Tokens.MachineKeySessionSecurityTokenHandler, System.IdentityModel.Services, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" /> <remove type="System.IdentityModel.Tokens.SessionSecurityTokenHandler, System.IdentityModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" /> </securityTokenHandlers> </identityConfiguration> </system.identityModel> <!-- config wif --> <system.identityModel.services> <federationConfiguration> <cookieHandler requireSsl="true" /> <wsFederation passiveRedirectEnabled="true" issuer="https://sts.my.com/adfs/ls/" realm="https://myappc.my.com/myapp/" requireHttps="true" /> </federationConfiguration> </system.identityModel.services> <runtime> <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"> <dependentAssembly> <assemblyIdentity name="System.Web.Helpers" publicKeyToken="31bf3856ad364e35" /> <bindingRedirect oldVersion="1.0.0.0-3.0.0.0" newVersion="3.0.0.0" /> </dependentAssembly> <dependentAssembly> <assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" /> <bindingRedirect oldVersion="0.0.0.0-5.1.0.0" newVersion="5.1.0.0" /> </dependentAssembly> <dependentAssembly> <assemblyIdentity name="System.Web.Optimization" publicKeyToken="31bf3856ad364e35" /> <bindingRedirect oldVersion="1.0.0.0-1.1.0.0" newVersion="1.1.0.0" /> </dependentAssembly> <dependentAssembly> <assemblyIdentity name="System.Web.WebPages" publicKeyToken="31bf3856ad364e35" /> <bindingRedirect oldVersion="1.0.0.0-3.0.0.0" newVersion="3.0.0.0" /> </dependentAssembly> <dependentAssembly> <assemblyIdentity name="WebGrease" publicKeyToken="31bf3856ad364e35" /> <bindingRedirect oldVersion="1.0.0.0-1.5.2.14234" newVersion="1.5.2.14234" /> </dependentAssembly> </assemblyBinding> </runtime> </configuration>
Example Code
* Example to print out all cliam types and values:
protected void Page_Load(object sender, EventArgs e) { var Identity = (ClaimsIdentity)User.Identity; if (!Identity.IsAuthenticated) { log.ErrorFormat("User {0} not authenticated!", GetUserName(Identity)); } else { log.InfoFormat("User {0} authenticated!", GetUserName(Identity)); } var claims = Identity.Claims; foreach (Claim c in claims) { log.InfoFormat("Got claim {0} with value {1}", c.Type, c.Value); } }
Create Relying Party
* Login ADFS server
* Open ADFS management console
* Go to: AD FS 2.0 > Trust Relationships > Replying Party Trusts
* Right click and select Add Relying Party Trust…
* Click Start on Welcome page:
* Select: Enter data about the relying party manually
* Enter:
– Display name: Test ADFS2
* Select: AD FS 2.0 profile
* Skip for now on Configure Certificate screen
* Select: Enable support for the WS-Federation Passive protocol
– Relying party WS-Federation Passive protocol URL: https://myappc.my.com/
* Click OK on Configure Identifiers
* On Choose Issuance screen, select Permit all users to access this replying party
* Review settings on Ready to Add Trust screen
* Click Next to add the relying party
Add Claim Rules
* Login ADFS server
* Open ADFS management console
* Go to: AD FS 2.0 > Trust Relationships > Replying Party Trusts
* Select relying party, e.g. Test ADFS2
* Click Edit Claim Rules…
* Click Add Rule…
* Enter:
– Claim rule name: Name ID
– Attribute store: Active Directory
– LDAP Attribute: SAM-Account-Name
– Outgoing Cliam Type: Name ID
* Click OK twice
* Add additional rules, e.g. E-mail Address
Deploy ASP.Net 4.5 to IIS 7.5
* Start IIS Manager
* Add new application pool
* Add new application
* Enable anonymous authentication
* Enable SSL
* Setup Web.config file
* Restart Default Web Site
Test
* Point browser to https://myappc.my.com/Default.aspx
* Check log file for claims, e.g.
User jimmy authenticated! Got claim http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier with value jimmy Got claim http://schemas.microsoft.com/ws/2008/06/identity/claims/authenticationmethod with value http://schemas.microsoft.com/ws/2008/06/identity/authenticationmethod/windows Got claim http://schemas.microsoft.com/ws/2008/06/identity/claims/authenticationinstant with value 20xx-xx-02T15:40:14.391Z