The following custom claims transformation module demonstrates how to enumerate the claims that are present in incoming claims, corporate claims, and outgoing claims. It also demonstrates how to add claims to these groups. Finally, it shows how to determine whether the transform module is called in the preprocessing stage or the post-processing stage.
using System;
using System.Collections.Generic;
using System.Text;
using System.Web.Security.SingleSignOn;
using System.Web.Security.SingleSignOn.Authorization;
namespace CustomTransformModule
{
//Custom transform module that you write should implement interface: IClaimTransform
//defined in System.Web.Security.SingleSignOn namespace found in
//System.Web.Security.SingleSignOn.ClaimTransforms.dll
public class CustomTransformModuleClass : IClaimTransform
{
public CustomTransformModuleClass()
{ }
/*
TransformClaims() method is defined in IClaimTransform interface. This method
provides access to Incoming, Corporate and Outgoing claims in the token and
cookie. This method is called twice:
In Pre-processing phase (before the Federation Server does its own claim
tranformation as defined in the trustpolicy file) and in Post-processing phase
(after the Federation Server has finished doing it's claim transformation).
Third parameter: outgoingClaims will always contain the final set of claims that
are sent in the token/cookie returned to the client.
Parameters:
transformStage: This parameter is an enum which represents the stage in which
the method is currently being called. It can have value:
PreProcessing or PostProcessing.
issuer: This is the URI of the issuer of the token
target: This is the URI of the target of the token.
By looking at issuer and target parameters you can determine if these set of claims
are going in a token or a cookie.
if issuer and target are same then it means it is a cookie. If they are not same then
it means it is a token.
*/
public void TransformClaims(ref SecurityPropertyCollection incomingClaims,
ref SecurityPropertyCollection corporateClaims,
ref SecurityPropertyCollection outgoingClaims,
ClaimTransformStage transformStage,
string issuer,
string target)
{
/*
//If you want to see what claims are present in incomingClaims
displayClaims(incomingClaims);
//Similarly if you want to see what claims are present in corporateClaims
displayClaims(corporateClaims);
//Similarly if you want to see what claims are present in outgoingClaims
displayClaims(outgoingClaims);
//If you want to add some claims in Incoming claim collection
addClaims(incomingClaims);
//Similarly if you want to add some claims in Corporate claim collection.
addClaims(corporateClaims);
//Similarly if you want to add some claims in Outgoing claim collection.
addClaims(outgoingClaims);
*/
//Checking value of transformStage parameter to determine in which stage
//is Transform module called.
if (transformStage == ClaimTransformStage.PreProcessing)
{
//Do something you want to do in Pre-Processing phase
}
else if(transformStage == ClaimTransformStage.PostProcessing)
{
addClaims(outgoingClaims);
//Do something you want to do in Post-Processing phase
}
}
//This function demonstrates how to create a UPN, Email, Common Name, Group and Custom claim.
//It also shows how to add claims in a SecurityPropertyCollection (which can be
//either of Incoming, Corporate, Outgoing claim collection set).
private void addClaims(SecurityPropertyCollection securityPropertyCollection)
{
//Adding a upn claim to the collection.
string upn = "user@microsoft.com";
securityPropertyCollection.Add(SecurityProperty.CreateUserPrincipalNameProperty(upn));
// create an email claim and add it to the collection
string emailAddr = "user@msn.com";
securityPropertyCollection.Add(SecurityProperty.CreateEmailNameProperty(emailAddr));
// create a common name claim and add it to the collection
string commonName = "Test user";
securityPropertyCollection.Add(SecurityProperty.CreateCommonNameProperty(commonName));
// create a group claim and add it to the collection
string group = "Happy Testers";
securityPropertyCollection.Add(SecurityProperty.CreateGroupProperty(group));
// Creating a new custom cadding a custom claim to the collection
string claimName = "ssn";
string claimValue = "123-45-6789";
securityPropertyCollection.Add(SecurityProperty.CreateCustomClaimProperty(claimName,claimValue));
}
//This function demonstrates how to enumerate claims in a SecurityPropertyCollection
//(which can be either of Incoming, Corporate, Outgoing claim collection set).
private void displayClaims(SecurityPropertyCollection securityPropertyCollection)
{
foreach (SecurityProperty securityProperty in securityPropertyCollection)
{
if(securityProperty.ClaimType.Equals(WebSsoClaimType.Custom))
{
Console.WriteLine("Custom claim name: {0} - value: {1}",
securityProperty.Name, securityProperty.Value);
}
else if (securityProperty.ClaimType.Equals(WebSsoClaimType.Upn))
{
Console.WriteLine("UPN - {0}", securityProperty.Value);
}
else if (securityProperty.ClaimType.Equals(WebSsoClaimType.Email))
{
Console.WriteLine("Email - {0}", securityProperty.Value);
}
else if (securityProperty.ClaimType.Equals(WebSsoClaimType.CommonName))
{
Console.WriteLine("Common Name - {0}", securityProperty.Value);
}
//If the Uri matches GroupPropertyExtension.Uri then it is group claim.
else if (securityProperty.ClaimType.Equals(WebSsoClaimType.Group))
{
Console.WriteLine("Group - {0}", securityProperty.Value);
}
}
}
}
}