Augmenting security with a claims-based architecture

The claims-based architecture can be used to augment your existing security implementation. A common approach will be to create a token service that verifies the consumer identity and creates a signed token including the claims necessary for accessing a resource from a service, living within or outside the security boundaries of the consumer.

The following diagram illustrates this scenario:

Augmenting security with a claims-based architecture

The previous recipe showed us the steps to create SamlSecurityToken. In this recipe, we will create a claims service that accepts the client credentials and returns signed SamlSecurityToken using the group-level permissions of the user as claims. In a Single Sign-On scenario, the generated security token will be posted using form variables to the service provider to get authenticated and make a claim for service access. We will limit the scope of this recipe to understand how a token can be generated using the token service and returned back to the client.

Getting ready

Create a Saml11Helper class using the methods from the previous recipe to create SamlSecurityToken using the ClaimSet object. Modify the serialization helper to return a token XML string instead of writing into a file.

public static string SerializeSamlToken(SamlSecurityToken token)
{
StringBuilder samlBuilder = new StringBuilder();
using (XmlWriter writer = XmlWriter.Create(samlBuilder))
{
try
{
WSSecurityTokenSerializer keyInfoSerializer = new WSSecurityTokenSerializer();
keyInfoSerializer.WriteToken(writer, token);
Console.WriteLine("Saml Token Successfully Created");
}
catch (Exception)
{
Console.WriteLine("Failed to seralize token");
}
}
return samlBuilder.ToString();
}

How to do it...

