In the previous two posts, I presented some information regarding the BizTalk Identity Services STS.
In this post I will show how to build a minimalistic WCF service that relies on this STS for the authorization decisions. I will also show how to build a client that uses this service.
For the sake of clarity, I will use no configuration file, so everything will be done in code.
The service’s endpoint uses a WSFederationHttpBinding, configured as follows
- The IssuedKeyType property is set to SecurityKeyType.SymmetricKey. This means that the proof-of-possession key will be a symmetric key (see WS-Trust for details). It also means that the STS must have the certificate of the service, in order to encipher the proof-of-possession key (see below for how to configure the STS with this certificate).
- The IssuedTokenType property reflects the type of token issued by the STS (a version 1.1 SAML token).
- The IssuerAddress property points to the STS endpoint that issues the required tokens. In this case, it’s the endpoint with name ‘SelfSignedSamlForCertificate’ (see part3), that accepts self-issued SAML tokens.
- The IssuerMetadataAddress property points to the address of the STS metadata.
Why is the IssuerAddress necessary? Namely, isn’t the IssuerMetadataAddress enough? Because, as seen in the previous part, this metadata contains several endpoints that implement the STS contract. By specifying the required endpoint’s address, this ambiguity is solved.
The previous settings define the required token type but not the required claims types. However, the desired claims dialect (“http://schemas.xmlsoap.org/ws/2006/12/authorization/authclaims“) is not directly supported by WCF, so the ClaimTypeRequirement property cannot be used. For this purpose, this requirement must be directly configured in the TokenRequestParameters collection.
Finally, I create a service host, add an endpoint with this binding, set the service’s certificate and enable metadata retrieval.
The <servicehost> string should be replace by the host name.
BizTalk Identity Services configuration
The following configurations are required at the BizTalk Identity Services, after login under the <username> account:
- Manage Access Control/Relying Party: add the address of the service’s endpoint’s (http://<servicehost>:8080/saac/ep1) and the service’s certificate. This association between an address and a certificate is necessary because the STS needs the public key of the relying service to encrypt the proof-of-possession token.
- Manage Access Control/Rules: define a claim mapping with:
- Input Claim:
- Type = ‘Username’
- Value = <username>
- Issuer = ‘identity.biztalk.net’
- Output Claims
- Type = ‘Resource#Operation’
- Value = ‘http://<servicehost>:8080/saac/ep1#operation‘
- Issuer = ‘identity.biztalk.net/<username>’
- This mapping means that the STS will issue, to a requestor that proves to be the <username> user, a token with the authorization claim “http://<servicehost>:8080/saac/ep1#operation“
- Input Claim:
At the client side, I use the MetadataResolver class to dynamically build the binding and address to the service, instead of statically using the svcutil.exe tool. Just to simply the example. the interface with the service contract is shared between the service and the client.
Then I create a ChannelFactory<T>, using the resolved binding and address, set the client certificate authentication details (PeerTrust because the service’s certificate is “home made”), create a binding and call the service’s operation.
Running the scenario
When I first ran this scenario, the CardSpace UI popped up, because the STS requires a SAML token but does not point to the metadata of its issuer. Then I selected the card that I registered in BizTalk Services, waited a couple of seconds for the client to request the authorization token and got a “ID3037: The specified request failed.” fault exception.
Why? Well, that’s the subject of the next post of this series.