5. Sending a token as a client
In this section, you’re going
to build a simple command-line client. This will make it easier to focus
on the service aspects of the code. Feel free to make it sexy by using
Silverlight or WPF.
For this client, we’ll
share the contract by sharing a project reference. (Many projects do
this, especially when you own both ends of the conversation.) You should
either share the contract through a project reference, or through a
shared assembly.
In this case, our biggest
customer, Maine Reversal, will be building this client. We’ve set up a
trusted relationship with them by swapping keys and configuring them in
ACS—we’ll look at how to do this in the next section. Maine Reversal
won’t be sending in any custom claims of their own, just their issuer
identity. This process essentially gives them a secure username and
password.
We’ve created a helpful utility class called ACSTokenValidator that encapsulates the
process of fetching an ACS header from the AppFabric service. Again,
this code is mostly from the SDK samples with some tweaks we wanted to
make. (Why write new code when they give us code that works?)
To call the GetTokenFromACS method, you’ll pass in the service namespace (StringReversalInc), the issuer name (the client’s name, which is MaineReversal
in this case), the signing key that Maine Reversal uses, and the URL
that represents your protected resource. This doesn’t have to be the
real URI of the intended destination, but in many cases will be. In security parlance this is referred to as the audience. The method call looks like this:
string Token = GetTokenFromACS("StringReversalInc",
"MaineReversal",
"ltSsoI5l+8DzLSmvsVOhOmflAsKHBYrGeCR8KtCI1eE=",
"http://localhost/processstring");
The GetTokenFromACS method performs all the work. It uses the WebClient
class to create the request to ACS. If everything goes well, the ACS
service will respond with a token you can put in your authorization
header on your request to the string-reversal service.
The following listing shows how you can request a token from the ACS service.
Listing 2. How a client gets a token from ACS
You have to provide the GetTokenFromACS method with the base address for the request . This is a combination of the ACS service address, accesscontrol.windows.net, and the namespace for the ACS account, StringReversalInc.
To make the call, you need to
provide three pieces of data: the issuer name (your name in the ACS
configuration), the signing key, and the namespace of the service you’re
trying to reach .
At this point, ACS will
check your credentials. The issuer name is basically your username, and
the signing key is your password. If everything checks out, ACS will
respond with a valid token that you can attach to your request to the
service .
6. Attaching the token
Attaching
the token to the header of the request is fairly simple on most
platforms. You can also put the token information in the URL or the
message body. Doing either isn’t as good as using an authorization
header, so only do this if your system doesn’t support an authorization
header.
To add the token to the authorization header, you can add it to the OutgoingRequest.Headers collection:
string authorizationHeader = string.Format("WRAP access_token=\"{0}\"", httpUtility.UrlDecode(Token));
WebOperationContext.Current.OutgoingRequest.Headers.Add("authorization", authorizationHeader);
To attach the token to the header, you need to use the UrlDecode
method to decode it, and then wrap it with the WRAP leading text. This
tells the destination service that the token is a WRAP token. This text
will be stripped off by the server once the token is validated. Then you
add the header to the outgoing request using the WebOperationContext class.
That’s all the client needs to
do. Your client should be robust enough to handle any errors in the ACS
service call or the ACS token request being denied.
In order for the token
validation and generation to work, you have to set up some configuration
in the ACS service: a trusted relationship with the issuer, and some
rules.