overview scenarios accessing claims windows authentication username authentication client certificate authentication
A typical configuration for a WCF service that uses a WS-Trust security token service would be this:
<system.serviceModel>
<services>
<service name=“Common.ClaimsService“>
<endpoint address=“wstrust“
binding=“ws2007FederationHttpBinding“
contract=“Common.IClaimsService“ />
</service>
</services>
<bindings>
<ws2007FederationHttpBinding>
<binding>
<security mode=“TransportWithMessageCredential“>
<message establishSecurityContext=“false“>
<issuerMetadata address=“https://idsrv/issue/wstrust/mex“ />
</message>
</security>
</binding>
</ws2007FederationHttpBinding>
</bindings>
</system.serviceModel>
This uses the 2007 version of the federation binding and advertises the security token service (or rather its metadata endpoint) in configuration (which ends up in the service metadata for svcutil support).
But you need more configuration – first let’s establish trust with the STS, specify the audience URI and set certificate checking:
<system.identityModel>
<identityConfiguration>
<audienceUris>
<add value=“https://roadie:444/identity/wstrust“ />
</audienceUris>
<issuerNameRegistry type=“…ConfigurationBasedIssuerNameRegistry, …“>
<trustedIssuers>
<add name=“IdSrv“
thumbprint=“BFF6C249A2FFAA51A959B422DAAEDCF10E8A38EB“ />
</trustedIssuers>
</issuerNameRegistry>
<certificateValidation certificateValidationMode=“None“ />
</identityConfiguration>
</system.identityModel>
Next – because WCF defaults to symmetric proof keys, we also need to specify a decryption certificate. This is different compared to WIF, and goes directly into the service credentials behavior:
<serviceCredentials useIdentityConfiguration=“true“>
<serviceCertificate findValue=“CN=RP“
storeLocation=“LocalMachine“
storeName=“My“
x509FindType=“FindBySubjectDistinguishedName“/>
</serviceCredentials>
…and of course you need the service authorization behavior to tell WCF to populate Thread.CurrentPrincipal:
<serviceAuthorization principalPermissionMode=“Always“ />
Calling the Service
When you setup the service like above, you will get full svcutil (or ‘Add Service Reference’) support and all client config will be created for you.
I personally prefer the explicit approach of requesting and managing tokens myself. This is accomplished with the WSTrustChannelFactory which is new in .NET 4.5 (but an old friend for people that did WIF before).
private static SecurityToken RequestSecurityToken()
{
// set up the ws-trust channel factory
var factory = new WSTrustChannelFactory(
new UserNameWSTrustBinding(
SecurityMode.TransportWithMessageCredential),
_idpAddress);
factory.TrustVersion = TrustVersion.WSTrust13;
factory.Credentials.UserName.UserName = “bob”;
factory.Credentials.UserName.Password = “abc!123″;
// create token request
var rst = new RequestSecurityToken
{
RequestType = RequestTypes.Issue,
KeyType = KeyTypes.Symmetric,
AppliesTo = new EndpointReference(_serviceAddress.AbsoluteUri)
};
// request token and return
return factory.CreateChannel().Issue(rst);
}
private static void CallService(SecurityToken token)
{
var binding = new WS2007FederationHttpBinding(
WSFederationHttpSecurityMode.TransportWithMessageCredential);
binding.Security.Message.EstablishSecurityContext = false;
// set up channel factory
var factory = new ChannelFactory<IClaimsService>(
binding,
new EndpointAddress(_serviceAddress));
factory.Credentials.SupportInteractive = false;
factory.Credentials.UseIdentityConfiguration = true;
// create channel with specified token
var proxy = factory.CreateChannelWithIssuedToken(token);
var id = proxy.GetIdentity();
}
Using Bearer Tokens
By default WCF uses symmetric proof keys. That means that the SAML token *must* be encrypted with the public key of the relying party to securely transmit the proof key.
Proof tokens provide a linkage between token requests and token usage and thus give you nice anti-repudiation and auditing features – in fact in some industries such audit trails are required.
The downside is that this requires additional key management and for many situations this may not be worth the effort. You can switch to bearer tokens which basically means that the linkage of the two protocol legs is gone, no additional encryption certificate is needed and you base all your protection on SSL.
<bindings>
<ws2007FederationHttpBinding>
<binding>
<security mode=“TransportWithMessageCredential“>
<message establishSecurityContext=“false“
issuedKeyType=“BearerKey“>
<issuerMetadata address=“https://idsrv/issue/wstrust/mex“ />
</message>
</security>
</binding>
</ws2007FederationHttpBinding>
</bindings>
That also means that you can remove the decrypting certificate in the service credentials behavior.
Then you’d request a bearer token from your STS (no encrypting certificate needed anymore in the STS configuration):
var rst = new RequestSecurityToken
{
RequestType = RequestTypes.Issue,
KeyType = KeyTypes.Bearer,
AppliesTo = new EndpointReference(_serviceAddress.AbsoluteUri)
};
Filed under: IdentityModel, WCF
