Establishing Trust from an ASP.NET Relying Party Application to an STS using FedUtil

[Starting with the .NET Framework 4.5, Windows Identity Foundation (WIF) has been fully integrated into the .NET Framework. The version of WIF addressed by this topic, WIF 3.5, is deprecated and should only be used when developing against the .NET Framework 3.5 SP1 or the .NET Framework 4. For more information about WIF in the .NET Framework 4.5, also known as WIF 4.5, see the Windows Identity Foundation documentation in the .NET Framework 4.5 Development Guide.]

FedUtil.exe is provided with Windows® Identity Foundation (WIF). It helps you to establish trust from a relying party (RP) application to security token services (STSes). It provides the following capabilities:

  • Register an existing production STS as a trusted issuer of the RP application.

  • Help develop a claims-aware application by offering a local STS.

  • Make an existing application claims-aware.

  • Update federation metadata for an RP application.

  • Schedule automatic updates of the federation metadata for an RP application.

The following sections show you how to do each of these tasks using FedUtil. You can also do them manually by making the same changes to your RP application’s web.config file that FedUtil does.

Note

Because FedUtil changes the configuration file, it might alter the existing security configuration of the application. Although FedUtil comments out any existing sections that are not needed, rather than deleting them, you should review the configuration file after running FedUtil to ensure that it has not commented out any security configuration upon which the application depends. Also note that FedUtil backs up your existing configuration file.

1. Create a local STS

In this exercise, you create a local STS for use with our claims-aware ASP.NET relying party application. Note that you must run FedUtil from inside Visual Studio to do this. This option is intended to help development of a claims-aware relying party ASP.NET application with a non-production STS. Later, we’ll see how you can switch to using a production STS.

Note

You must run Visual Studio in Elevated mode for FedUtil to work correctly.

In Visual Studio, open the File menu and select New, Web Site. Select Claims-aware ASP.NET Web Site.

Next, right-click your project in the Solution Explorer and select Add STS Reference:

79a0b161-f082-4c34-96e7-7da5d3126776

This runs the FedUtil tool. You’ll see the FedUtil dialog, beginning with the Welcome to Federation Utility tool page:

55362f83-729f-4ecb-84a6-7d7f18ce736a

