Just a couple of concluding remarks on this series of posts.
1. Claims checking
The scenario presented in the previous posts contains a subtle flaw: the claims are being requested but not being checked by the service. Even in the first version, where the claim requirements are configured in the service’s binding, the presence of this claims in the message received by the service is not checked.
For this purpose, we must use a custom ServiceAuthorizationManager that overrides the CheckAccessCore method to check if the required claims are contained in the ServiceSecurityContext.AuthorizationContext property.
The BizTalk services SDK already contains such a class in the FederatedAccessManager sample project, so the following assignment will solve this flaw.
2. The model below
The WCF platform defines a security framework based on the security model proposed by the WS-* family of specifications. It’s my opinion that platforms such as WCF simplify but do not isolate the architect/developer from this underlying model. This series of posts also aims to illustrate the importance of its knowledge.
In the last post, I described how to build a service that relies on the BizTalk Identity Services for the authorization decisions, and also how to build a client that uses this service. However, the execution of this client ended up on a “ID3037: The specified request failed.” fault returned by the BizTalk Identity Services STS.
Unfortunately this message error is not documented, so I went to analyze the message exchange between the client and the STS. For this, I used the message logging capability of WCF. I enabled the logging at service level and not at transport level, because at this level the messages are enciphered.
Here is the body of the Security Token Request message:
The problems is not evident, but it is visible in the above message: the <t:Claims> element does not have the Dialect attribute.
Why wasn’t it there?
Before answering this question, let’s recall why it should be there?
Remember that the required claims are one of the service requisites expressed in the service’s policy. Namely, in the <RequestSecurityTokenTemplate>. According to the WS-SecurityPolicy spec:
This required element contains elements which MUST be copied into the request sent to the specified issuer. Note: the initiator is not required to understand the contents of this element.
So, the next step was to verify if the Dialect attribute was in the service policy. Remember, from last post, that the claims requirements were defined in an XML element inserted in the TokenRequestParameters collection.
As seen in the above fragment, the Dialect attribute is present in the service’s policy
Well, apparently this is a “bug” in WCF’s WSDL import process, which handles the <Claims> element differently.
What are the workarounds?
- One method is to intercept the token request at the client side, using a custom token provider and explicitly insert the correct claim requirements. This is what is done by some of the BizTalk services SDK samples.
- Another method is to change the clients’s binding (obtained via the the MetadataResolver) and insert the claims requirement. This is done in the following fragment
In both workarounds, it is necessary to remove the original Claims element (the one imported without the Dialect attribute).
After this change everything runs well.
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.
In the last post, I introduced the BizTalk Identity Services as an example of an publicly available STS. In this post I will describe some aspects of the metadata (WSDL based description) exposed by this STS.
Recall that this metadata can be retrieved at: http://identity.biztalk.net/sts/<username>/sts.wsdl
where <username> is the registered used name.
Beginning at the end (<wsdl:service> element), the service exposes 5 endpoints (<wsdl:port> elements) with the following names:
All of these endpoints expose the same Security Token Service contract, defined by the WS-Trust (Feb. 2005 version) spec.
The principal difference between these endpoints is their policy, referenced by the <wsdl:binding> elements associated to each endpoint. Namely, each policy requires a different token type and claims types in the token request message. This difference is visible in the <sp:SignedSupportingTokens> element.
For instance, the policy of the ‘UserNameForCertificate‘ endpoint requires an UsernameToken.
The ‘…ForCertificate’ suffix, present in all endpoint’s names, means that the messages are protected using a X.509 certificate based scheme. This requirement is expressed by the <sp:ProtectionToken> assertion, present in all policies.
So, the existence of multiple endpoints for the same contract, each with a different policy, allows for different token and claim types to be used with the same STS.
Notice that this metadata describes the STS requirements (required token and claims types) but not its capabilities (issued token and claims types). This type of capabilities are not addressed by the WS-SecurityPolicy language. Instead, they belong to the federation metadata model defined in the (still not very used) WS-Federation spec. However, to the best of my knowledge, the BizTalk Identity Services don’t expose this type of metadata, so these capabilities must be acquired out-of-band.
In the next post, I will show how to create a WCF service that relies on this STS for the authorization decisions. I will also show how to build a client that uses this service.
This is the second post of a series where I describe some issues regarding the definition and usage of claim requirements on the Windows Communication Foundation (WCF) platform. On the first post, I introduced the concept of claim requirements, and how to express them in WS-Policy and WCF. In this post I begin to introduce a usage scenario.
BizTalk Identity Services
(disclaimer: the information below refers to Community Technological Preview, so things will probably change in the future)
Among several other things, BizTalk Services provides a publicly-accessible STS for each registered user. This STS can play two different roles: Identity Provider or Resource side STS (R-STS). In the later role, this STS act as a Policy Decision Point (PDP), responsible for evaluating the service’s access control policy,
- First, it receives a token request from the service’s client with:
- A description of the required authorization claims
- The claims of the requestor
- The address of the target service
- Then, it evaluates the service’s policy using the above input information.
- Finally, if the authorization claims are granted by the authorization policy, it issues a token with them to the requestor.
This R-STS can be used by:
- Services with endpoints “hosted” by BizTalk Connectivity Services. In addition to the connectivity functionality, BizTalk Connectivity Services also plays the role of a Policy Enforcement Point, verifying if the messages received by the “hosted” endpoint contain security tokens with the required authorization claims.
- Independent (“stand alone”) services, that is, services not hosted by BizTalk Services. In this case, the policy enforcement must be done by the service.
The policy of a BizTalk Services STS is defined by a set of rules. Each rule defines a mapping between one or more input claims (claims of the token requestor) and an output claim (claim present in the issued token). When playing the role of an R-STS, these output claims belong to the authorization dialect defined by WS-Federation (see last post).
The metadata of the STS is available at the following addresses:
- http://identity.biztalk.net/sts/<username>/sts.wsdl, accessible via a straight HTTP GET.
- http://identity.biztalk.net/sts/<username>/mex, accessible via the WS-MetadataExchange protocol.
where <username> should be replaced by the user’s name (remember that there is an STS for each registered user).
Observing the contents of this metadata (just register with BizTalk Services and point a browser to the above address) is a rather educative experience, that will be the subject of the next post in this series.
This is the first post of a series where I describe some issues regarding the definition and usage of claim requirements on the Windows Communication Foundation (WCF) platform.
The constraints and requirements of a WCF service can be expressed by a policy, defined according to the WS-Policy spec framework. Typically, this policy is automatically generated from the endpoint’s binding information and embedded into the service’s WSDL.
A policy is composed by assertions, that define specific constraints and requirements. The WS-SecurityPolicy spec defines a set of security specific assertions. One of those is the <IssuedToken> assertion, that is used by services to require security tokens issued by token issuers. The “parameters” of this assertion include:
- An endpoint reference to the token issuer, optionally including the issuer’s address and metadata location
- A set of elements that should be present in the request made by the client to the issuer. These elements, defined by the WS-Trust specs, define aspects such as:
- The requested token and key types.
- The required claims – claims that should be present in the issued token.
The required claims are defined by the <Claims> element, present inside the <IssuedToken> assertion and on the request sent by the client to the token issuer. This <Claims> element supports different ways of expressing the claims requirements. For that purpose, it contains a Dialect attribute (an URI) indicating the specific language used inside the <Claims> element.
The WS-Federation spec (version 1.1) defines a specific dialect for expressing authorization claims, depicted in the following XML
The Information Card Profile also defines a claim dialect where a required claim is represented by a <ClaimType> element:
WCF directly supports this last dialect via the Security.Message.ClaimTypeRequirements property of both WFederationHttpBinding and WS2007FederationHttpBinding. This property represents a collection of ClaimTypeRequirement, where the claim types required by the service can be added.
In principle, it is also possible to use another dialect with WCF. In WS-SecurityPolicy, the <Claims> element is contained inside the <RequestSecurityTokenTemplate> element, which can be populated via the Security.Message.TokenRequestParameters property of any federation binding. This property represents the collection of XmlElement that are childs of the <RequestSecurityTokenTemplate>.
Today, a former participant in one of our .NET courses ask me a couple of questions regarding the implementation of federation scenarios with WCF.
One of the pointers that I gave him was to this slide deck by Todd West, presented at TechEd06. Back in 2006, when I started studying this subject, these slides were a very valuable resource
Previous location of my blog: http://www.cc.isel.ipl.pt/CS/blogs/pfelix/default.aspx