WCF Security Token Service

[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.]

In Visual Studio, open the File menu and select New, Web Site. Select WCF Security Token Service.

If you look at your web.config file, you’ll see a number of differences from the web.config for a typical ASP.NET Web site.

  • The following application settings have been added:

    <appSettings>
        <add key="IssuerName" value="PassiveSigninSTS"/>
        <add key="SigningCertificateName" value="CN=STSTestCert"/>
        <add key="EncryptingCertificateName" value=""/>
    </appSettings>
    

    The STS uses a default certificate to sign the tokens it issues. 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.

  • All users have been granted access to the federation metadata. The federation metadata contains information about the public key of the token signing certificate, the endpoints that are exposed by the STS, and what claims are issued.

    <location path="FederationMetadata">
        <system.web>
            <authorization>
                <allow users="*" />
            </authorization>
        </system.web>
    </location>
    
  • The <system.Web>/<assemblies> element now contains a reference to the Microsoft.IdentityModel.dll assembly:

    <add assembly="Microsoft.IdentityModel, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
    
  • The authentication has been changed from “Windows” to “None”:

    <authentication mode="None">
    
  • An authentication service, profile service, and role service have been added:

    <system.web.extensions>
        <scripting>
            <webServices>
            <!--
                Uncomment this section to enable the authentication service. Include 
                requireSSL="true" if appropriate. 
                <authenticationService enabled="true" requireSSL = "true|false"/>
            -->
            <!--
                Uncomment these lines to enable the profile service, and to choose the 
                profile properties that can be retrieved and modified in ASP.NET AJAX 
                applications.
                <profileService enabled="true"
                readAccessProperties="propertyname1,propertyname2"
                writeAccessProperties="propertyname1,propertyname2" />
            -->
            <!--
                Uncomment this section to enable the role service.
                <roleService enabled="true"/>
            -->
            </webServices>
            <!--
                <scriptResourceHandler enableCompression="true" enableCaching="true" />
            -->
        </scripting>
    </system.web.extensions>
    
  • The following services, endpoints, bindings, and behaviors have been added:

    <system.serviceModel>
        <services>
            <service name="Microsoft.IdentityModel.Protocols.WSTrust.WSTrustServiceContract" behaviorConfiguration="ServiceBehavior">
            <endpoint address="IWSTrust13" binding="ws2007HttpBinding" contract="Microsoft.IdentityModel.Protocols.WSTrust.IWSTrust13SyncContract"  bindingConfiguration="ws2007HttpBindingConfiguration"/>
            <host>
              <baseAddresses>
                <add baseAddress="https://localhost/STSService1/Service.svc" />
              </baseAddresses>
            </host>
            <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
          </service>
        </services>
        <bindings>
          <ws2007HttpBinding>
            <binding name="ws2007HttpBindingConfiguration">
              <security mode="Message">
                <message establishSecurityContext="false" />
              </security>
            </binding>
          </ws2007HttpBinding>
        </bindings>
        <behaviors>
          <serviceBehaviors>
            <behavior name="ServiceBehavior">
              <!-- To avoid disclosing metadata information, set the value below to false and remove the metadata endpoint above before deployment -->
              <serviceMetadata httpGetEnabled="true" />
              <!-- To receive exception details in faults for debugging purposes, set the value below to true.  Set to false before deployment to avoid disclosing exception information -->
              <serviceDebug includeExceptionDetailInFaults="false" />
            </behavior>
          </serviceBehaviors>
        </behaviors>
    </system.serviceModel>
    
  • A trace has been added, which you can uncomment to enable tracing. For more information, see WIF Tracing and How to: Enable Tracing.

    <!-- 
      Uncomment the lines below to enable WIF tracing to: WIFTrace.e2e. 
      Open the trace file using the SvcTraceViewer.exe tool (shipped with the WCF SDK available from Microsoft) or a xml viewer.
      Refer to MSDN if you wish to add WCF tracing.
      -->
    
      <!--<system.diagnostics>
        <sources>
          <source name="Microsoft.IdentityModel" switchValue="Verbose">
            <listeners>
              <add name="xml" type="System.Diagnostics.XmlWriterTraceListener" initializeData="WIFTrace.e2e" />
            </listeners>
          </source>
        </sources>
        <trace autoflush="true" />
      </system.diagnostics>-->
    

In the App_Code folder, open CustomSecurityTokenService.cs.

  • Update static readonly string[] ActiveClaimsAwareApps to include the URLs of relying party applications to which you want this STS to issue tokens.

  • In the override of the GetOutputClaimsIdentity method, add the claims that your relying party application requires the STS to issue, as well as any custom claims that you want your STS to issue.

CustomSecurityTokenService.cs implements the following required methods.

  1. GetScope. This method takes the caller’s IClaimsPrincipal and the incoming RST and returns the configuration for the token issuance request, which is represented by the Scope class. In this method, you can normalize the relying party’s address and choose signing and encryption keys. Typically, security tokens are encrypted so that only the relying party can read them.

  2. GetOutputClaimsIdentity. This method takes the caller’s IClaimsPrincipal, the incoming RST, and the Scope object returned from GetScope, and returns the IClaimsIdentity to be included in the issued token. This lets you decide which claims are included in the token.