As .NET Core has evolved, the WCF team has worked to expand support for WCF client scenarios on .NET Standard and .NET Core. Until recently, one of the gaps developers faced when building WCF clients for .NET Core was the lack of WSFederationHttpBinding and WS2007FederationHttpBinding. These bindings support WS-Federation authentication scenarios where users authenticate with a security token service (like Active Directory Federation Services) and use a token from that authentication provider to authenticate with a separate service (called the ‘relying party’). Last month, the System.ServiceModel.Federation package (targeting .NET Standard 2.0) released, enabling these client WCF scenarios!
This post covers the basics of getting started with System.ServiceModel.Federation in your .NET Core application. It goes over how to install the package and how its use differs from previous WS-Fed WCF scenarios.
Using WSFederationHttpBinding
To use the .NET Standard-compatible version of WSFederationHttpBinding, add a reference to the System.ServiceModel.Federation package with version 4.8.0.
<PackageReference Include="System.ServiceModel.Federation" Version="4.8.0" />
This package contains the WSFederationHttpBinding type that is now used for both WSFederationHttp and WS2007FederationHttp scenarios. A key difference between .NET Framework WCF scenarios and .NET Core WCF scenarios is that .NET Core doesn’t use application config files for setting up WCF objects, so the binding will need to be configured in code rather than in app.config, as you might have previously done for .NET Framework.
If you’re using a WCF client (derived from ClientBase<T>) to interact with your WCF service, you can use the client’s constructor that takes a Binding and an EndpointAddress as parameters. In many cases, existing client code generated by .NET Framework’s SvcUtil will continue to work. Just make sure you’re using client constructors that accept a binding as a parameter instead of one that expects to create the binding from configuration. Updates to dotnet-svcutil and Visual Studio’s WCF Web Service Reference Provider Tool are planned which will enable auto-generating .NET Standard-specific clients for WCF services with WS-Federation bindings.
The WSFederationHttpBinding constructor takes a single parameter of type WSTrustTokenParameters. This parameter is used to specify details about the token issuer (STS) the binding should get tokens from and how those tokens should be handled. The easiest way to create an instance of WSTrustTokenParameters is to use the WSTrustTokenParameters.CreateWS2007FederationTokenParameters or WSTrustTokenParameters.CreateWSFederationTokenParameters helper methods. These static methods will create WSTrustTokenParameters for WS2007Federation and WSFederation scenarios, respectively. Both methods take the issuer binding (also called the ‘inner binding’) and endpoint address as parameters. It’s also possible to create your own WSTrustTokenParameters via the constructor and specify exactly the behavior you need. Important properties on the WSTrustTokenParameters type include:
- IssuerAddressThis is an- EndpointAddressfor the STS that the federation binding should get tokens from.
- IssuerBindingThis property represents what is sometimes known as the inner binding – the WCF binding used for communicating with the token issuer. This is often a- WSHttpBindingor- WS2007HttpBinding, but will vary based on the scenario and should match the type of binding that would have been used for the issuerBinding in a .NET Framework app.config file.
- MessageSecurityVersionThis property specifies which versions of WSSecurity, WSTrust, WSSecureConversation, and WSSecurityPolicy should be used. If you were previously using- WSFederationHttpBinding, then the correct value for this property is- WSSecurity11WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11BasicSecurityProfile10. If you were previously using- WS2007FederationHttpBinding, then the correct value is- WSSecurity11WSTrust13WSSecureConversation13WSSecurityPolicy12BasicSecurityProfile10. Using the- CreateWSFederationTokenParametersor- CreateWS2007FederationTokenParametershelper methods will initialize this properly automatically.
- TokenTypeThis optional property specifies the type of token that should be requested from the issuer.
- CacheIssuedTokens,- MaxIssuedCachingTime, and- IssuedTokenRenewalThresholdPercentageThese properties indicate whether tokens should be cached and for how long. In many cases, these properties don’t need to be set as the defaults (tokens are cached for 60% of their lifetime) are sufficient.
- EstablishSecurityContextThis boolean determines whether or not to use a secure conversation context. Again, this property often doesn’t need to be set because the default (true) is common.
- RequestContextAn optional string that will be passed along in WS-Trust requests to the token issuer that can help with correlating messages for diagnostic purposes.
Once the WSTrustTokenParameters instance has been created and passed to a WSFederationHttpBinding, that binding can be used to create a WCF client (derived from ClientBase) or ChannelFactory.
Here is an example of creating a typical WSFederationHttpBinding:
// First, create the inner binding for communicating with the token issuer.
// The security settings will be specific to the STS and should mirror what
// would have been in an app.config in a .NET Framework scenario.
var issuerBinding = new WS2007HttpBinding(SecurityMode.TransportWithMessageCredential);
issuerBinding.Security.Message.ClientCredentialType = MessageCredentialType.UserName;
issuerBinding.Security.Message.EstablishSecurityContext = false;
// Next, create the token issuer's endpoint address
var endpointAddress = new EndpointAddress("https://<IssuerAddress>/adfs/services/trust/13/usernamemixed");
// Finally, create the WSTrustTokenParameters
var tokenParameters = WSTrustTokenParameters.CreateWS2007FederationTokenParameters(issuerBinding, endpointAddress);
// This workaround is necessary only until an updated System.ServiceModel.Federation ships with
// https://github.com/dotnet/wcf/issues/4426 fixed.
// The CreateWSFederationTokenParameters helper method does not have this bug.
tokenParameters.KeyType = SecurityKeyType.SymmetricKey;
// Create the WSFederationHttpBinding
var binding = new WSFederationHttpBinding(tokenParameters);
A sample client using WSFederationHttpBinding is available on GitHub.
Wrap up
With the release of System.ServiceModel.Federation, it is now be possible to implement scenarios that consume WCF services with WS-Federation bindings on .NET Core. The System.ServiceModel.Federation package is built from the WCF repository, so please leave feedback there if you run into anything that doesn’t work right.
 
                         
                     
        
Have tried but seems derived keys are not supported (WSTrustTokenParameters.RequireDerivedKeys). The WSFederationHttpBinding automatically sets it to false.
Never thought I’d see such an incommodious property name as
in an official Microsoft package 🙂
Yea, that name is definitely a mouthful. 🙂 It’s long because it’s trying to capture all the different components of a message security version. There are probably other (more succinct) ways of doing that, but those properties have been around for a while now (since 3.0, I think), so we don’t want to change them now.
and on the previous line
😆🙈