To create a SamlProvider service, perform the following steps:

  1. Create a Visual C# Console Application project, and add reference to the System.IdentityModel and System.ServiceModel assemblies. Include the Saml11Helper class in the project.
  2. Create a SecurityTokenAuthorizationPolicy class to define a custom authorization policy by implementing the IAuthorizationPolicy (System.IdentityModel.Policy) interface. Define a constructor that accepts an instance of the WindowsClaimSet object:
    public class SecurityTokenAuthorizationPolicy : IAuthorizationPolicy
    {
    WindowsClaimSet claims;
    public SecurityTokenAuthorizationPolicy(WindowsClaimSet claims)
    {
    this.claims = claims;
    }
    }
    
  3. Provide an implementation of the Evaluate method:
    public bool Evaluate(EvaluationContext evaluationContext, ref object state)
    {
    evaluationContext.AddClaimSet(this, claims);
    evaluationContext.RecordExpirationTime (DateTime.Now.AddHours(10));
    return true;
    }
    

    Note

    The WindowsClaimSet instance is added to evaluationContext and an expiration policy is set to expire in 10 hours.

  4. Create a ClaimsTokenAuthenticator class to validate the incoming credentials and create a WindowsClaimSet instance using the WindowsIdentity class. The class inherits from WindowsUserNameSecurityTokenAuthenticator (System.IdentityModel.Selectors) and implements the ValidateUserNamePasswordCore method:
    public class ClaimsTokenAuthenticator : WindowsUserNameSecurityTokenAuthenticator
    {
    protected override ReadOnlyCollection<IAuthorizationPolicy> ValidateUserNamePasswordCore(string userName, string password)
    {
    if (IsAuthenticated(userName, password))
    {
    string name = userName.Split('')[1];
    List<IAuthorizationPolicy> policies = new List<IAuthorizationPolicy>(1);
    WindowsClaimSet claimSet = new WindowsClaimSet(new WindowsIdentity(name), true);
    policies.Add(new SecurityTokenAuthorizationPolicy(claimSet));
    return policies.AsReadOnly();
    }
    return null;
    }
    private bool IsAuthenticated(string userName, string password)
    {
    //TODO: Call the provider to validate the credentials
    return true;
    }
    }
    

    The IsAuthenticated method can be used to call the identity provider (Active Directory/Forms database) and validate the credentials. For the purpose of our recipe, we will assume that the incoming credentials are valid.

    Note

    The includeGroups parameter should be set to true while creating the WindowsClaimSet instance to include the group claims in the output that can be used for the purpose of authorization.

  5. Create a ClaimsTokenManager class by implementing ServiceCrendentialsSecurityTokenManager (System.ServiceModel.Security). The class implements the abstract method—CreateSecurityTokenAuthenticator to return a ClaimsTokenAuthenticator object:
    public override SecurityTokenAuthenticator CreateSecurityTokenAuthenticator(SecurityTokenRequirement tokenRequirement, out SecurityTokenResolver outOfBandTokenResolver)
    {
    if (tokenRequirement.TokenType == SecurityTokenTypes.UserName)
    {
    outOfBandTokenResolver = null;
    return new ClaimsTokenAuthenticator();
    }
    else
    {
    return base.CreateSecurityTokenAuthenticator(tokenRequirement, out outOfBandTokenResolver);
    }
    }
    
  6. We will also create a custom ServiceCredentials implementation that returns the ClaimsTokenManager object in the overridden method—CreateSecurityTokenManager:
    public class ClaimsProviderServiceCredentials : ServiceCredentials
    {
    public ClaimsProviderServiceCredentials()
    : base()
    {
    }
    protected override ServiceCredentials CloneCore()
    {
    return new ClaimsProviderServiceCredentials();
    }
    public override SecurityTokenManager CreateSecurityTokenManager()
    {
    return new ClaimsTokenManager(this);
    }
    }
    
  7. Create SamlProviderService that retrieves ClaimSet from the service's AuthorizationContext and creates SamlSecurityToken using the Saml11Helper class. In this recipe, the serialized token is returned as an XML string:
    public class ClaimsProviderService : IClaimsProviderService
    {
    public string GetSaml11Token()
    {
    var claimSets = new List<ClaimSet>(ServiceSecurityContext. Current.AuthorizationContext.ClaimSets);
    ClaimSet claimSet = claimSets.Find((Predicate<ClaimSet>)delegate(ClaimSet target)
    {
    WindowsClaimSet defaultClaimSet = target.Issuer as WindowsClaimSet;
    return defaultClaimSet != null;
    });
    var accessControlClaims = claimSet.FindClaims(ClaimTypes.Sid, Rights.PossessProperty);
    SamlAssertion assertion = Saml11Helper.CreateSamlAssertionFromUserNameClaims (accessControlClaims);
    SamlSecurityToken token = new SamlSecurityToken(assertion);
    return Saml11Helper.SerializeSamlToken(token);
    }
    }
    

How it works...

The client creates an instance of the ClaimsProviderService proxy and sets the username and password properties for the ClientCrendentials object:

static void Main(string[] args)
{
string userName = WindowsIdentity.GetCurrent().Name;
Console.WriteLine("Enter your password");
string password = GetPasswordFromConsole();
ClaimsProviderServiceClient client = new ClaimsProviderServiceClient();
client.ClientCredentials.UserName.UserName = userName;
client.ClientCredentials.UserName.Password = password;
client.ClientCredentials.ServiceCertificate.Authentication.CertificateValidationMode = System.ServiceModel.Security.X509CertificateValidationMode.PeerOrChainTrust;
Console.WriteLine(client.GetSaml11Token());
Console.ReadLine();
}

When the service operation is invoked, the supplied username and password is retrieved by TokenAuthenticator, which then creates a WindowsClaimSet object that gets assigned to the authorization policy. Assigned ClaimSet is retrieved back in the service using AuthorizationContext, and the group-level permissions assigned to the user are used to create the claims for SamlSecurityToken.

There's more...

In this recipe, the token is returned as an XML string. Realistically, ClaimsProviderService would participate in a federation scenario where it issues the token to a Security Token Service in a different realm using the WS-Trust protocol specification. This is explained further, later in the chapter.

See also

The complete source code for the application is available in the Chapter 1Recipe 3 folder.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.119.159.178