This page requires you to enter two fields:

  1. Application configuration location: Specify the path to the web.config file for your ASP.NET service. If you run FedUtil from outside Visual Studio, or you run it from the Tools menu in Visual Studio without having a project open, this field is empty. If you run FedUtil by right-clicking on a project in Visual Studio, this field already contains the path to the web.config file for your project. The web.config file must already exist and should be in its default state (that is, as it was generated by Visual Studio). If you run FedUtil more than once on the same web.config file, FedUtil simply overwrites the content that it adds to the web.config file.

  2. Application URI: Specify the URI for your ASP.NET service. Note that this is a .svc file. If you run FedUtil from outside Visual Studio, or you run it from the Tools menu in Visual Studio without having a project open, this field is empty. If you run FedUtil by right-clicking on a project in Visual Studio, this field already contains two URIs for your project: one that uses localhost, and one that uses the fully qualified domain name for your computer, if available. This URI is used as the realm value while configuring the application for claims. It is also used as the first audience URI. If you want to specify additional audience URIs, you must do so manually. If the URI is not secure (that is, does not begin with “https://”), you receive a warning when you click Next.

When you have provided the information, click Next. You’ll see the Security Token Service page. Select Create a new STS project in the current solution:

e49ab820-73fb-4c19-974b-0c00cb5970f3

Note that if you run FedUtil from outside Visual Studio, or if you run FedUtil from the Tools menu in Visual Studio without having a project open, the Create a new STS project in the current solution option is not available.

Click Next. The Summary page appears:

969492e8-73d1-4029-a797-28a77f28f004

The Summary page shows the information you entered in the Application Information dialog, your choice to create a new STS, the claims requested by the application, and the changes that FedUtil will make to your application’s configuration.

Click Finish.

If you look at your web.config file, you’ll see that FedUtil has modified it:

  • The following application settings are added:

    <appSettings>
        <add key="FederationMetadataLocation" value="C:\inetpub\wwwroot\ClaimsAwareWebSite1_STS\FederationMetadata\2007-06\FederationMetadata.xml" />
    </appSettings>
    
  • All users have been granted access to the federation metadata:

    <location path="FederationMetadata">
        <system.web>
          <authorization>
            <allow users="*" />
          </authorization>
        </system.web>
    </location>
    
  • The WSFederationAuthenticationModule and SessionAuthenticationModule are added to the <system.Web>/<httpModules> element:

    <httpModules>
    ...
        <add name="WSFederationAuthenticationModule" type="Microsoft.IdentityModel.Web.WSFederationAuthenticationModule, Microsoft.IdentityModel, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
        <add name="SessionAuthenticationModule" type="Microsoft.IdentityModel.Web.SessionAuthenticationModule, Microsoft.IdentityModel, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
    </httpModules>
    
  • They are also added to the <system.webServer>/<modules> element:

    <system.webServer>
    ...
        <modules>
            <add name="WSFederationAuthenticationModule" type="Microsoft.IdentityModel.Web.WSFederationAuthenticationModule, Microsoft.IdentityModel, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" preCondition="managedHandler" />
            <add name="SessionAuthenticationModule" type="Microsoft.IdentityModel.Web.SessionAuthenticationModule, Microsoft.IdentityModel, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" preCondition="managedHandler" />
        </modules>
    ...
    </system.webServer>
    
  • Finally, the <microsoft.identityModel>/<service> element is modified as follows:

    <microsoft.identityModel>
        <service>
            <audienceUris>
                <add value="https://localhost:58496/ClaimsAwareWebSite2/" />
            </audienceUris>
            <federatedAuthentication enabled="true">
                <wsFederation passiveRedirectEnabled="true" issuer="https://localhost:58497/ClaimsAwareWebSite2_STS/" realm="https://localhost:58496/ClaimsAwareWebSite2/" requireHttps="false" />
                <cookieHandler requireSsl="false" />
            </federatedAuthentication>
            <applicationService>
                <claimTypeRequired>
                    <claimType type="https://schemas.xmlsoap.org/ws/2005/05/identity/claims/name" optional="true" />
                    <claimType type="https://schemas.microsoft.com/ws/2008/06/identity/claims/role" optional="true" />
                </claimTypeRequired>
            </applicationService>
            <issuerNameRegistry type="Microsoft.IdentityModel.Tokens.ConfigurationBasedIssuerNameRegistry, Microsoft.IdentityModel, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35">
                <trustedIssuers>
                    <add thumbprint="0E2A9EB75F1AFC321790407FA4B130E0E4E223E2" name="CN=STSTestCert" />
                </trustedIssuers>
            </issuerNameRegistry>
        </service>
    </microsoft.identityModel>
    
    • An <audienceUris> element is added to specify the URI of the claims-aware ASP.NET relying party application.

    • A <federatedAuthentication> element is added to specify the location of the STS for this claims-aware ASP.NET relying party application. For this exercise, the local STS is used.

    • An <applicationService>/<claimTypeRequired> element is added to specify the claims that the application requires in any tokens that are issued to it by the STS. For this exercise, the default claims “name” and “role” are used. Note that the relying party doesn’t really depend on these claim type requirements. They are present in the configuration file for two reasons:

      1. They allow FedUtil to create correct application federation metadata.

      2. They provide an easy way for relying parties to update the claim type requirements of the relying party application.

    • An <issuerNameRegistry>/<trustedIssuers> element is added to specify the certificate that the STS uses to sign the tokens that it issues. The STS will use a default certificate to sign the tokens it generates. This cert is named “STSTestCert” and it is added to your certificate store automatically for use by the STS. The certificate file is present in the STS project. The password for the file is “STSTest”. This should not be used in a production exercise. You can replace the default certificate with any other certificate. Please ensure that the user for your IIS process has access to the private key for any such certificate. You might also choose to create a type derived from IssuerNameRegistry to perform a programmatic validation of certificates of the trusted issuers.

      security Security Note
      If you run FedUtil again to establish trust from your RP application to a different STS, FedUtil will add the certificate for the new STS, but will not remove the certificate for the old STS. If you want your RP application to no longer trust the old STS, you must edit the web.config file and remove the certificate for the old STS.

Also, if you look at the Solution Explorer, you’ll see that FedUtil has added a new project to your solution. This project is the local STS. Note also that a federation metadata document has been added to both the relying party application and the local STS.

0d9713f7-ebf0-4741-8a85-6cb36d99ece2

Note that the tokens that are issued by this local STS are not encrypted.

To add additional claims to be issued by the local STS, open CustomSecurityTokenService.cs in the STS project under the App_Code folder, and navigate to the GetOutputClaimsIdentity method and add the additional claims.

2. Register an existing production STS

In this exercise, you establish trust from an ASP.NET relying party to an existing STS.

In Visual Studio, open the File menu and select New, Web Site. Select Claims-aware ASP.NET Web Site. Right-click your project in the Solution Explorer and select Add STS Reference. This runs the FedUtil tool. In the Welcome to the Federation Utility Tool page, make sure the Application configuration location and Application URI are correct and click Next.

In the Application Information page, select Use an Existing STS:

18b594ce-a7da-4ca4-b025-756aa7ed156c

You must specify the location of the federation metadata endpoint for the production STS. You can click the Test Location button to make sure the metadata document is accessible. This button makes a request to the specified endpoint and displays the response in your default Web browser. For this exercise, we use an Active Directory® Federation Services (AD FS) 2.0 STS. When you have specified the location of the federation metadata document, click Next.

Note that if you specify an STS that has a certificate that is not trusted by the local certificate store, you’ll see the following warning message: “ID1025: A certificate chain processed, but terminated in a root certificate which is not trusted by the trust provider.” If you want to continue anyway, click Yes. If not, click No and select a different STS.

Another Application Information page appears, this time asking you to select No encryption or Enable encryption:

Confirm with your STS administrator that token encryption is supported by the production STS. If so, enabling encryption is recommended. For this exercise, select Enable encryption. Now you must select the certificate that the relying party wants the STS to use when encrypting the tokens.

Use default certificate means that if the local STS has already created a certificate for encrypting tokens, then this same certificate is used again for decryption. When registering a production STS, this isn’t very common, because the production STS will probably not use the same certificate that you used for the local STS. You should not use this option in a production solution. If you have a service certificate already, you might want to use the same certificate.

If you select an existing certificate, FedUtil displays the certificate(s) in the local certificate store. The certificate must have a private key and a subject name. Make sure that the identity (for example, NETWORK SERVICE) under which the application runs has access to the private key of the certificate.

For this exercise, you can either use the default certificate or select an existing one. When you are done, click Next.

The Offered Claims page appears:

b310bfbc-3186-4d81-bacc-913aa80d8a33

It contains a list of claims that are offered by the STS. FedUtil gets this list by downloading the metadata from the STS and parsing it. By default, FedUtil configures only the name and role claims as required claims in the relying party’s configuration. To see how to configure your relying party application to require additional claims, see 3. Update Federation Metadata. If there are claims required by your relying party application but not offered by the STS, you should contact the STS administrator and make the necessary agreements.

Click Next. The Summary page appears:

104f1b7c-f19e-43bf-a6aa-9eb4d92f3532

If you selected a test certificate, the application information includes this note: “Selected application certificate: A new certificate with subject name 'CN=DefaultApplicationCertificate' will be added to the personal and trusted people certificate store, if not already present.” If you selected an existing certificate, you’ll see the thumbprint for that certificate.

The Summary page shows the information you entered in the Application Information dialog, your choice to use an existing STS, the claims requested by the application, and the changes that FedUtil will make to your application’s configuration.

The Summary page also includes a checkbox labeled “Schedule daily metadata updates for this application”. If you check this checkbox, FedUtil schedules a task to update the application’s metadata at midnight every night. For more information, see How to: Perform Trust Management using FedUtil.

Click Finish.

The following are the changes to the web.config file of the relying party:

  • The following application settings are added. “Specified STS” refers to the STS you specified in FedUtil.

    <appSettings>
        <add key="FederationMetadataLocation" value="<specified STS>" />
    </appSettings>
    
  • All users have been granted access to the federation metadata:

    <location path="FederationMetadata">
        <system.web>
          <authorization>
            <allow users="*" />
          </authorization>
        </system.web>
    </location>
    
  • The WSFederationAuthenticationModule and SessionAuthenticationModule are added to the <system.Web>/<httpModules> element:

    <httpModules>
    ...
        <add name="WSFederationAuthenticationModule" type="Microsoft.IdentityModel.Web.WSFederationAuthenticationModule, Microsoft.IdentityModel, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
        <add name="SessionAuthenticationModule" type="Microsoft.IdentityModel.Web.SessionAuthenticationModule, Microsoft.IdentityModel, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
    </httpModules>
    
  • They are also added to the <system.webServer>/<modules> element:

    <system.webServer>
    ...
        <modules>
            <add name="WSFederationAuthenticationModule" type="Microsoft.IdentityModel.Web.WSFederationAuthenticationModule, Microsoft.IdentityModel, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" preCondition="managedHandler" />
            <add name="SessionAuthenticationModule" type="Microsoft.IdentityModel.Web.SessionAuthenticationModule, Microsoft.IdentityModel, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" preCondition="managedHandler" />
        </modules>
    ...
    </system.webServer>
    
  • Finally, the <microsoft.identityModel>/<service> element is modified as follows. “Specified STS” refers to the STS that you specified in FedUtil.

    <microsoft.identityModel>
        <service>
          <audienceUris>
            <add value="https://localhost:57349/ClaimsAwareWebSite2/" />
          </audienceUris>
          <federatedAuthentication>
            <wsFederation passiveRedirectEnabled="true" issuer="https://<specified STS>/FederationPassive/" realm="https://localhost:57349/ClaimsAwareWebSite2/" requireHttps="false" />
            <cookieHandler requireSsl="false" />
          </federatedAuthentication>
          <serviceCertificate>
            <certificateReference x509FindType="FindByThumbprint" findValue="48BF03FCEDA703DE09E0F1F0CEFED60BB92B3DD8" storeLocation="LocalMachine" storeName="My" />
          </serviceCertificate>
          <applicationService>
            <claimTypeRequired>
              <!--Following are the claims offered by STS 'http://<specified STS>/Trust'. Add or uncomment claims that you require by your application and then update the federation metadata of this application.-->
              <claimType type="https://schemas.xmlsoap.org/ws/2005/05/identity/claims/name" optional="true" />
              <claimType type="https://schemas.microsoft.com/ws/2008/06/identity/claims/role" optional="true" />
              <!--<claimType type="https://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress" optional="true" />-->
              <!--<claimType type="https://schemas.xmlsoap.org/ws/2005/05/identity/claims/upn" optional="true" />-->
              <!--<claimType type="https://schemas.xmlsoap.org/claims/CommonName" optional="true" />-->
              <!--<claimType type="https://schemas.xmlsoap.org/claims/EmailAddress" optional="true" />-->
              <!--<claimType type="https://schemas.xmlsoap.org/claims/Group" optional="true" />-->
              <!--<claimType type="https://schemas.xmlsoap.org/claims/UPN" optional="true" />-->
              <!--<claimType type="https://schemas.xmlsoap.org/ws/2005/05/identity/claims/privatepersonalidentifier" optional="true" />-->
              <!--<claimType type="https://schemas.xmlsoap.org/ws/2005/05/identity/claims/webpage" optional="true" />-->
              <!--<claimType type="https://schemas.xmlsoap.org/ws/2005/05/identity/claims/title" optional="true" />-->
              <!--<claimType type="https://schemas.xmlsoap.org/ws/2005/05/identity/claims/picture" optional="true" />-->
              <!--<claimType type="https://schemas.xmlsoap.org/ws/2005/05/identity/claims/manager" optional="true" />-->
              <!--<claimType type="https://schemas.xmlsoap.org/ws/2005/05/identity/claims/department" optional="true" />-->
            </claimTypeRequired>
          </applicationService>
          <issuerNameRegistry type="Microsoft.IdentityModel.Tokens.ConfigurationBasedIssuerNameRegistry, Microsoft.IdentityModel, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35">
            <trustedIssuers>
              <add thumbprint="5C8885A8E3D29D6BF6C9365E00B1BEA5EB284D1E" name="CN=<specified STS>, OU=US-Federated Identity, O=Microsoft Corporation, L=Redmond, S=Washington, C=US" />
            </trustedIssuers>
          </issuerNameRegistry>
        </service>
      </microsoft.identityModel>
    
    • An <audienceUris> element is added to specify the URI of the claims-aware ASP.NET relying party application.

    • A <federatedAuthentication> element is added to specify the location of the STS for this claims-aware ASP.NET relying party application. This is the STS that you specified in FedUtil.

    • A <serviceCertificate> element is added to specify the location of the certificate that the claims-aware ASP.NET relying party application uses to encrypt its communications with the STS. This is the certificate that you specified in FedUtil.

    • An <applicationService>/<claimTypeRequired> element is added to specify the claims that the application requires in any tokens that are issued to it by the STS. By default, FedUtil configures your claims-aware ASP.NET relying party application to require only the name and role claims. To see how to configure your relying party application to require additional claims, see 3. Update Federation Metadata.

    • An <issuerNameRegistry>/<trustedIssuers> element is added to specify the certificate that the STS uses to sign the tokens that it issues.

Note that you can run FedUtil repeatedly to switch from a local STS to a production STS and back again. Each time you run FedUtil, it simply overwrites the configuration it created previously. However, you cannot use FedUtil to switch from using a local or production STS to using no STS.

Also note that if you run FedUtil and create a local STS, then switch to a production STS, the <issuerNameRegistry> element in your configuration file will contain two trusted issuers. One is the local STS and the other is the production STS. Once you’re ready to deploy your application, you should remove the local STS from the issuer name registry.

3. Update Federation Metadata

By default, when you use FedUtil and specify a production STS, FedUtil configures your application to require only the name and role claims. You can see this by looking at the <Microsoft.IdentityModel>/<service>/<applicationService>/<claimTypeRequired> element in your application’s web.config file:

<claimTypeRequired>
    <!--Following are the claims offered by STS '<specified STS>',
and added at 4/15/2009 3:57:07 PM.
Add or uncomment claims that you require by your application
and then update the federation metadata of this application.-->
    <claimType type="https://schemas.xmlsoap.org/ws/2005/05/identity/claims/name" optional="true" />
    <claimType type="https://schemas.microsoft.com/ws/2008/06/identity/claims/role" optional="true" />
    <!--<claimType type="https://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress" optional="true" />-->
...
</claimTypeRequired>

For example, in the previous code snippet, the emailaddress claim is commented out. To configure your application to require additional claims, uncomment that claims that you want. Then, in Solution Explorer, right-click your application project and select Update federation metadata:

14597f95-c206-4df5-bb01-36f677bb8bf5

FedUtil updates the federation metadata of your application to reflect your changes to the list of required claims. Afterward, open your application’s FederationMetadata.xml file and look at the updated list of required claims. It should now include any additional claims that you uncommented in your application’s web.config file. Note that FedUtil also makes a backup copy of your application’s web.config file.

<fed:ClaimTypesRequested>
    <auth:ClaimType Uri="https://schemas.xmlsoap.org/ws/2005/05/identity/claims/name" Optional="True" xmlns:auth="http://docs.oasis-open.org/wsfed/authorization/200706" />
    <auth:ClaimType Uri="https://schemas.microsoft.com/ws/2008/06/identity/claims/role" Optional="True" xmlns:auth="http://docs.oasis-open.org/wsfed/authorization/200706" />
...
</fed:ClaimTypesRequested>

You can also add custom claim types to your application’s web.config file. You must then ask your STS administrator to update the STS policy for your application so that it issues the new claim types.