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:
IssuerAddress
This is anEndpointAddress
for the STS that the federation binding should get tokens from.IssuerBinding
This property represents what is sometimes known as the inner binding – the WCF binding used for communicating with the token issuer. This is often aWSHttpBinding
orWS2007HttpBinding
, 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.MessageSecurityVersion
This property specifies which versions of WSSecurity, WSTrust, WSSecureConversation, and WSSecurityPolicy should be used. If you were previously usingWSFederationHttpBinding
, then the correct value for this property isWSSecurity11WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11BasicSecurityProfile10
. If you were previously usingWS2007FederationHttpBinding
, then the correct value isWSSecurity11WSTrust13WSSecureConversation13WSSecurityPolicy12BasicSecurityProfile10
. Using theCreateWSFederationTokenParameters
orCreateWS2007FederationTokenParameters
helper methods will initialize this properly automatically.TokenType
This optional property specifies the type of token that should be requested from the issuer.CacheIssuedTokens
,MaxIssuedCachingTime
, andIssuedTokenRenewalThresholdPercentage
These 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.EstablishSecurityContext
This 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.RequestContext
An 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
😆🙈