Having done quite a bit of WCF customization myself, it is fun to see how Geneva framework wires itself up into the WCF runtime.
The high-level goals are as follows:
- route the token provisioning, serialization and authentication through the Geneva pipeline
- make an IClaimsPrincipal available on the service side
- allow setting issued tokens directly on a ChannelFactory
On the service side this is achieved by passing in a ServiceHost instance into FederatedServiceCredentials.ConfigureHost(). What does exactly happen inside that call?
- replace the standard WCF ServiceCredential with a FederatedServiceCredential
- the service credential drives the creation of a SecurityTokenManager (in this case the FederatedSecurityTokenManager)
- this in turn creates the token provider, serializer and authenticator. In Geneva all three functionalities are inside a SecurityTokenHandler.
- Geneva’s token manager dispatches the incoming requests to the corresponding methods of the token handler depending on the incoming token type
- set the service certificate
- either by copying the standard service certificate specified in the ServiceCredential.
- or by replacing the existing one with the certificate specified in the <microsoft.IdentityModel /> configuration section
- create token resolvers for
- the service certificate
- issuer certificates (if the WCF knownIssuers configuration element is set)
- set a ClaimsAuthenticationManager (either a pass-through one, or the one specified in code/config)
- set the PrincipalPermissionMode to Custom. This is necessary to populate Thread.CurrentPrincipal with an IClaimsPrincipal.
- set the service authorization manager.
- service authorization managers drive the creation of authorization policies.
- an authorization policy in turn can parse the WCF internal claims and set Thread.CurrentPrincipal. Persisting the bootstrap token also happens here.
- to make this all work, Geneva has its own service authorization manager (IdentityModelServiceAuthorizationManager) and its own authorization policy (Microsoft.IdentityModel.Tokens.AuthorizationPolicy).
On the client side things are much simpler. The main purpose of the Geneva client side plumbing is to allow more direct interaction with tokens. The standard WCF issued token client credential assumes you want to implicitly acquire a token from a WS-Trust token service.
Token provisioning is driven by so called SecurityTokenParameters. Whereas the WCF built-in IssuedSecurityTokenParameters only allow specifying the details of the token issuer, the Geneva FederatedClientCredentialsParameters instead allows setting a pre-acquired token directly.
So when you call FederatedClientCredentials.ConfigureChannelFactory<T> all that is happening is, that the standard WCF ClientCredentials get replaced by the FederatedClientCredentials class. This creates a FederatedClientCredentialsSecurityTokenManager which in turn instantiates the token serializer (via the security token handlers) and a token provider that is aware of FederatedClientCredentialsParameters.
To actually set the token on a channel, you call one of the extension methods for ChannelFactory<T>. They can be found in Microsoft.IdentityModel.Protocols.WSTrust.ChannelFactoryOperations. These extension methods take the token you pass in, create the token parameters and add them to the token parameters collection of the channel.