Using SAML as a Client Credential Type in WCF (updated to WIF RTM)

A reader has asked me to update the Client SAML sample to WIF RTM (for background and motivation please read here first).

The main work was in the SAML security token handler Validate method, this looks now like this:

public override ClaimsIdentityCollection ValidateToken(SecurityToken token)
{
    if (token == null)
    {
        throw new ArgumentNullException(“token”);
    }       

    var samlToken = token as SamlSecurityToken;
    if (samlToken == null)
    {
        throw new ArgumentException(“token”);
    }
    if (samlToken.Assertion == null)
    {
        throw new ArgumentException(“token”);
    }
   
    var assertion = samlToken.Assertion as Saml11Assertion;
    this.ValidateConditions(samlToken.Assertion.Conditions, false);

    // extract claims from token
    var identity = new ClaimsIdentity(“ClientSaml”);
    ProcessStatement(assertion.Statements, identity, “Client”);
   
    // call authentication and filtering logic
    IClaimsIdentity newIdentity;

    try
    {
        if (ValidateUser(identity, out newIdentity))
        {
            return new ClaimsIdentityCollection(new IClaimsIdentity[] { newIdentity });
        }
        else
        {
            throw new SecurityTokenValidationException(“Authentication failed”);
        }
    }
    catch (Exception ex)
    {
        throw new SecurityTokenValidationException(“Security token validation failed”, ex);
    }
}

You would then derive from the base handler and implement the ValidateUser method. This method does some sort of authentication based on the incoming claims and returns an IClaimsIdentity containing the claims that should get passed through to the service code, e.g.:

// sample implementation – do not use for production ;)
protected override bool ValidateUser(ClaimsIdentity id, out IClaimsIdentity newIdentity)
{
    newIdentity = null;
    var usernameClaim = id.Claims.First(c => c.ClaimType == WSIdentityConstants.ClaimTypes.Name);
    var passwordClaim = id.Claims.First(c => c.ClaimType == _passwordClaimType);
    var customerIdClaim = id.Claims.First(c => c.ClaimType == _customerIdClaimType);
   
    if (usernameClaim.Value == passwordClaim.Value)
    {
        newIdentity = new ClaimsIdentity(new Claim[]
        {
            usernameClaim,
            customerIdClaim
        }, “ClientSaml”);

        return true;
    }

    return false;
}

You can find the complete source code here.

This entry was posted in IdentityModel. Bookmark the permalink.

1 Response to Using SAML as a Client Credential Type in WCF (updated to WIF RTM)

  1. Rakesh says:

    Thanks for the write-up. The issue at hand is that we have a WSDL that was provided for integration, and 2 operations require SAML 2.0 assertions, whereas one does not. For the operations that require SAML 2.0 assertion, developing a client using .Net 4.0, what is the best way to integrate SAML 2.0 components? WIF has a CTP that does not have backward compatibility with the prior version installed with VS2012 (.net 3.5 version I believe), and we are therefore stuck having to override the SOAP header using the IClientMessageInspector methods.

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 )

Facebook photo

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

Connecting to %s