Display Tokens & Geneva

What are display tokens? In short: They allow an STS to pass some or all claims back to the client in a way that the client can read them. This differs from the “real” claims which are part of the security token and are encrypted for the relying party. A popular example of an application that consumes display claims is the CardSpace identity selector that allows you to preview the claims before they get send to the RP.

Look here in section 4.3.6 for the technical specification and here for a good discussion of use and abuse of display tokens.

In Geneva, display tokens are represented by the DisplayToken class (which is a container for DisplayClaims). The SecurityTokenService class has an overridable method called GetDisplayToken in which the DisplayToken gets constructed to be put into the RSTR (see also here). This method internally calls GetDisplayClaimsForSubject on the default ClaimsMapper that is configured on the SecurityTokenServiceConfiguration of your STS. This default claims mapper simply takes all claims found in the subject and emits them as display claims. For some standard claims the mapper already knows the display name and description – the others are emitted without further descriptions.

It seems that in the future you want to extend the ClaimsMapper class for your own display token work – for now the class does not seem to be ready for that. Another behavior of the current Geneva bits is, that display claims are enabled by default – that means if your user requests them (more on that later) all claims will be emitted in clear to the user. This may or may not be what you want. In future builds of Geneva, the display token feature will be opt-in.

But if you are building an STS with the current bits – you almost certainly want to take control over display token generation, because e.g.

  • maybe you emit claims that the user should not be able to see.
  • if you want to emit a display token and you use non-standard claims, you want to provide display names and descriptions.

 

Generating a display token
Currently the easiest way to do this is to override the above mentioned GetDisplayToken method in your STS, e.g.:

protected override DisplayToken GetDisplayToken(
  string requestedDisplayTokenLanguage, IClaimsIdentity subject)
{
    var displayClaims = new List<DisplayClaim>
    {
        new DisplayClaim(WSIdentityConstants.ClaimTypes.GivenName, “FirstName”, “First Name”,
            subject.GetClaimValue(WSIdentityConstants.ClaimTypes.GivenName)),
        new DisplayClaim(WSIdentityConstants.ClaimTypes.Surname, “LastName”, “Last Name”,
            subject.GetClaimValue(WSIdentityConstants.ClaimTypes.Surname)),
        new DisplayClaim(WSIdentityConstants.ClaimTypes.Name, “Name”, “Name”,
            subject.GetClaimValue(WSIdentityConstants.ClaimTypes.Email)),
    };


    return new DisplayToken(requestedDisplayTokenLanguage, displayClaims);
}

(of course – if you want to localize the claims – you should honor the requestDisplayTokenLanguage parameter)

 

Requesting and consuming a display token
The above GetDisplayToken method gets only called if a display token is requested. This is done by adding a <RequestDisplayToken /> element to the RST – either by adding this element to the additional request parameters collection on the binding or by explicitly setting the DisplayTokenLanguage property on the RequestSecurityToken class (e.g. when requesting a token using WSTrustClient).

The returned display token can be found in the RSTR on the RequestedDisplayToken property. The following code snippet shows both the request and the consumption (some details omitted):

WSTrustClient client = new WSTrustClient(
    GetStsBinding(),
    GetStsEndpoint(),
    TrustVersion.WSTrust13,
    GetStsCredentials());

RequestSecurityToken rst = new RequestSecurityToken();
rst.RequestType = WSTrust13Constants.RequestTypes.Issue;
rst.AppliesTo = new EndpointAddress(rp);
rst.TokenType = Saml11SecurityTokenHandler.OasisWssSamlTokenProfile11;
rst.DisplayTokenLanguage = “en”;

RequestSecurityTokenResponse rstr;
client.Issue(rst, out rstr);

foreach (var displayClaim in rstr.RequestedDisplayToken.DisplayClaims)
{
    Console.WriteLine(string.Format(“{0}: {1} ({2})”,
        displayClaim.DisplayTag,
        displayClaim.Description,
        displayClaim.DisplayValue));
}

 

HTH

This entry was posted in ASP.NET, IdentityModel, WCF. Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s