<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>All Free Tech &#187; wcf</title>
	<atom:link href="http://www.allfreetech.com/tag/wcf/feed" rel="self" type="application/rss+xml" />
	<link>http://www.allfreetech.com</link>
	<description>For developers</description>
	<lastBuildDate>Tue, 01 Feb 2011 13:45:24 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.1.3</generator>
		<item>
		<title>Building a Claims-Based Security Model in WCF &#8211; Part 2</title>
		<link>http://www.allfreetech.com/microsoft-net/building-a-claims-based-security-model-in-wcf-part-2-71.html</link>
		<comments>http://www.allfreetech.com/microsoft-net/building-a-claims-based-security-model-in-wcf-part-2-71.html#comments</comments>
		<pubDate>Wed, 23 Dec 2009 03:55:36 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Microsoft .Net]]></category>
		<category><![CDATA[wcf]]></category>

		<guid isPermaLink="false">http://www.allfreetech.com/?p=71</guid>
		<description><![CDATA[In Part 1 of this article I discussed the motivation behind implementing a claims-based security model for your WCF services and introduced a simple approach to normalizing claims for different credential types using a custom authorization policy. During the article, I discussed the following: How different user credentials are mapped to a set of claims [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.theserverside.net/tt/articles/showarticle.tss?id=ClaimsBasedSecurityModel">In Part 1</a> of this article I discussed the motivation behind implementing a claims-based security model for your WCF services and introduced a simple approach to normalizing claims for different credential types using a custom authorization policy. During the article, I discussed the following:</p>
<ul>
<li>How different user credentials are mapped to a set of claims that are attached to the security context for each request.</li>
<li>How to access those claims through the AuthorizationContext to perform authorization, in lieu of role-based security checks.</li>
<li>How to create a custom authorization policy to issue a set of normalized claims for any credential, and attach those claims to the AuthorizationContext for later authorization checks.</li>
</ul>
<p>Part 1 introduces some of the benefits of a claims-based security model. Specifically, that it enables service developers to focus on application-specific claims to authorize calls to each operation, while decoupling the authentication step and removing dependencies on specific credential types. This model also allows applications to support more than one credential type by mapping authenticated callers to a set of normalized claims.</p>
<p>In this article I will discuss other design decisions related to the claims-based security model. I&rsquo;ll walk through the process for creating a set of claims-based utilities to encapsulate claims authorization at the service tier; and explain how SAML tokens can be issued by a security token service for authentication, supplying normalized claims to the security context.</p>
<h1>Claims-Based Permission Demands</h1>
<p>When you work with a traditional role-based security model, as I discussed in Part 1 of this article, you often apply role-based permission demands at the service operation to authorize calls. For services that may authorize both Windows and custom username and password credentials, you can stack permission demands as shown here &ndash; for each of the supported roles at an operation:</p>
<pre>[PrincipalPermission(SecurityAction.Demand,
Role=&quot;BUILTIN\\Administrators&quot;)]
[PrincipalPermission(SecurityAction.Demand,
Role=&quot;Administrators&quot;)]
public string AdminOperation()
{
  // protected code
}
</pre>
<p>Permission demands implemented with the <strong>PrincipalPermission</strong> or <strong>PrincipalPermissionAttribute</strong> rely on the security principal attached to the executing thread to authorize calls. The most common check is to require specific roles through the <strong>IsInRole()</strong> function exposed by the <strong>IPrincipal</strong> type. This model for authorizing access to operations is easy to work with, and familiar, but an equivalent set of claims-based principal and principal permission types do not exist. In this section, I will describe a set of claims-based utilities I created to implement this familiar model around claims. It includes the following custom types:</p>
<ul>
<li>ClaimsPrincipal</li>
<li>ClaimsPrincipalPermission</li>
<li>ClaimsPrincipalPermissionAttribute</li>
</ul>
<h1>ClaimsPrincipal</h1>
<p>In Part 1 I showed you how to use a custom authorization policy to map a UserName credential to a set of application claims to be attached to the AuthorizationContext. Custom authorization policies are also responsible for providing a security principal for the request thread, in the form of an IPrincipal type. The custom authorization policy from Part 1 extracted the identity of the caller from the EvaluationContext, mapped that caller to a set of claims to be used for authorization, and created a simple GenericPrincipal with the identity and no roles. This work is done in the Evaluate() function of the custom authorization policy, as shown here:</p>
<pre>public bool Evaluate(EvaluationContext evaluationContext, ref object state)
{
  if (evaluationContext.Properties.ContainsKey(&quot;Identities&quot;))
  {
    List&lt;IIdentity&gt; identities =
evaluationContext.Properties[&quot;Identities&quot;] as List&lt;IIdentity&gt;;
    IIdentity identity = identities[0];

    ClaimSet claims = MapClaims(identity);

    GenericPrincipal newPrincipal = new GenericPrincipal(identity, null);
    evaluationContext.Properties[&quot;Principal&quot;] = newPrincipal;

    if (claims!=null)
      evaluationContext.AddClaimSet(this, claims);

    return true;
  }
  else
    return false;
}
</pre>
<p>Supplying a security principal is merely a formality in this case &ndash; since authorization is performed directly against the custom claim set added to the AuthorizationContext via <strong>AddClaimSet()</strong>. Assuming claims are assigned according to those discussed in Part 1, the following code looks for a claim set issued by <em> http://www.thatindigogirl.com/samples/2006/06/issuer</em> in the AuthorizationContext. In this example, the code checks that the claim set contains the &ldquo;delete&rdquo; claim for the &ldquo;customers&rdquo; resource:</p>
<pre>public void DeleteCustomer(string customerId)
{
  AuthorizationContext authContext =
ServiceSecurityContext.Current.AuthorizationContext;

  ClaimSet issuerClaimSet = null;
  foreach (ClaimSet cs in authContext.ClaimSets)
  {
    Claim issuerClaim =
Claim.CreateNameClaim(&quot;http://www.thatindigogirl.com
/samples/2006/06/issuer&quot;);

    if (cs.Issuer.ContainsClaim(issuerClaim))
      issuerClaimSet=cs;
  }

  if (issuerClaimSet==null)
    throw new SecurityException(&quot;Access is denied. No claims were
provided from the expected issuer.&quot;);

  Claim c = new Claim(&quot;http://schemas.thatindigogirl.com
/samples/2006/06/identity/claims/delete&quot;,
&quot;http://schemas.thatindigogirl.com/samples/2006/06/identity
/resources/customers&quot;, Rights.PossessProperty);

  if (!issuerClaimSet.ContainsClaim(c))
    throw new SecurityException(&quot;Access is denied. Required claims not
satisfied.&quot;);

  // delete customer
}
</pre>
<h2>Implementing IClaimsPrincipal and ClaimsPrincipal</h2>
<p>The first step in creating a first class claims-based model is to create a custom <strong>ClaimsPrincipal</strong> type for the request thread &ndash; to encapsulate the set of claims that authorization will be performed against. As you know, the security principal must implement IPrincipal which includes an Identity property and an IsInRole() method. To support the claims-based approach I created an <strong>IClaimsPrincipal</strong> interface which has the following definition:</p>
<pre>public interface IClaimsPrincipal
{
  ClaimSet Claims {get;}
  ClaimSet Issuer {get;}

  bool HasRequiredClaims(ClaimSet requiredClaims);
}
</pre>
<p>As you would expect from a claims-based approach, a security principal implementing this interface provides access to the applicable claim set for authorization, the issuer of that claim set, and has a function to check that a set of required claims have been supplied. In my <strong>ClaimsPrincipal</strong> type I implement both IPrincipal and IClaimsPrincipal as shown in <strong>Listing 1</strong>.</p>
<p><strong>Listing 1: Implementation of the ClaimsPrincipal type</strong></p>
<pre>using System;
using System.Collections.Generic;
using System.Text;
using System.Security.Principal;
using System.IdentityModel.Claims;

public class ClaimsPrincipal : IClaimsPrincipal, IPrincipal
{
  private ClaimSet m_claims;
  private IIdentity m_identity;

  public ClaimsPrincipal(IIdentity identity, ClaimSet claims)
  {
    this.m_identity = identity;
    this.m_claims = claims;
  }

  ClaimSet IClaimsPrincipal.Issuer
  {
    get { return this.m_claims.Issuer; }
  }

  bool IClaimsPrincipal.HasRequiredClaims(ClaimSet requiredClaims)
  {
    bool hasClaims = true;
    bool issuerMatch = false;

    // check issuer
    foreach (Claim c in requiredClaims.Issuer)
    {
      if (this.m_claims.Issuer.ContainsClaim(c))
      {
        issuerMatch=true;
        break;
      }
    }

    // check required claims
    if (issuerMatch)
    {
      foreach (Claim c in requiredClaims)
      {
        if (!this.m_claims.ContainsClaim(c))
        {
          hasClaims = false;
          break;
        }
      }
    }

    return issuerMatch &amp;&amp; hasClaims;
  }

  ClaimSet IClaimsPrincipal.Claims
  {
    get { return this.m_claims; }
  }

  IIdentity IPrincipal.Identity
  {
    get
    {
      return this.m_identity;
    }
  }

  bool IPrincipal.IsInRole(string role)
  {
    throw new NotSupportedException(&quot;ClaimsPrincipal does not
implement role-based security checks.&quot;);
  }

}
</pre>
<p>The constructor takes an IIdentity type and a ClaimSet representative of the claims to authorize. In the implementation of IPrincipal, the Identity property returns this identity reference, but the IsInRole() function throws an exception since we&rsquo;re not expecting any role-based checks when using claims-based security. The implementation of IClaimsPrincipal returns the associated ClaimSet from the Claims property, returns the issuer&rsquo;s ClaimSet for the Issuer property, and performs a check for the correct issuer and claim set in the HasRequiredClaims() method.</p>
<h2>Attaching the ClaimsPrincipal Instance</h2>
<p>This ClaimsPrincipal type can be constructed in the custom authorization policy instead of the GenericPrincipal shown earlier. The same claim set that is being added to the EvaluationContext should also be passed to the ClaimsPrincipal when it is constructed, as shown here in this updated Evaluate() method:</p>
<pre>public bool Evaluate(EvaluationContext evaluationContext,
ref object state)
{

  if (evaluationContext.Properties.ContainsKey(&quot;Identities&quot;))
  {
    List&lt;IIdentity&gt; identities =
evaluationContext.Properties[&quot;Identities&quot;] as List&lt;IIdentity&gt;;
    IIdentity identity = identities[0];

    ClaimSet claims = MapClaims(identity);

    ClaimsPrincipal newPrincipal =
new ClaimsPrincipal(identity, claims);
    evaluationContext.Properties[&quot;Principal&quot;] = newPrincipal;

    evaluationContext.AddClaimSet(this, claims);

    return true;
  }
  else
    return false;
}
</pre>
<h2>Validating ClaimsPrincipal Claims</h2>
<p>This removes the need to traverse the AuthorizationContext for the correct issuer. Instead, you can retrieve the security principal attached to the thread, check that it implements IClaimsPrincipal, and validate that the required claims were provided:</p>
<pre>IClaimsPrincipal claimsPrincipal = Thread.CurrentPrincipal
as IClaimsPrincipal;

if (claimsPrincipal == null)
  throw new SecurityException(&quot;Access is denied. Security principal
should be a IClaimsPrincipal type.&quot;);

Claim issuerName = Claim.CreateNameClaim(
ClaimsAuthorizationPolicy.IssuerName);
List&lt;Claim&gt; issuerClaims = new List&lt;Claim&gt;();
issuerClaims.Add(issuerName);

List&lt;Claim&gt; requiredClaims = new List&lt;Claim&gt;();
requiredClaims.Add(new Claim(�http://schemas.thatindigogirl.com
/samples/2006/06/identity/claims/delete�,
�http://schemas.thatindigogirl.com/samples/2006/06/identity
/resources/customers�, Rights.PossessProperty));

DefaultClaimSet claimSet = new DefaultClaimSet(
new DefaultClaimSet(issuerClaims), requiredClaims);

<strong>if (!claimsPrincipal.HasRequiredClaims(claimSet))
  throw new SecurityException(&quot;Access is denied. Security principal
does not satisfy required claims.&quot;);</strong>
</pre>
<p>HasRequiredClaims() expects you to pass a ClaimSet that includes the required claims with the correct issuer. Clearly, this still adds bloat to your code, but it can be simplified by using the ClaimsPrincipalPermission type that I&rsquo;ll explain next.</p>
<h1>ClaimsPrincipalPermission</h1>
<p>You can perform permission demands in code to enforce role-based security using the following syntax:</p>
<pre>PrincipalPermission p = new PrincipalPermission(null,
&quot;Administrators&quot;, true);
p.Demand();
</pre>
<p>The PrincipalPermission type is passed a username, role and authentication status. When the permission demand is invoked the security principal attached to the request thread is checked against these values &ndash; in this case the user name is null, thus not checked, but the user must be in the &ldquo;Administrators&rdquo; role and be authenticated. I created a custom <strong>ClaimsPrincipalPermission</strong> to facilitate similar demands for claims.</p>
<p>Like with the PrincipalPermission type, the ClaimsPrincipalPermission implements <strong>IPermission</strong>,<strong> ISecurityEncodable </strong>and<strong> IUnrestrictedPermission</strong>. These interfaces are shown here:</p>
<pre>public interface IPermission : ISecurityEncodable
{
  void Demand();

  IPermission Copy();
  IPermission Intersect(IPermission target);
  bool IsSubsetOf(IPermission target);
  IPermission Union(IPermission target);
}

public interface ISecurityEncodable
{
  void FromXml(SecurityElement e);
  SecurityElement ToXml();
}

public interface IUnrestrictedPermission
{
  bool IsUnrestricted();
}
</pre>
<p>In the following paragraphs I will discuss the implementation of the ClaimsPrincipalPermission type, including each of these methods that are common to all IPrincipal types.</p>
<h2>Constructing ClaimPrincipalPermission</h2>
<p>The implementation of Demand() is where all the work is done to check the security principal attached to the current thread and ensure that the requirements held by the ClaimPrincipalPermission are met. That implies that the ClaimsPrincipalPermission must supply overloaded constructors to provide information for the permission demand. ClaimsPrincipalPermission issues demands based on the following properties:</p>
<ul>
<li><strong>IsAuthenticated:</strong> Since ClaimsPrincipal still carries information about the identity of the caller, you can validate that the caller has been authenticated by providing a value for this property.</li>
<li><strong>RequiredClaims:</strong> This is a ClaimSet which contains the list of required claims to be demanded, and information about the issuer of those claims.</li>
<li><strong>Issuer: </strong>This is a ClaimSet identifying the issuer of the required claims.</li>
</ul>
<p>The ClaimsPrincipalPermission constructor takes a boolean and ClaimSet to populate these properties as follows:</p>
<pre>// fields
private ClaimSet m_requiredClaims;
private bool m_isAuthenticated;

// properties
public bool IsAuthenticated
{
  get
  {
    return m_isAuthenticated;
  }
}

public ClaimSet Issuer
{
  get
  {
    return ((this.m_requiredClaims==null)?null :
this.m_requiredClaims.Issuer);
  }
}

public ClaimSet RequiredClaims
{
  get
  {
    return this.m_requiredClaims;
  }
}

// constructor
public ClaimsPrincipalPermission(bool isAuthenticated,
ClaimSet requiredClaims)
{
  this.m_isAuthenticated = isAuthenticated;
  this.m_requiredClaims=requiredClaims;
}
</pre>
<p>Once you have constructed the ClaimsPrincipalPermission type, you can use it to perform permission demands.</p>
<p>Another constructor is also supplied allowing the ClaimsPrincipalPermission to be initialized as restricted or unrestricted, according to the PermissionState enumeration.</p>
<pre>private bool m_isUnrestricted;

public ClaimsPrincipalPermission(PermissionState state)
{
  this.m_isUnrestricted = (state == PermissionState.Unrestricted);
}
</pre>
<p>This value returned by the IsUnrestricted property of the IUnrestrictedPermission interface.</p>
<h2>Demand()</h2>
<p>Permission demands use the properties of the IPermission type to check the security principal attached to the thread for specified requirements. The implementation of <strong>Demand()</strong> for ClaimsPrincipalPermission executes the following checks:</p>
<ul>
<li>It checks to see that the security principal attached to the thread is an IClaimsPrincipal type, and throws a SecurityException if it is not.</li>
<li>If the IsAuthenticated property is set to true, it checks to see that the current principal is authenticated.</li>
<li>If the RequiredClaims property is null, it does not check any further, and the demand is complete, otherwise, the requirements for issuer and claims are verified as discussed next.</li>
<li>The Issuer is checked next. When the RequiredClaims property is set, a ClaimSet is provided which includes a ClaimSet for the Issuer. The assumption here is that the developer has provided one or more identifying claims about the required Issuer. If one of these claims is matched by the Issuer of the security principal&rsquo;s claims, then we have a match.</li>
<li>Once an Issuer match is verified the list of required claims are checked. All required claims must be present in the RequiredClaims ClaimSet, or the demand fails.</li>
</ul>
<p>The code to execute these checks begins with the Demand() implementation, which then calls to a shared CheckClaims() method, which then calls to the ClaimsPrincipal&rsquo;s HasRequiredClaims() method (shown in <strong>Listing 1</strong>). The Demand() and CheckClaims() methods are shown in Listing 2.</p>
<p><strong><em>Listing 2: Demand() and CheckClaims() functions from ClaimsPrincipalPermission </em></strong></p>
<pre>public void Demand()
{
  IClaimsPrincipal p = Thread.CurrentPrincipal as IClaimsPrincipal;

  if (p == null)
    throw new SecurityException(&quot;Access is denied. Security principal
should be a IClaimSetPrincipal type.&quot;);

  this.CheckClaims(p);
}

public void CheckClaims(IClaimsPrincipal principal)
{
  IPrincipal p = principal as IPrincipal;

  if (this.m_isAuthenticated &amp;&amp; !p.Identity.IsAuthenticated)
  {
    throw new SecurityException(&quot;Access is denied. Security principal
is not authenticated.&quot;);
  }

  if (this.m_requiredClaims==null)
  {
    return;
  }

  if (!principal.HasRequiredClaims(this.m_requiredClaims))
    throw new SecurityException(&quot;Access is denied. Security principal
does not satisfy required claims.&quot;);

}
</pre>
<p>Now I will discuss other members of IPermission implemented by ClaimsPrincipalPermission &ndash; specifically Copy(), Intersect(), IsSubsetOf() and Union() &ndash; used to facilitate the generation of new permission objects or permission comparison.</p>
<h2>Copy()</h2>
<p>Copy() is the simplest IPermission function. It requires only that you clone the current permission object as shown here:</p>
<pre>public IPermission Copy()
{
  if (this.IsUnrestricted())
    return new
ClaimsPrincipalPermission(PermissionState.Unrestricted);
  else
    return new ClaimsPrincipalPermission(this.m_isAuthenticated,
this.m_requiredClaims);
}
</pre>
<p>If the permission was constructed as unrestricted, values for IsAuthenticated and RequiredClaims take on their defaults.</p>
<h2>Intersect()</h2>
<p>Intersect() returns a new permission object that represents the intersection of two permissions. In the ClaimsPrincipalPermission, this is implemented in the following manner:</p>
<ul>
<li>If the permission to intersect with is null, null is returned.</li>
<li>If the permission to intersect with is not a ClaimsPrincipalPermission type, null is returned.</li>
<li>If either the permission to intersect or this permission is unrestricted, return a copy of the opposite permission.</li>
<li>If IsAuthenticated does not match for both permissions, null is returned.</li>
<li>If ALL of the Issuer claims are not matched, null is returned. The assumption here is that a developer is providing another permission to intersect with, and they should thus describe the Issuer with the same set of claims. This simplifies how developers can use these permissions, by reducing the complexity that would follow if you attempted to intersect the ClaimSet of an Issuer, and the Issuer&rsquo;s Issuer, and that Issuer&rsquo;s Issuer, and so on. In other words, the nature of the ClaimSet and the nested Issuer claim sets demands simplicity here.</li>
<li>Once the Issuer ClaimSet is verified as a perfect match between permissions, the actual claim sets can be intersected. So long as they are issued by the same Issuer, the list of required claim sets in both permissions can be intersected to produce a new ClaimSet by the same Issuer.</li>
</ul>
<p>The resulting code is shown in Listing 3.</p>
<p><strong><em>Listing 3: Implementation of Intersect() and IsExactIssuerMatch() </em></strong></p>
<pre>public IPermission Intersect(IPermission target)
{
  if (target == null)
    return null;

  ClaimsPrincipalPermission perm = target as
ClaimsPrincipalPermission;
  if (perm == null)
    return null;

  if (this.IsUnrestricted())
    return target.Copy();

  if (perm.IsUnrestricted())
    return this.Copy();

  if (this.m_isAuthenticated != perm.IsAuthenticated)
    return null;

  if (!IsExactIssuerMatch(perm.Issuer)) return null;

  List<claim> claims = new List<claim>();
  foreach (Claim c in this.m_requiredClaims)
  {
    if (perm.RequiredClaims.ContainsClaim(c))
    {
      claims.Add(c);
    }
  }

  // it is assumed that the issuers are identical from the call
  // to IsExactIssuerMatch() above
  ClaimsPrincipalPermission newPerm = new
ClaimsPrincipalPermission(this.m_isAuthenticated, new
DefaultClaimSet(this.m_requiredClaims.Issuer, claims));
  return newPerm;

}

protected bool IsExactIssuerMatch(ClaimSet target)
{
  bool issuerMatch = true;
  foreach (Claim c in target)
  {
    if (!this.m_requiredClaims.Issuer.ContainsClaim(c))
    {
      issuerMatch = false;
      break;
    }
  }
  return issuerMatch;
}
</claim></claim></pre>
<h2>IsSubsetOf()</h2>
<p>IsSubsetOf() returns a boolean result after checking to see if the current permission is a subset of the permission passed to the method. This method does the following:</p>
<ul>
<li>Returns false if the permission passed is null.</li>
<li>Returns false if the permission passed is not a ClaimsPrincipalPermission type.</li>
<li>Returns true if the target permission is unrestricted. Returns false if this permission is unrestricted.</li>
<li>Returns false if the IsAuthenticted properties do not match.</li>
<li>Returns false if the Issuer of both permissions are not an exact match.</li>
<li>Finally, it checks to see if the required claims in this permission instance are all found in the permission passed to the method. If they are not all present, returns false, otherwise true.</li>
</ul>
<p>The resulting code is shown here:</p>
<pre>public bool IsSubsetOf(IPermission target)
{

  if (target == null)
    return false;

  ClaimsPrincipalPermission perm = target as
ClaimsPrincipalPermission;
  if (perm == null)
    return false;

  if (perm.IsUnrestricted)
    return true;

  if (this.IsUnrestricted)
    return false;

  if (this.m_isAuthenticated != perm.IsAuthenticated)
    return false;

  if (!IsExactIssuerMatch(perm.Issuer)) return false;

  bool isSubsetOf = false;
  foreach (Claim c in this.m_requiredClaims)
  {
    if (!perm.RequiredClaims.ContainsClaim(c))
    {
      isSubsetOf=false;
      break;
    }

  }

  return isSubsetOf;
}
</pre>
<h2>Union ()</h2>
<p>Union() returns a new permission type that includes all of the required claims of two permissions, assuming that they both share the same setting for IsAuthenticated and Issuer values. Similar validation on the permission passed to the method, the IsAuthenticated property and the Issuer value are executed before creating a new permission type with the entire set of claims (without duplicates). The code looks as follows:</p>
<pre>public IPermission Union(IPermission target)
{
  if (target == null)
    return null;

  ClaimsPrincipalPermission perm = target as
ClaimsPrincipalPermission;
  if (perm == null)
    return null;

  if (perm.IsUnrestricted|| this.IsUnrestricted)
    return new
ClaimsPrincipalPermission(PermissionState.Unrestricted);

  if (this.m_isAuthenticated != perm.IsAuthenticated)
    return null;

  if (!IsExactIssuerMatch(perm.Issuer)) return null;

  List&lt;Claim&gt; claims = new List&lt;Claim&gt;();
  foreach(Claim c in this.m_requiredClaims)
    claims.Add(c);

  foreach (Claim c in perm.RequiredClaims)
  {
    if (!this.m_requiredClaims.ContainsClaim(c))
    {
      claims.Add(c);
    }
  }

  // it is assumed that the issuers are identical from the call
  // to IsExactIssuerMatch() above
  ClaimsPrincipalPermission newPerm = new
ClaimsPrincipalPermission(this.m_isAuthenticated, new
DefaultClaimSet(this.m_requiredClaims.Issuer, claims));
  return newPerm;

}
</pre>
<h2>FromXml() and ToXml()</h2>
<p>IPermission inherits ISecurityEncodable as I mentioned earlier. The job of FromXml() and ToXml() are to support XML serialization and deserialization of the permission. This is not a necessary feature for this particular permission type, thus is not implemented.</p>
<h2>Claims-Based Demands</h2>
<p>With this ClaimsPrincipalPermission you can now place permission demands in code, for example in each service operation, as follows:</p>
<pre>public void DeleteCustomer(string customerId)
{

  ClaimSet issuerClaimSet = new
DefaultClaimSet(Claim.CreateNameClaim(
&quot;http://www.thatindigogirl.com/samples/2006/06/issuer&quot;));

  Claim claim = new Claim(
&quot;http://schemas.thatindigogirl.com/samples/2006/06/identity/
claims/delete&quot;, &quot;http://schemas.thatindigogirl.com/samples/2006/06/
identity/resources/customers&quot;, Rights.PossessProperty);

  ClaimSet requiredClaimSet = new
DefaultClaimSet(issuerClaimSet, claim);

  ClaimsPrincipalPermission perm = new
ClaimsPrincipalPermission(true, requiredClaimSet);

  perm.Demand();

  // code to delete customer
}
</pre>
<p>But wait &ndash; isn&rsquo;t this supposed to reduce the amount of code necessary to check claims? The problem is that it isn&rsquo;t as simple as passing a string array of roles, when we do claims-based security. Generating a ClaimSet is the only reliable way to initialize the ClaimsPrincipalPermission with the issuer and required claims for the demand. But, since claims are tightly related to the authorization policy at your service, you can, and should, provide utility functions to generate claim sets for the issuer, and for common claims.</p>
<p>If you do, you can reduce the above code to these two lines:</p>
<pre>ClaimsPrincipalPermission perm = new ClaimsPrincipalPermission(true,
ClaimsAuthorizationPolicy.CreateCustomersClaimSet(
ClaimsAuthorizationPolicy.ClaimTypes.Delete));
perm.Demand();
</pre>
<p>The CreateCustomersClaimSet() function is a static function exposed by the custom IAuthorizationPolicy type, ClaimsAuthorizationPolicy. Inside, it leverages string constants defining ClaimTypes and Resources as discussed in Part 1 of this article, to create a ClaimSet using the authorization policy issuer. It allows you to pass a parameter array of strings indicating the ClaimTypes to be included in the ClaimSet. Internal validation ensures that strings passed to the method are actually valid ClaimTypes. The core code is shown here:</p>
<pre>public static ClaimSet CreateApplicationClaimSet(
params string[] claimTypes)
{
  List&lt;Claim&gt; claims = new List&lt;Claim&gt;();
  foreach(string s in claimTypes)
  {
    if (!IsValidClaimType(s))
      throw new SecurityException(string.Format(&quot;Invalid claim type
provided: {0}&quot;, s));

    claims.Add(new Claim(s,
ClaimsAuthorizationPolicy.Resources.Application,
Rights.PossessProperty));
  }

  return new DefaultClaimSet(
ClaimsAuthorizationPolicy.CreateIssuerClaimSet(), claims);
}

public static ClaimSet CreateIssuerClaimSet()
{
  return new DefaultClaimSet(Claim.CreateNameClaim(
ClaimsAuthorizationPolicy.IssuerName));
}
</pre>
<p><em>NOTE: You can look at the code sample for this article for a similar example with a complete listing of constants and helper methods for the authorization policy. </em></p>
<h1>ClaimsPrincipalPermissionAttribute</h1>
<p>As I mentioned earlier, you can also perform permission demands declaratively using the <strong>PrincipalPermissionAttribute</strong> as follows:</p>
<pre>[PrincipalPermission(SecurityAction.Demand,
Role=&quot;BUILTIN\\Administrators&quot;)]
[PrincipalPermission(SecurityAction.Demand,
Role=&quot;Administrators&quot;)]
public string AdminOperation()
{
  // protected code
}
</pre>
<p>Like the PrincipalPermission, the PrincipalPermissionAttribute type can be initialized with a username, role and authentication status. You also indicate you are executing a demand with the first parameter, SecurityAction.Demand. To execute the demand, the runtime asks the attribute to create an instance of the associated permission, PrincipalPermission, and its Demand() function is executed to enforce this before the operation can be invoked.</p>
<p>To provide a similar experience for claims-based demands, I have created a ClaimsPrincipalPermissionAttribute which I&rsquo;ll describe in the next sections.</p>
<h2>Implementing CodeAccessSecurityAttribute</h2>
<p>As with the PrincipalPermissionAttribute type, the ClaimsPrincipalPermissionAttribute inherits <strong>CodeAccessSecurityAttribute</strong>, which in turn inherits <strong>SecurityAttribute</strong>. The base type, SecurityAttribute, supplies these key members:</p>
<ul>
<li><strong>Action:</strong> This property indicates the SecurityAction to execute, which in this context is SecurityAction.Demand.</li>
<li><strong>Unrestricted:</strong> If this property is true it indicates that the caller should be granted full access to the resource protected by the associated permission, if false, no access is granted.</li>
<li><strong>CreatePermission():</strong> Invoked by the runtime to construct the permission type associated with the CodeAccessSecurityAttribute, in order to execute the permission demand.</li>
</ul>
<p>The idea is to provide appropriate public properties on this custom attribute to so that the associated permission type can be constructed with values that can be used for permission demands. The base type for the attribute, CodeAccessSecurityAttribute, provides a constructor that takes the PermissionState enumeration setting the restricted state of the attribute, if applicable. The implementation of ClaimsPrincipalPermissionAttribute also exposes two other properties: Authenticated and RequiredClaimType.</p>
<p>The <strong>Authenticated </strong>property merely indicates if the security principal attached to the thread must be authenticated, just like the ClaimsPrincipalPermission. <strong>RequiredClaimType</strong> is a string property that indicates the claim type represented by the attribute. Ultimately this will be used to construct a ClaimSet to be passed to the ClaimsPrincipalPermission for permission demands. In this implementation I am assuming that the caller will pass a valid claim type from the ClaimsAuthorizationPolicy.ClaimTypes static class, discussed in Part 1. <strong>Resource</strong> is also a string property indicating the resource associated with the claim. This should be based on the ClaimsAuthorizationPolicy.Resources static class, also discussed in Part 1. Based on these supported resources and claim types I am inferring the issuer when the claim set is created during CreatePermission().</p>
<p><strong>Listing 4</strong> shows the full implementation.</p>
<p><strong><em>Listing 4: Implementation of ClaimsPrincipalPermissionAttribute </em></strong></p>
<pre>using System;
using System.Security.Permissions;
using System.IdentityModel.Claims;

[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, AllowMultiple = true, Inherited = false)]
public class ClaimsPrincipalPermissionAttribute :
CodeAccessSecurityAttribute
{

  private bool m_isAuthenticated;
  private string m_requiredClaimType;
  private string m_resource;

  public ClaimsPrincipalPermissionAttribute(SecurityAction action)
: base(action)
  {
    this.m_isAuthenticated = true;
  }

  public string RequiredClaimType
  {
    get
    {
      return this.m_requiredClaimType;

    }
    set
    {
      this.m_requiredClaimType = value;
    }
  }

  public string Resource
  {
    get
    {
      return this.m_resource;
    }
    set
    {
      this.m_resource = value;
    }
  }

  public bool Authenticated
  {
    get
    {
      return m_isAuthenticated;
    }
    set
    {
      m_isAuthenticated = value;
    }
  }

  public override System.Security.IPermission CreatePermission()
  {
    if (this.Unrestricted)
      return new
ClaimsPrincipalPermission(PermissionState.Unrestricted);

  ClaimSet cs = ClaimsAuthorizationPolicy.CreateClaimSet
(this.m_resource, this.m_requiredClaimType);
  return new ClaimsPrincipalPermission(this.m_isAuthenticated, cs);

  }
}
</pre>
<h2>Attribute Usage</h2>
<p>All attributes have an <strong>AttributeUsageAttribute</strong> applied to their type definition to indicate allowed use of the attribute. In the case of the ClaimsPrincipalPermissionAttribute, the following AttributeUsageAttribute is applied (also shown in <strong>Listing 4</strong>):</p>
<pre>[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, AllowMultiple = true, Inherited = false)]
public class ClaimsPrincipalPermissionAttribute : CodeAccessSecurityAttribute
</pre>
<p>In this case, the attribute is restricted to methods on a class, and cannot be inherited if there is a base type. So that you can stack many ClaimsPrincipalPermissionAttribute on a single method, AllowMultiple is set to true.</p>
<h2>Declarative Claims-Based Demands</h2>
<p>The purpose of providing the ClaimsPrincipalPermissionAttribute is to support declarative permission demands for each service operation instead of constructing the ClaimsPrincipalPermission directly. The following illustrates issuing a permission demand for the right to delete customers:</p>
<pre><strong>[ClaimsPrincipalPermissionAttribute(SecurityAction.Demand,
RequiredClaimType = ClaimsAuthorizationPolicy.ClaimTypes.Delete, Resource=ClaimsAuthorizationPolicy.Resources.Customers)]</strong>
public void DeleteCustomer(string customerId)
{
  // protected code
}
</pre>
<p>The verbosity of the attribute declaration results from the nature of claims-based security &ndash; it isn&rsquo;t as simple as just passing a list of roles or user names to the attribute or permission. I have already simplified it by inferring the issuer, assuming it is associated with the type of claims and resources supported by the authorization policy. But, you can take it one level further by defining custom attributes that derive from this more general attribute. For example, I could create an attribute specifically for Create, Read, Update and Delete rights for Customers. Consider the following <strong>DeleteCustomersClaimAttribute</strong>:</p>
<pre>[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class,
AllowMultiple = true, Inherited = false)]
public class DeleteCustomersClaimAttribute:
ClaimsPrincipalPermissionAttribute
{

  public DeleteCustomersClaimAttribute(SecurityAction action)
: base(action)
  {
    this.Authenticated=true;
    this.RequiredClaimType =
ClaimsAuthorizationPolicy.ClaimTypes.Delete;
    this.Resource=ClaimsAuthorizationPolicy.Resources.Customers;
  }
}
</pre>
<p>When applied to a service operation, it greatly simplifies the declaration:</p>
<pre>[DeleteCustomersClaim(SecurityAction.Demand)]
public void DeleteCustomer(string customerId)
{
  // protected code
}
</pre>
<p>So, when you design your claims-based permission model, you can come up with a collection of simplified attributes for developers to work with, while encapsulating the richness of the claims-based authorization within.</p>
<h1>Pros and Cons of Claims-Based Security Permissions</h1>
<p>The nice thing about using this claims-based security model is that developers can focus on demanding specific claims before operations can be executed, but they don&rsquo;t need to know what form of authentication was used to grant those claims, so long as they trust the issuer. Since the model is familiar, the task is simplified. Furthermore, since the ClaimsPrincipalPermission also holds the ClaimSet granted by the trusted issuer, permission demands can also be placed in downstream assemblies used by the service, if applicable. This may be necessary when business rules require knowledge of the authenticated caller, or their granted rights.</p>
<p>One downside of this approach is that the authorization policy must supply a complete set of claims for the authorized caller, so that operations can demand the claims they require. If there is a long list of claims that apply to features, actions and other information supplied about the caller, the ClaimSet can become quite large. A refinement of this model would be to modify the functionality of the authorization policy to grant a claim set that merely identifies the caller, without assigning all possible claims. Then, modify the attribute to gather the claims for a specific service and/or operation, on demand. Of course this can add overhead to each operation call, but can reduce the size of the claim set stored by the security context that may also need to be serialized and forward to downstream services.</p>
<h1>Security Token Services, SAML Tokens and Claims</h1>
<p>So far I have focused on how you can build a custom authorization policy to map any type of credential to a normalized set of claims &ndash; enabling service developers to authorize calls based on those claims regardless of the way calls are authenticated. Assuming that a trusted set of claims has been added to the security context, the claims-based authorization model I have described can be applied to your service operations, programmatically or declaratively with ClaimsPrincipalPermission and ClaimsPrincipalPermissionAttribute, respectively. What these constructs rely on is that a ClaimsPrincipal has been attached to the thread carrying the claim set that should be used for authorization. <strong>Figure 1 </strong>illustrates how the custom authorization policy attaches a set of claims and a custom security principal to the security context for each call to a business service.</p>
<p><strong><em>Figure 1: This custom authorization policy maps a UserName credential to a set of normalized claims. </em></strong></p>
<p><img height="468" src="http://www.theserverside.net/tt/articles/content/ClaimsBasedSecurityModel2/clip_image002.jpg" width="624" /></p>
<p>Using a custom authorization policy to map credentials to normalized claims is a great way to start moving to a claims-based security model, without introducing the concepts of federation and SAML tokens. So long as your services authorize calls based on claims attached to the security context or ClaimsPrincipal you can introduce federation without modifications to service code. In this section I&rsquo;ll explain how federated security and SAML tokens can be introduced while still utilizing the claims-based security model I&rsquo;ve described.</p>
<h2>Token Issuance</h2>
<p>Figure 1 illustrates a scenario where the business service is responsible for configuring a custom authorization policy to normalize claims. Fortunately the authorization policy decouples authentication of the UserName token (or, other tokens if supported) from the authorization against normalized claims. The requirement is only that the AuthorizationContext contains an appropriate claim set from the desired issuer, and that a ClaimsPrincipal is attached to the thread also referencing that claim set.</p>
<p>You can use WSFederationHttpBinding to delegate authentication to a Security Token Service (STS) that will issue a SAML token containing the same normalized claims. Using this binding the client will authenticate to the STS, retrieve the SAML token with normalized claims, and then authenticate to the business service with that token. The resulting claim set is automatically attached to the security context for authorization purposes, as I will discuss shortly. Figure 2 illustrates the flow of token issuance.</p>
<p><strong><em>Figure 2: With WSFederationHttpBinding clients authenticate first to the STS, and then present issued tokens (such as SAML) to services.</em></strong></p>
<p><img height="468" src="http://www.theserverside.net/tt/articles/content/ClaimsBasedSecurityModel2/clip_image002_0000.jpg" width="624" /></p>
<h2>WSFederationHttpBinding</h2>
<p>You can configure your services to require a SAML token issued by a particular STS using <strong>WSFederationHttpBinding</strong>. This binding requires you to provide the following information:</p>
<ul>
<li><strong>IssuedTokenType:</strong> The type of token you require the STS to issue. In this case it is a SAML v1.1 token.</li>
<li><strong>ClaimTypeRequirements:</strong> A list of required or optional claim types that should be included in the issued token. In the case of the SAML token these will be supplied as SAML attributes. The service model will be able to automatically unpack those attributes into a claim set.</li>
<li><strong>Issuer Address:</strong> The Uri where the WS-Trust endpoint implemented by the STS can be located.</li>
<li><strong>Issuer Binding:</strong> The binding requirements of the issuer, so that the client can supply the correct binding with credentials to authenticate to the STS.</li>
<li><strong>Issuer Identity:</strong> In this case a certificate reference is used to identify the STS.</li>
</ul>
<p>The resulting WSFederationHttpBinding section is shown in <strong>Listing 5</strong>.</p>
<p><strong><em>Listing 5: WSFederationHttpBinding configuration. </em></strong></p>
<pre>&lt;wsFederationHttpBinding&gt;
  &lt;binding name=&quot;wsFed&quot; &gt;
    &lt;security mode=&quot;Message&quot;&gt;
      &lt;message issuedTokenType=&quot;http://docs.oasis-open.org/wss/oasis-
wss-saml-token-profile-1.1#SAMLV1.1&quot;
negotiateServiceCredential=&quot;false&quot;&gt;

         &lt;claimTypeRequirements&gt;
          &lt;add
claimType=&quot;http://schemas.thatindigogirl.com/samples/2006/06/identity/
claims/create&quot; isOptional=&quot;true&quot;/&gt;

          &lt;add
claimType=&quot;http://schemas.thatindigogirl.com/samples/2006/06/identity/
claims/read&quot; isOptional=&quot;false&quot; /&gt;
          &lt;add
claimType=&quot;http://schemas.thatindigogirl.com/samples/2006/06/identity/
claims/update&quot; isOptional=&quot;true&quot;/&gt;
          &lt;add
claimType=&quot;http://schemas.thatindigogirl.com/samples/2006/06/identity/
claims/delete&quot; isOptional=&quot;true&quot;/&gt;
        &lt;/claimTypeRequirements&gt;

        &lt;issuer address=&quot;http://localhost:51213/TokenIssuer/Service.svc&quot;
binding =&quot;wsHttpBinding&quot;  bindingConfiguration=&quot;stsBinding&quot; &gt;
          &lt;identity&gt;
	      &lt;certificateReference findValue=&quot;IPKey&quot;
x509FindType=&quot;FindBySubjectName&quot; storeLocation=&quot;LocalMachine&quot;
storeName=&quot;TrustedPeople&quot; /&gt;
          &lt;/identity&gt;
        &lt;/issuer&gt;

      &lt;/message&gt;
    &lt;/security&gt;
  &lt;/binding&gt;
&lt;/wsFederationHttpBinding&gt;
</pre>
<p>Clients use a similar configuration to initialize a proxy to invoke the service, thus the proxy has enough information to automatically make calls to the STS passing the UserName credential to authenticate. The goal of this process is that the SAML token returned by the STS will contain the normalized claims that were previously issued by the ClaimsAuthorizationPolicy discussed earlier.</p>
<h2>Normalizing Claims at the STS</h2>
<p>When you delegate authentication to an STS, this implies that the STS knows how to generate the required claims to authorize access at your business services. An STS can be any service that implements the WS-Trust contract as described by OASIS (see resources). Normally, you will not consider implementing your own WS-Trust endpoint. Instead, you might use a pre-existing STS such as the next generation Active Directory Federation Services (ADFS) or Ping Trust. To illustrate a simple example of an STS, I have provided a custom STS in the code sample that will issue a SAML token with the normalized claims already discussed.</p>
<p>This custom STS consists of a WCF service that authenticates callers with UserName token, and maps those tokens to normalized claims. In fact the configuration of this custom STS service can use the same custom authorization policy to generate a claim set for the UserName. As Figure 3 illustrates, the authorization policy provides a claim set to the security context. This claim set is then used by the STS to generate a SAML token with the appropriate claims.</p>
<p><strong><em>Figure 3: The custom STS provided in the sample code uses the same custom authorization policy to map UserName to normalized claims. </em></strong></p>
<p><img height="468" src="http://www.theserverside.net/tt/articles/content/ClaimsBasedSecurityModel2/clip_image002_0001.jpg" width="624" /></p>
<p>From a high level, the SAML token includes a private key signature indicating issuer, which in this case is a private key using the DNS &ldquo;IPKey&rdquo;. The token also includes a collection of SAML attributes which each evaluate to the assigned normalized claims. Listing 6 illustrates the main piece of code where the SAML token is actually generated, with the generation of the attribute list and token generation shown bold. The call to GetClaimSet() checks the authorization context for claims added by the custom authorization policy discussed earlier, returning that set of claims.</p>
<p><strong><em>Listing 6: Generating a SAML token from normalized claims. </em></strong></p>
<pre>private SecurityToken CreateSAMLToken(DateTime validFrom,
DateTime validTo, SecurityKey signingKey,
SecurityKeyIdentifier signingKeyIdentifier,
SecurityKeyIdentifier proofKeyIdentifier,
IList&lt;ClaimTypeRequirement&gt; claimReqs )
{
  List&lt;string&gt; confirmations = new List&lt;string&gt;();
  confirmations.Add(SamlConstants.HolderOfKey);

  SamlSubject subject = new SamlSubject(null, null, m_issuer,
confirmations, null, proofKeyIdentifier);

  List&lt;SamlAttribute&gt; attributes = new List&lt;SamlAttribute&gt;();
  ClaimSet cs = GetClaimSet(claimReqs);

  foreach (Claim c in cs)
    attributes.Add(new SamlAttribute(c));

  List&lt;SamlStatement&gt; statements = new List&lt;SamlStatement&gt;();
  statements.Add(new SamlAttributeStatement(subject, attributes));

  SamlConditions conditions = new SamlConditions(validFrom, validTo);

  SamlAssertion assertion = new SamlAssertion(&quot;_&quot; + Guid.NewGuid().ToString(), m_issuer, validFrom, conditions, null, statements);

  string signatureAlgorithm = GetSignatureAlgorithm(signingKey);
  assertion.SigningCredentials = new SigningCredentials(signingKey,
signatureAlgorithm, SecurityAlgorithms.Sha1Digest,
signingKeyIdentifier);

  SamlSecurityToken token = new SamlSecurityToken(assertion);
  return token;
}
</pre>
<p>Without getting caught up in the details of the SAML token, or the STS, the point here is that any STS can be configured to issue SAML tokens that include attributes representative of a set of normalized claims your services depend on. You don&rsquo;t have to write your own STS to do it. With this arrangement you can delegate authentication of callers so that they can pass any supported credential to the STS, and allow a trusted STS to determine the claims to be granted. <strong>Figure 4 </strong>illustrates an STS that is capable of authenticating Windows, UserName, Certificate, SAML (from a different source), or a token from CardSpace (self-issued, perhaps).</p>
<p><strong><em>Figure 4: An STS can authenticate any type of credential and map that to normalized claims encapsulated by a SAML token. </em></strong></p>
<p><img height="468" src="http://www.theserverside.net/tt/articles/content/ClaimsBasedSecurityModel2/clip_image002_0002.jpg" width="624" /></p>
<p>By signing the token with the STS&rsquo; private key the claims passed inside the SAML token are guaranteed to have come from a trusted source &ndash; assuming that the business service &ldquo;trusts&rdquo; that signature, which I&rsquo;ll discuss next.</p>
<h2>Generating Claims from SAML Tokens</h2>
<p>When a service is configured to require a SAML token (in this case using WSFederationHttpBinding) the token is authenticated at the service before its attributes are extracted &ndash; a ClaimSet constructed from them. When a SAML token is supplied in the security headers for a message, the <strong>SamlSecurityTokenAuthenticator</strong> type validates the signature of the token. By default, it is expected that the token is signed by a trusted RSA issuer, and this information is supplied by a service behavior as shown in the &lt;issuedTokenAuthentication&gt; section of <strong>Listing 7</strong>.</p>
<p><strong><em>Listing 7: Service behavior configuration to supply a custom authorization policy and indicate trusted RSA issuers. </em></strong></p>
<pre>&lt;serviceBehaviors&gt;
  &lt;behavior name=&quot;serviceBehavior&quot;&gt;
    &lt;serviceAuthorization principalPermissionMode=&quot;Custom&quot; &gt;
      &lt;authorizationPolicies&gt;
        &lt;add policyType=
&quot;ClaimsBasedSecurityComponents.SAMLClaimsAuthorizationPolicy,
ClaimsBasedSecurityComponents&quot;/&gt;
      &lt;/authorizationPolicies&gt;
    &lt;/serviceAuthorization&gt;
    &lt;serviceCredentials&gt;
      &lt;issuedTokenAuthentication allowUntrustedRsaIssuers=&quot;false&quot;&gt;
	  &lt;knownCertificates&gt;
	      &lt;add findValue=&quot;IPKey&quot; storeLocation =&quot;LocalMachine&quot;
storeName=&quot;TrustedPeople&quot; x509FindType =&quot;FindBySubjectName&quot;/&gt;
        &lt;/knownCertificates&gt;
      &lt;/issuedTokenAuthentication&gt;
      &lt;serviceCertificate findValue=&quot;RPKey&quot;
storeLocation=&quot;LocalMachine&quot; storeName=&quot;My&quot;
x509FindType=&quot;FindBySubjectName&quot;/&gt;
    &lt;/serviceCredentials&gt;
  &lt;/behavior&gt;
&lt;/serviceBehaviors&gt;
</pre>
<p>In this case, the STS signed the SAML token with its private key, IPKey. Since this key is trusted the SAML token attributes are extracted and placed in the AuthorizationContext in the form of a ClaimSet, as illustrated by <strong>Figure 5</strong>.</p>
<p><strong><em>Figure 5: Trusted SAML tokens are converted to claim sets for the authorization context. </em></strong></p>
<p><img height="468" src="http://www.theserverside.net/tt/articles/content/ClaimsBasedSecurityModel2/clip_image002_0003.jpg" width="624" /></p>
<p>Since the ClaimsPrincipalPermission and ClaimsPrincipalPermissionAttribute discussed in this article depend on the security principal attached to the thread to be a ClaimsPrincipal, a custom authorization policy (also shown configured in <strong>Listing 6</strong>) is still necessary to create the custom principal and associate the correct claim set. To handle this I provided a <strong>SAMLClaimsAuthorizationPolicy</strong>, which inherits ClaimsAuthorizationPolicy and overrides Evaluate() as follows:</p>
<pre>public override bool Evaluate(EvaluationContext evaluationContext, ref
object state)
{
  ClaimSet principalClaimSet = null;

  foreach (ClaimSet cs in evaluationContext.ClaimSets)
  {
    if (cs.Issuer.ContainsClaim(Claim.CreateDnsClaim(&quot;IPKey&quot;)))
    {
      principalClaimSet = cs;
    }
  }

  if (principalClaimSet != null)
  {
    ClaimsPrincipal newPrincipal = new ClaimsPrincipal(new
GenericIdentity(&quot;IPKey&quot;), principalClaimSet);
    evaluationContext.Properties[&quot;Principal&quot;] = newPrincipal;
    return true;
  }
  else
    return false;
}
</pre>
<p>When this authorization policy is invoked the SAML token has already been validated, its claims attached to the EvaluationContext. The issuer of the claim set we want is IPKey, in this case. Thus, the claims issued by IPKey, the STS, are attached to the ClaimsPrincipal instance. <strong>Figure 6</strong> illustrates this addition.</p>
<p><strong><em>Figure 6: A custom authorization policy that attaches claims received through a SAML token to a ClaimsPrincipal.</em></strong></p>
<p><img height="468" src="http://www.theserverside.net/tt/articles/content/ClaimsBasedSecurityModel2/clip_image002_0004.jpg" width="624" /></p>
<p>At this point, the SAML token has carried the normalized claims to the business service, and the business service has constructed a custom ClaimsPrincipal to associate the claim set to the security principal to support the claims-based authorization model I described earlier.</p>
<h2>Adjustments to the Claims-Based Authorization Model</h2>
<p>A few adjustments must be made to the model I have described thus far, to support the claim set extracted from the SAML token. If you recall, the original ClaimsAuthorizationPolicy constructs a normalized claim set using a name claim as the Issuer, where the name is &ldquo;<em>http://www.thatindigogirl.com/samples/2006/06/issuer&rdquo;. </em>When claims are extracted from a SAML token, the Issuer is described by an X509ClaimSet, in this case IPKey. That means there is a Name claim and DNS claim of &ldquo;IPKey&rdquo;, and the original issuer name is nowhere to be found.</p>
<p>To support claim sets issued by the ClaimsAuthorizationPolicy, or via SAML token, I added additional claims to the Issuer claim set that include the following information:</p>
<pre>public const string IssuerUri =
&quot;http://www.thatindigogirl.com/samples/2006/06/issuer&quot;;

public const string IssuerName = &quot;IPKey&quot;;

The helper function used to generate the Issuer claim set now generates a Uri, Name and DNS claim as shown here:
public static ClaimSet CreateIssuerClaimSet()
{
  return new DefaultClaimSet(Claim.CreateUriClaim(new
Uri(ClaimsAuthorizationPolicy.IssuerUri)),
Claim.CreateDnsClaim(ClaimsAuthorizationPolicy.IssuerName),
Claim.CreateNameClaim(ClaimsAuthorizationPolicy.IssuerName));
}
</pre>
<p>By making this change, the ClaimsPrincipalPermission is able to validate the issuer since only one of the claims must match.</p>
<h1>Summary</h1>
<p>In both parts of this article I have explained my approach to building a custom claims-based security model for your WCF services. Obviously to achieve this model it is necessary to establish a set of well-defined claims associated with service operations and application features. The idea being that those claims would should be required to access operations. For example, claims can be representative of features and actions users may take in the application, or claims can carry information about the caller that is useful to determine their rights. You should define a set of claims relevant to the application, so that operations can require claims to access certain features, and as new features are added to the application, new claims can be introduced.</p>
<h1>Resources</h1>
<p>Code for this article: <a href="http://www.dasblonde.net/downloads/tssclaimsbasedpart2.zip">http://www.dasblonde.net/downloads/tssclaimsbasedpart2.zip</a></p>
<p><strong>Michele Leroux Bustamante</strong></p>
]]></content:encoded>
			<wfw:commentRss>http://www.allfreetech.com/microsoft-net/building-a-claims-based-security-model-in-wcf-part-2-71.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Building a Claims-Based Security Model in WCF &#8211; Part 1</title>
		<link>http://www.allfreetech.com/microsoft-net/building-a-claims-based-security-model-in-wcf-part-1-68.html</link>
		<comments>http://www.allfreetech.com/microsoft-net/building-a-claims-based-security-model-in-wcf-part-1-68.html#comments</comments>
		<pubDate>Wed, 23 Dec 2009 03:53:11 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Microsoft .Net]]></category>
		<category><![CDATA[wcf]]></category>

		<guid isPermaLink="false">http://www.allfreetech.com/?p=68</guid>
		<description><![CDATA[Traditional security models for intranet and Internet applications use some form of username and password to authenticate users. Client-server applications deployed to a common domain often rely on Windows credentials (NTLM or Kerberos), while services exposed to the Internet often require a username and password to be passed in an interoperable format (WS-Security) to be [...]]]></description>
			<content:encoded><![CDATA[<p>Traditional security models for intranet and Internet applications use some form of username and password to authenticate users. Client-server applications deployed to a common domain often rely on Windows credentials (NTLM or Kerberos), while services exposed to the Internet often require a username and password to be passed in an interoperable format (WS-Security) to be authenticated against a custom credential store. These scenarios are frequently accompanied by role-based security checks that authorize access to functionality. Although popular, role-based security is often too coarse an approach since custom roles are often necessary to represent different combinations of permissions or rights. Thus, applications are usually better off authorizing calls based on permissions granted, using roles to gather the appropriate permission set. This type of permission-based security model will provide a more fine-grained result over role-based security &ndash; the downside is that .NET doesn&rsquo;t inherently support it so it requires more work to implement.</p>
<p>WCF introduces a claims-based approach to security at service boundaries, improving on role-based and permission-based security models. Claims can represent many different types of information including identity, roles, permissions or rights and even general information about the caller that may be useful to the application. A set of claims is also vouched for by an issuer such as a security token service, adding credibility to the information described by each claim &ndash; something not present in role-based or permission-based models. An additional benefit of using a claims-based security model is that it supports federated and single sign-on scenarios.</p>
<p>This two-part article will explain how claims-based security is supported by WCF, and show you how to implement a claims-based security model for your services. In this first article I&rsquo;ll start by providing a quick review of the traditional role-based model most .NET applications rely on, and then I&rsquo;ll compare this model to the claims-based model supported by WCF. In the process, I&rsquo;ll explain how different security tokens are converted into claims, how the security context for each request is initialized with those claims, and how you can interact with claims to authorize calls. I&rsquo;ll also explain how to define custom claims for an application, how to normalize different credentials into that set of claims using a custom authorization policy, and how to handle authorization centrally or at each service operation. In the second article I&rsquo;ll show you how to refine this claims-based authorization model working with custom security principals and claims-based permission demands. I&rsquo;ll then explain how you can decouple authentication using security token services or CardSpace, and how to work with SAML tokens that carry normalized claims.</p>
<h2>WCF and Role-Based Security</h2>
<p>Any application can leverage built-in role-based security features of .NET including Windows client applications, ASP.NET web applications, ASP.NET web services built with ASMX and WCF services. In all cases, when users are authenticated a security principal is attached to the executing thread. This security principal holds the caller&rsquo;s identity, which may be tied to a Windows account or a custom credential, and its roles. Security principals are the heart of role-based security &ndash; used to perform authorization checks in code. This section will review how this works and how WCF services work with this role-based security model.</p>
<p><strong>Security Principals and Identities</strong></p>
<p>To review, a security principal is a type that implements the <strong>IPrincipal</strong> interface which includes the following members:</p>
<pre>public interface IPrincipal
{
      bool IsInRole(string role);
      IIdentity Identity { get; }
}
</pre>
<p>Implementations of this interface should return true from the <strong>IsInRole()</strong> method if the associated user belongs to the specified role. The user is identified by the <strong>Identity</strong> property which is a type that implements the <strong>IIdentity</strong> interface shown here:</p>
<pre>public interface IIdentity
{
      string AuthenticationType { get; }
      bool IsAuthenticated { get; }
      string Name { get; }
}
</pre>
<p>Essentially the IIdentity implementation should hold the authenticated user&rsquo;s name and the authentication type.</p>
<p>These interfaces enable standardized access to authenticated users and associated roles. When users are authenticated, an IIdentity type is created based on the type of credential provided. Built-in types for various .NET applications include WindowsIdentity, FormsIdentity, PassportIdentity, X509Identity and GenericIdentity. Based on the authorization policy for the application, the security principal can be a WindowsPrincipal, GenericPrincipal or RoleProviderPrincipal &ndash; the latter of which is new to WCF.</p>
<p><strong>Security Principals and WCF</strong></p>
<p>When a service operation is invoked, the request thread will have a security principal attached. The type of IIdentity associated with that principal is based on the credential type received at the service. The type of IPrincipal is based on the authorization mode for the service. Let&rsquo;s walk through two common examples, for Windows and UserName credential types.</p>
<p>Consider this service configuration with a WSHttpBinding endpoint that requires a Windows credential passed via message security mode:</p>
<pre>&lt;system.serviceModel&gt;
  &lt;services&gt;
    &lt;service name=&quot;RoleBasedServices.SecureServiceInternal&quot; &gt;
      &lt;endpoint contract=&quot;RoleBasedServices.ISecureService&quot;
binding=&quot;wsHttpBinding&quot; bindingConfiguration=&quot;wsHttpWindows&quot; /&gt;
    &lt;/service&gt;
  &lt;/services&gt;
  &lt;bindings&gt;
    &lt;wsHttpBinding&gt;
      &lt;binding name=&quot;wsHttpWindows&quot;&gt;
        &lt;security mode=&quot;Message&quot;&gt;
          &lt;message clientCredentialType=&quot;Windows&quot; /&gt;
        &lt;/security&gt;
      &lt;/binding&gt;
    &lt;/wsHttpBinding&gt;
  &lt;/bindings&gt;
&lt;/system.serviceModel&gt;
</pre>
<p>When the Windows credential is passed by the client, it is serialized to a security token in the message. By default that token is authenticated and authorized against the Windows domain using NTLM or Kerberos (depending on your set up). For Windows credentials, the only authentication option is the Windows domain. By default, authorization relies on the Windows domain as well, per the <strong>PrincipalPermissionMode</strong> setting. The following illustrates a service behavior configuration showing the default settings for Windows authentication and authorization:</p>
<pre>&lt;behavior name=&quot;internalServiceBehavior&quot;&gt;
  &lt;serviceAuthorization
principalPermissionMode=&quot;UseWindowsGroups&quot; /&gt;
  &lt;serviceCredentials&gt;
    &lt;windowsAuthentication includeWindowsGroups=&quot;true&quot;
allowAnonymousLogons=&quot;false&quot; /&gt;
  &lt;/serviceCredentials&gt;
&lt;/behavior&gt;
</pre>
<p>With this configuration, the resulting security principal attached to the thread is a WindowsPrincipal with a WindowsIdentity reference.</p>
<p>In the case of UserName credentials, if the client passes a username and password that should be authenticated against a custom credential store, and not the Windows domain, you must explicitly configure the authentication and authorization modes. By default, UserName credentials are authenticated against the Windows domain, unless you provide an alternate <strong>UserNamePasswordValidationMode</strong>. Likewise, the default authorization mode uses the Windows domain unless you provide an alternate PrincipalPermissionMode. The following configuration illustrates a service that requires UserName credentials, and authenticates and authorizes against the configured ASP.NET membership and roles provider:</p>
<pre>&lt;system.serviceModel&gt;
  &lt;services&gt;
    &lt;service name=&quot;RoleBasedServices.SecureServiceExternal&quot;
behaviorConfiguration=&quot;externalServiceBehavior&quot;&gt;
      &lt;endpoint contract=&quot;RoleBasedServices.ISecureService&quot;
binding=&quot;wsHttpBinding&quot; bindingConfiguration=&quot;wsHttpUsername&quot; /&gt;
    &lt;/service&gt;
  &lt;/services&gt;
  &lt;bindings&gt;
    &lt;wsHttpBinding&gt;
      &lt;binding name=&quot;wsHttpUsername&quot;&gt;
        &lt;security mode=&quot;Message&quot;&gt;
          &lt;message clientCredentialType=&quot;UserName&quot;
negotiateServiceCredential=&quot;false&quot;
establishSecurityContext=&quot;false&quot; /&gt;
        &lt;/security&gt;
      &lt;/binding&gt;
    &lt;/wsHttpBinding&gt;
  &lt;/bindings&gt;
  &lt;behaviors&gt;
    &lt;serviceBehaviors&gt;
      &lt;behavior name=&quot;externalServiceBehavior&quot;&gt;
        &lt;serviceAuthorization principalPermissionMode=&quot;UseAspNetRoles&quot; /&gt;
        &lt;serviceCredentials&gt;
          &lt;userNameAuthentication
userNamePasswordValidationMode=&quot;MembershipProvider&quot; /&gt;
          &lt;serviceCertificate findValue=&quot;RPKey&quot;
x509FindType=&quot;FindBySubjectName&quot; storeLocation=&quot;LocalMachine&quot;
storeName=&quot;My&quot;/&gt;
        &lt;/serviceCredentials&gt;
      &lt;/behavior&gt;
    &lt;/serviceBehaviors&gt;
  &lt;/behaviors&gt;
&lt;/system.serviceModel&gt;
</pre>
<p>To authenticate using the ASP.NET membership provider, you set the authentication mode to <strong>MembershipProvider</strong> instead of Windows (the default). To authorize using the ASP.NET roles provider, you set the authorization mode to <strong>UseAspNetRoles</strong> instead of UseWindowsGroups (the default). Unless you configure an alternate ASP.NET membership and roles provider, this means the default ASP.NET membership and roles provider &ndash; but you can create a custom provider to go against your own credential store if desired.</p>
<p>In this case a <strong>RoleProviderPrincipal</strong> is attached to the thread instead of a WindowsPrincipal. It references a GenericIdentity type carrying the username.</p>
<p>For both Windows and UserName credentials, the security principal attached to the thread supports role-based security since they respectively have access to the Windows or custom roles for the user. I&rsquo;ll review how permission demands interact with the security principal shortly.</p>
<p><strong>ServiceSecurityContext</strong></p>
<p>In the case of WCF services, you can access information about the user through two means: the security principal attached to the thread, and the service security context. Put another way, the service model populates both the <strong>CurrentPrincipal</strong> property of the thread and the <strong>ServiceSecurityContext</strong> when it processes security tokens. For traditional role-based security, the CurrentPrincipal property is used to gain access to the security principal and the user identity:</p>
<pre>IPrincipal principal = Thread.CurrentPrincipal;
IIdentity identity = Thread.CurrentPrincipal.Identity;
</pre>
<p>You can also access the user identity through the ServiceSecurityContext. This type also provides run-time access to other relevant information about the security context for a service operation &#8211; specifically, it provides access to identities, claims, and authorization policies as follows:</p>
<ul>
<li><strong>PrimaryIdentity:</strong> Contains a reference to the IIdentity type representing the authenticated caller.</li>
<li><strong>WindowsIdentity:</strong> Contains a reference to the same IIdentity as the PrimaryIdentity property if it is a WindowsIdentity type.</li>
<li><strong>AuthorizationContext:</strong> Contains information about the security token(s) passed in the message. This information is useful for performing claims-based authorization which I&rsquo;ll discuss shortly.</li>
<li><strong>AuthorizationPolicies:</strong> Contains information about the authorization policies used to grant claims, also to be discussed.</li>
</ul>
<p>You can access the ServiceSecurityContext through the current OperationContext as shown here:</p>
<pre>ServiceSecurityContext context = OperationContext.Current.ServiceSecurityContext;</pre>
<p>Or, you can reach it directly through the static Current property:</p>
<pre>ServiceSecurityContext context = ServiceSecurityContext.Current;</pre>
<p>So, what&rsquo;s the significance of the security principal attached to the thread and the security context? The security principal is used for role-based security consistent with pre-WCF role-based security techniques, while the ServiceSecurityContext is a WCF-specific abstraction that is most useful when you move away from role-based security to claims-based security as I will discuss.</p>
<p><strong>Role-Based Permission Demands</strong></p>
<p>.NET role-based security relies on the IPrincipal object attached to the thread to perform authorization checks. To authorize access to WCF operations you can use a <strong>PrincipalPermission</strong> demand to find out if the user is authenticated, if they are in a particular role, or if a particular user is calling (not as useful). Using an imperative permission demand within the WCF operation means creating a PrincipalPermission instance, initializing the values to enforce, and issuing a Demand():</p>
<pre>public string AdminsOnly()
{
  // unprotected code

  PrincipalPermission p = new PrincipalPermission(null, &quot;Administrators&quot;);
  p.Demand();

  // protected code
}
</pre>
<p>In this example, an exception will be thrown if the user is not in the Administrators group. You can also do this declaratively with the <strong>PrincipalPermissionAttribute</strong>:</p>
<pre>[PrincipalPermission(SecurityAction.Demand, Role=&quot;Administrators&quot;)]
public string AdminsOnly()
{
  // protected code
}
</pre>
<p>Ultimately, both of these scenarios use the PrincipalPermission type to validate the thread&rsquo;s security principal. This is done by checking the IsAuthenticated property of the IIdentity type and invoking the IsInRole() method of the IPrincipal type to check membership.</p>
<p>Internally, each IPrincipal type has its own way to enforce role checks when IsInRole() is called. In the case of the RoleProviderPrincipal it uses the ServiceSecurityContext to access the user&rsquo;s identity, and it relies on the configured membership provider to check roles.</p>
<h2>WCF and Claims-Based Security</h2>
<p>Clearly, applying role-based permission demands is an easy approach to authorizing callers at the service tier. But, as I mentioned earlier, roles are very coarse and are prone to customization and change. Permissions are more granular, but don&rsquo;t carry guarantees and aren&rsquo;t first class citizens in any .NET security model. Claims, on the other hand, are a first class citizen with WCF.</p>
<p><strong>Claims</strong></p>
<p>Credentials are passed in the security headers of a message as security tokens. Each security token in a message is mapped to a set of claims that are added to the security context for the request. A claim describes an individual right or action applicable to a particular resource. For example, an identity claim might describe a username, while a proof of possession claim might describe a role, a right to a particular resource, or some other useful information.</p>
<p>Claims are represented at runtime as a <strong>Claim</strong> type, from the System.IdentityModel.Claims namespace, with the following key properties:</p>
<ul>
<li><strong>ClaimType:</strong> Can be any Uri value identifying the type of claim. A basic set of claims used by WCF can be found in the <strong>ClaimTypes</strong> static class, but this can be customized.</li>
<li><strong>Resource:</strong> Can be any type, but should contain the resource being referred to by the claim. For an e-mail possession claim, this would contain an e-mail address as a string.</li>
<li><strong>Right:</strong> Can be a Uri identifying an identity claim, or a possession claim. The <strong>Rights</strong> static class contains the correct Uri to use.</li>
</ul>
<p>You can programmatically construct a Claim by providing a ClaimType, Resource and Right. The following code shows how to create a Claim that represents possession of an email address:</p>
<pre>Claim c = new
Claim(&quot;http://schemas.xmlsoap.org/ws/2005/05/identity/
claims/emailaddress&quot;, &quot;mlb@idesign.net&quot;, 

http://schemas.xmlsoap.org/ws/2005/05/identity/right/possessproperty);
</pre>
<p>You can also rely on the ClaimTypes and Rights static classes instead of looking up the correct Uri for each:</p>
<pre>Claim c = new Claim(ClaimTypes.Email, &quot;mlb@idesign.net&quot;,
Rights.PossessProperty);
</pre>
<p>The types of claims associated with the security context depend on the type of token, as I&rsquo;ll discuss next.</p>
<p><strong>Claim Sets</strong></p>
<p>A claim set is a collection of claims granted by a particular issuer. For example, the claims extracted from an X.509 token are vouched for by the certificate authority. The certificate authority is therefore the issuer of the claim set. A claim set is represented at runtime by the <strong>ClaimSet</strong> type. Key properties for this type are:</p>
<ul>
<li><strong>Issuer:</strong> Another ClaimSet describing the issuer.</li>
<li>A collection of claims the issuer vouches for.</li>
</ul>
<p>WindowsClaimSet, UserNameClaimSet and X509ClaimSet are examples of types that inherit the ClaimSet base type. These are the claim sets generated for Windows, UserName and X.509 tokens, respectively. To give you some context for what goes into a ClaimSet, let&rsquo;s look at a few examples relevant to some common credentials used for authentication.</p>
<p>A WindowsClaimSet includes information about the identity of the user, plus other information about windows groups and other security identifiers. The following table shows a list of identity and possession claims for a Windows token:</p>
<table border="1" bordercolor="#000000" cellpadding="5" cellspacing="0">
<tbody>
<tr>
<td valign="top" width="454">
<p><strong>Right:ClaimType </strong></p>
</td>
<td valign="top" width="185">
<p><strong>Resource </strong></p>
</td>
</tr>
<tr>
<td valign="top" width="454">
<p>http://schemas.xmlsoap.org/ws/2005/05/identity/right/identity: http://schemas.xmlsoap.org/ws/2005/05/identity/claims/sid</p>
</td>
<td valign="top" width="185">
<p>S-1-5-21-2747712036-3657831467-4081887108-1000</p>
</td>
</tr>
<tr>
<td valign="top" width="454">
<p>http://schemas.xmlsoap.org/ws/2005/05/identity/right/possessproperty: http://schemas.xmlsoap.org/ws/2005/05/identity/claims/sid</p>
</td>
<td valign="top" width="185">
<p>S-1-5-21-2747712036-3657831467-4081887108-1000</p>
</td>
</tr>
<tr>
<td valign="top" width="454">
<p>http://schemas.xmlsoap.org/ws/2005/05/identity/right/possessproperty: <a href="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name">http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name</a></p>
</td>
<td valign="top" width="185">
<p>IDesign\\Administrator</p>
</td>
</tr>
<tr>
<td valign="top" width="454">
<p>http://schemas.xmlsoap.org/ws/2005/05/identity/right/possessproperty: <a href="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/sid">http://schemas.xmlsoap.org/ws/2005/05/identity/claims/sid</a></p>
</td>
<td valign="top" width="185">
<p>S-1-5-21-2747712036-3657831467-4081887108-513</p>
</td>
</tr>
<tr>
<td valign="top" width="454">
<p>http://schemas.xmlsoap.org/ws/2005/05/identity/right/possessproperty: <a href="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/sid">http://schemas.xmlsoap.org/ws/2005/05/identity/claims/sid</a></p>
</td>
<td valign="top" width="185">
<p>S-1-1-0</p>
</td>
</tr>
<tr>
<td valign="top" width="454">
<p>http://schemas.xmlsoap.org/ws/2005/05/identity/right/possessproperty: <a href="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/sid">http://schemas.xmlsoap.org/ws/2005/05/identity/claims/sid</a></p>
</td>
<td valign="top" width="185">
<p>S-1-5-32-544</p>
</td>
</tr>
<tr>
<td valign="top" width="454">
<p>http://schemas.xmlsoap.org/ws/2005/05/identity/right/possessproperty: <a href="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/sid">http://schemas.xmlsoap.org/ws/2005/05/identity/claims/sid</a></p>
</td>
<td valign="top" width="185">
<p>S-1-5-32-545</p>
</td>
</tr>
<tr>
<td valign="top" width="454">
<p>http://schemas.xmlsoap.org/ws/2005/05/identity/right/possessproperty: <a href="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/sid">http://schemas.xmlsoap.org/ws/2005/05/identity/claims/sid</a></p>
</td>
<td valign="top" width="185">
<p>S-1-5-4</p>
</td>
</tr>
<tr>
<td valign="top" width="454">
<p>http://schemas.xmlsoap.org/ws/2005/05/identity/right/possessproperty: <a href="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/sid">http://schemas.xmlsoap.org/ws/2005/05/identity/claims/sid</a></p>
</td>
<td valign="top" width="185">
<p>S-1-5-11</p>
</td>
</tr>
<tr>
<td valign="top" width="454">
<p>http://schemas.xmlsoap.org/ws/2005/05/identity/right/possessproperty: <a href="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/sid">http://schemas.xmlsoap.org/ws/2005/05/identity/claims/sid</a></p>
</td>
<td valign="top" width="185">
<p>S-1-5-15</p>
</td>
</tr>
<tr>
<td valign="top" width="454">
<p>http://schemas.xmlsoap.org/ws/2005/05/identity/right/possessproperty: <a href="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/sid">http://schemas.xmlsoap.org/ws/2005/05/identity/claims/sid</a></p>
</td>
<td valign="top" width="185">
<p>S-1-2-0</p>
</td>
</tr>
<tr>
<td valign="top" width="454">
<p>http://schemas.xmlsoap.org/ws/2005/05/identity/right/possessproperty: <a href="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/sid">http://schemas.xmlsoap.org/ws/2005/05/identity/claims/sid</a></p>
</td>
<td valign="top" width="185">
<p>S-1-5-64-10</p>
</td>
</tr>
</tbody>
</table>
<p>You&rsquo;ll notice a few things about these claims:</p>
<ul>
<li>There is a single <strong>identity claim </strong>that is an SID associated with a Windows token identifier.</li>
<li>The remaining claims are <strong>possession of property claims</strong> that provide additional information about the user. Those include a name claim with the user name associated with the token; and other SID claims representative of other token information and groups associated with the user.</li>
</ul>
<p>The issuer can also be described as a WindowsClaimSet, representative of the Windows account for the machine where the claims were issued.</p>
<p>A UserNameClaimSet produces a completely different set of claims as shown in this table:</p>
<table border="1" bordercolor="#000000" cellpadding="5" cellspacing="0">
<tbody>
<tr>
<td valign="top" width="454">
<p><strong>Right:ClaimType </strong></p>
</td>
<td valign="top" width="185">
<p><strong>Resource </strong></p>
</td>
</tr>
<tr>
<td valign="top" width="454">
<p>http://schemas.xmlsoap.org/ws/2005/05/identity/right/identity: <a href="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name">http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name</a></p>
</td>
<td valign="top" width="185">
<p>Admin</p>
</td>
</tr>
<tr>
<td valign="top" width="454">
<p>http://schemas.xmlsoap.org/ws/2005/05/identity/right/possessproperty: <a href="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name">http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name</a></p>
</td>
<td valign="top" width="185">
<p>Admin</p>
</td>
</tr>
</tbody>
</table>
<p>This time you&rsquo;ll notice that a single identity and possess property claim are provided &ndash; both indicating the user name &ndash; and that no roles are included in this claim set. The issuer of a UserNameClaimSet is usually a DefaultClaimSet indicating the system (or, application) issued the claims. This table lists the claims inside the issuer&rsquo;s DefaultClaimSet:</p>
<table border="1" bordercolor="#000000" cellpadding="5" cellspacing="0">
<tbody>
<tr>
<td valign="top" width="454">
<p><strong>Right:ClaimType </strong></p>
</td>
<td valign="top" width="185">
<p><strong>Resource </strong></p>
</td>
</tr>
<tr>
<td valign="top" width="454">
<p><a href="http://schemas.xmlsoap">http://schemas.xmlsoap</a>.org/ws/2005/05/identity/right/identity: <a href="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/system">http://schemas.xmlsoap.org/ws/2005/05/identity/claims/system</a></p>
</td>
<td valign="top" width="185">
<p>System</p>
</td>
</tr>
<tr>
<td valign="top" width="454">
<p>http://schemas.xmlsoap.org/ws/2005/05/identity/right/possessproperty: <a href="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/system">http://schemas.xmlsoap.org/ws/2005/05/identity/claims/system</a></p>
</td>
<td valign="top" width="185">
<p>System</p>
</td>
</tr>
</tbody>
</table>
<p>For X.509 tokens, the X509ClaimSet describes information related to the certificate as shown here:</p>
<table border="1" bordercolor="#000000" cellpadding="5" cellspacing="0">
<tbody>
<tr>
<td valign="top" width="454">
<p><strong>Right:ClaimType </strong></p>
</td>
<td valign="top" width="185">
<p><strong>Resource </strong></p>
</td>
</tr>
<tr>
<td valign="top" width="454">
<p>http://schemas.xmlsoap.org/ws/2005/05/identity/right/identity: <a href="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/thumbprint">http://schemas.xmlsoap.org/ws/2005/05/identity/claims/thumbprint</a></p>
</td>
<td valign="top" width="185">
<p>cb d5 50 10 f1 65 af 3d 3b be a7 03 fb fe 87 28 89 06 e4 b6</p>
</td>
</tr>
<tr>
<td valign="top" width="454">
<p>://schemas.xmlsoap.org/ws/2005/05/identity/right/possessproperty: <a href="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/thumbprint">http://schemas.xmlsoap.org/ws/2005/05/identity/claims/thumbprint</a></p>
</td>
<td valign="top" width="185">
<p>cb d5 50 10 f1 65 af 3d 3b be a7 03 fb fe 87 28 89 06 e4 b6</p>
</td>
</tr>
<tr>
<td valign="top" width="454">
<p>http://schemas.xmlsoap.org/ws/2005/05/identity/right/possessproperty: <a href="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/x500distinguishedname">http://schemas.xmlsoap.org/ws/2005/05/identity/claims/x500distinguishedname</a></p>
</td>
<td valign="top" width="185">
<p>CN=SubjectKey</p>
</td>
</tr>
<tr>
<td valign="top" width="454">
<p>http://schemas.xmlsoap.org/ws/2005/05/identity/right/possessproperty: <a href="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/dns">http://schemas.xmlsoap.org/ws/2005/05/identity/claims/dns</a></p>
</td>
<td valign="top" width="185">
<p>SubjectKey</p>
</td>
</tr>
<tr>
<td valign="top" width="454">
<p>http://schemas.xmlsoap.org/ws/2005/05/identity/right/possessproperty: <a href="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name">http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name</a></p>
</td>
<td valign="top" width="185">
<p>SubjectKey</p>
</td>
</tr>
<tr>
<td valign="top" width="454">
<p>http://schemas.xmlsoap.org/ws/2005/05/identity/right/possessproperty: <a href="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/rsa">http://schemas.xmlsoap.org/ws/2005/05/identity/claims/rsa</a></p>
</td>
<td valign="top" width="185">
<p>RSACryptoServiceProvider instance</p>
</td>
</tr>
</tbody>
</table>
<p>The issuer for the X509ClaimSet depends on the type of certificate it represents. For example, if the certificate is self-issued, so is the claim set, which means the Issuer references itself. If the certificate is the root certificate, then the issuer should be the Certificate Authority certificate, otherwise it could represent another certificate in the chain.</p>
<p>The point of this discussion is to help you visualize the fact that every security token can be mapped to a set of claims, and that the service model extracts relevant claims for tokens it knows about. So far, I have focused only on Windows, UserName and Certificate credentials. What you should take away is the following:</p>
<ul>
<li>For Windows credentials, clearly it is easier to work with role-based security rather than resolving SIDs to Windows groups using the claim set.</li>
<li>For UserName credentials, role-based security is the obvious choice since no roles are included in the claim set.</li>
<li>For Certificate credentials, since there is no role-based security (unless you map certificates to Windows accounts) you might find the claim set useful for doing custom authorization. For example you might have a database that associates certificates with custom roles or claims.</li>
</ul>
<p>You can construct a custom claim set by either extending the DefaultClaimSet type or by constructing a DefaultClaimSet instance and providing a list of claims along with an issuer. The following example creates a claim set that describes an issuer using a name claim:</p>
<pre>Claim c =Claim.CreateNameClaim(
&quot;http://www.thatindigogirl.com/samples/2006/06/issuer&quot;);
Claim[] claims = new Claim[1];
claims[0] = c;
ClaimSet issuer = new DefaultClaimSet(claims);
</pre>
<p>Since an issuer is not provided to the DefaultClaimSet constructor, the resulting ClaimSet is considered to be self-issued, and the Issuer property will reference itself. You can use this issuer claim set to construct a custom claim set for an application, as you&rsquo;ll see later on.</p>
<p><strong>AuthorizationContext</strong></p>
<p>As I&rsquo;ve discussed, when clients send credentials they are serialized as security tokens. The service model processes each security token and generates claims that vary based on the type of token. The claims are stored in the security context, accessible through the <strong>AuthorizationContext</strong> shown here:</p>
<pre>AuthorizationContext authContext =
ServiceSecurityContext.Current.AuthorizationContext;
</pre>
<p>The AuthorizationContext includes one or more claim sets based on the authenticated security tokens from the incoming request message, and associated authorization policies. You can programmatically access each claim set and drill down to extract specific claims for authorization. For example, inside a service operation you might look for an X509CertificateClaimSet and check the DNS claim for a particular subject key:</p>
<pre>AuthorizationContext authContext =
ServiceSecurityContext.Current.AuthorizationContext;

X509CertificateClaimSet certClaims = null;
foreach (ClaimSet c in authContext.ClaimSets)
{
  certClaims = c as X509CertificateClaimSet;
  if (certClaims != null)
    break;
}

if (certClaims == null)
  throw new SecurityException(&quot;Access is denied. X509CertificateClaimSet is required.&quot;);

if (!certClaims.ContainsClaim(Claim.CreateDnsClaim(&quot;RPKey&quot;)))
  throw new SecurityException(&quot;Access is denied.&quot;);
</pre>
<p>This example illustrates how you can access claims through the AuthorizationContext, based on the types of claim sets discussed so far. In reality it is more likely that you&rsquo;ll map the incoming certificate to a custom set of roles or claims in order to standardize how you authorize callers to each operation. The AuthorizationContext becomes very useful in accessing custom claims attached to the security context that have specific meaning to your application. This is what I&rsquo;ll focus on for the remainder of this article.</p>
<h2>Building a Claims-Based Authorization Model</h2>
<p>Now that you have some background on how claims are associated with the AuthorizationContext, and how you can access those claims to authorize calls &#8211; I&rsquo;ll explain how to build a claims-based security model at the service tier using a custom authorization policy. The idea behind this is that your applications and services may need to support many credential types to support internal and external clients. Figure 1 illustrates this.</p>
<p><img height="389" src="http://www.theserverside.net/tt/articles/content/ClaimsBasedSecurityModel/clip_image002.jpg" width="623" /></p>
<p><strong>Figure 1: Services can be configured to support different credential types through security policy. </strong></p>
<p><em>NOTE: All endpoints for a service share behavior, so you are more likely to have a common base service type with service logic, while exposing several derived types with unique endpoints and authorization behavior. </em></p>
<p>If services focus on authorization based on a normalized set of claims, the security policy can change without affecting service authorization, or downstream business rules based on user rights. Service developers should be able to work with a specific set of claims required to access features and interact with business rules &ndash; and ideally these claims are not coupled to a particular credential or set of roles. One way to achieve this is with a custom authorization policy as shown in Figure 2.</p>
<p><img height="468" src="http://www.theserverside.net/tt/articles/content/ClaimsBasedSecurityModel/clip_image004.jpg" width="624" /></p>
<p><strong>Figure 2: A custom authorization policy can produce a normalized set of claims for all credentials so that services can focus on a single set of claims for authorization. </strong></p>
<p>In this case, the authorization policy is responsible for normalizing claims based on credentials provided, and the service authorizes against this consistent set of claims.</p>
<p><strong>Defining Custom Claims</strong></p>
<p>Before you can implement a claims-based model, you must consider what types of claims make sense to your application. If you think of claims as permissions that are required to access features, one thing you can do is create a list of these permissions, and the resources or features they relate to if applicable, and then formulate a set of custom claim types and resources based on this information.</p>
<p>Consider CRUD (Create, Read, Update, and Delete) operations related to resources in an application. If the application has two key features related to Customers and Orders, you might want to specify CRUD rights for each resource that can later be allocated to users as they are authenticated. The following table summarizes the possible claims:</p>
<table border="1" bordercolor="#000000" cellpadding="5" cellspacing="0">
<tbody>
<tr>
<td valign="top" width="308">
<p><strong>Right:ClaimType </strong></p>
</td>
<td valign="top" width="331">
<p><strong>Resource </strong></p>
</td>
</tr>
<tr>
<td valign="top" width="308">
<p>http://schemas.xmlsoap.org/ws/2005/05/identity/right/possessproperty: http://schemas.thatindigogirl.com/samples/2006/06/identity/claims/create</p>
</td>
<td valign="top" width="331">
<p><a href="http://schemas.thatindigogirl.com/samples/2006/06/identity/resource/customers">http://schemas.thatindigogirl.com/samples/2006/06/identity/resources/customers</a></p>
</td>
</tr>
<tr>
<td valign="top" width="308">
<p>http://schemas.xmlsoap.org/ws/2005/05/identity/right/possessproperty: <a href="http://schemas.thatindigogirl.com/samples/2006/06/identity/claims/read">http://schemas.thatindigogirl.com/samples/2006/06/identity/claims/read</a></p>
</td>
<td valign="top" width="331">
<p><a href="http://schemas.thatindigogirl.com/samples/2006/06/identity/resource/customers">http://schemas.thatindigogirl.com/samples/2006/06/identity/resources/customers</a></p>
</td>
</tr>
<tr>
<td valign="top" width="308">
<p>http://schemas.xmlsoap.org/ws/2005/05/identity/right/possessproperty: <a href="http://schemas.thatindigogirl.com/samples/2006/06/identity/claims/update">http://schemas.thatindigogirl.com/samples/2006/06/identity/claims/update</a></p>
</td>
<td valign="top" width="331">
<p><a href="http://schemas.thatindigogirl.com/samples/2006/06/identity/resource/customers">http://schemas.thatindigogirl.com/samples/2006/06/identity/resources/customers</a></p>
</td>
</tr>
<tr>
<td valign="top" width="308">
<p>http://schemas.xmlsoap.org/ws/2005/05/identity/right/possessproperty: <a href="http://schemas.thatindigogirl.com/samples/2006/06/identity/claims/delete">http://schemas.thatindigogirl.com/samples/2006/06/identity/claims/delete</a></p>
</td>
<td valign="top" width="331">
<p><a href="http://schemas.thatindigogirl.com/samples/2006/06/identity/resource/customers">http://schemas.thatindigogirl.com/samples/2006/06/identity/resources/customers</a></p>
</td>
</tr>
<tr>
<td valign="top" width="308">
<p>http://schemas.xmlsoap.org/ws/2005/05/identity/right/possessproperty: <a href="http://schemas.thatindigogirl.com/samples/2006/06/identity/claims/create">http://schemas.thatindigogirl.com/samples/2006/06/identity/claims/create</a></p>
</td>
<td valign="top" width="331">
<p><a href="http://schemas.thatindigogirl.com/samples/2006/06/identity/resource/orders">http://schemas.thatindigogirl.com/samples/2006/06/identity/resources/orders</a></p>
</td>
</tr>
<tr>
<td valign="top" width="308">
<p>http://schemas.xmlsoap.org/ws/2005/05/identity/right/possessproperty: <a href="http://schemas.thatindigogirl.com/samples/2006/06/identity/claims/read">http://schemas.thatindigogirl.com/samples/2006/06/identity/claims/read</a></p>
</td>
<td valign="top" width="331">
<p><a href="http://schemas.thatindigogirl.com/samples/2006/06/identity/resource/orders">http://schemas.thatindigogirl.com/samples/2006/06/identity/resources/orders</a></p>
</td>
</tr>
<tr>
<td valign="top" width="308">
<p>http://schemas.xmlsoap.org/ws/2005/05/identity/right/possessproperty: <a href="http://schemas.thatindigogirl.com/samples/2006/06/identity/claims/update">http://schemas.thatindigogirl.com/samples/2006/06/identity/claims/update</a></p>
</td>
<td valign="top" width="331">
<p><a href="http://schemas.thatindigogirl.com/samples/2006/06/identity/resource/orders">http://schemas.thatindigogirl.com/samples/2006/06/identity/resources/orders</a></p>
</td>
</tr>
<tr>
<td valign="top" width="308">
<p>http://schemas.xmlsoap.org/ws/2005/05/identity/right/possessproperty: <a href="http://schemas.thatindigogirl.com/samples/2006/06/identity/claims/delete">http://schemas.thatindigogirl.com/samples/2006/06/identity/claims/delete</a></p>
</td>
<td valign="top" width="331">
<p><a href="http://schemas.thatindigogirl.com/samples/2006/06/identity/resource/orders">http://schemas.thatindigogirl.com/samples/2006/06/identity/resources/orders</a></p>
</td>
</tr>
</tbody>
</table>
<p>To work with custom claims and resources in code you can create a list of representative constants as follows:</p>
<pre>public static class ClaimTypes
{
  public const string Create = &quot;http://schemas.thatindigogirl.com/
samples/2006/06/identity/claim/create&quot;;
  public const string Read = &quot;http://schemas.thatindigogirl.com/
samples/2006/06/identity/claim/read&quot;;
  public const string Update = &quot;http://schemas.thatindigogirl.com/
samples/2006/06/identity/claim/update&quot;;
  public const string Delete = &quot;http://schemas.thatindigogirl.com/
samples/2006/06/identity/claim/delete&quot;;
}

public static class Resources
{
  public const string Customers = &quot;http://schemas.thatindigogirl.com/
samples/2006/06/identity/resources/customers&quot;;
  public const string Orders = &quot;http://schemas.thatindigogirl.com/
samples/2006/06/identity/resources/orders&quot;;
}
</pre>
<p>Services would then be designed to perform authentication against these claims, as appropriate for the operation being invoked. For example, an operation that will delete a customer should check that one of the claims provided in the authorization context includes the <strong>ClaimTypes.Delete</strong> right for <strong>Resources.Customers</strong>. As new features are added to the application, new claims may also be introduced to the authorization model, but if designed properly existing operations wouldn&rsquo;t need to change their authorization requirements.</p>
<p>It may also be important who issued the claim. For example, you may want to look for a claim set by a trusted issuer before checking for particular claims within the claim set. When you&rsquo;re using a custom authorization policy, as I will discuss in the coming sections, the issuer might just be the application as it was for the UserNameClaimSet discussed earlier, or a named internal issuer. In the article to follow this one, I will talk about trusting external issuers.</p>
<p><strong>Implementing IAuthorizationPolicy</strong></p>
<p>Once you have established your requirements for claims-based authorization, you can implement a custom authorization policy to handle mapping different credentials and tokens to your normalized application claims. A custom authorization policy is a type that implements the IAuthorizationPolicy interface from the System.IdentityModel.Policy namespace. Authorization policies can inspect the claims that will be attached to the security context, before operations are called, and attach new claim sets to that context. In addition, a custom authorization policy is required to provide a security principal to be attached to the request thread &ndash; in lieu of it being done automatically through default authentication.</p>
<p>To implement a custom authorization policy, you create a type that implements <strong>IAuthorizationPolicy</strong>. This interface also inherits <strong>IAuthorizationComponent</strong>, which means you must also provide implementation for its members. Definitions for the two interfaces are shown here:</p>
<pre>public interface IAuthorizationPolicy : IAuthorizationComponent
{
  ClaimSet Issuer { get; }

  bool Evaluate(EvaluationContext evaluationContext,
ref object state);
}

public interface IAuthorizationComponent
{
  string Id { get; }
}
</pre>
<p>The functionality for each member should be implemented as follows:</p>
<ul>
<li><strong>Id </strong>returns a unique identifier for the authorization policy instance. This can be a unique GUID.</li>
<li><strong>Issuer</strong> returns a ClaimSet describing the issuer associated with the authorization policy. If claims are generated by this authorization policy, it must provide an issuer when generating the claim set for the authorization context.</li>
<li>The <strong>Evaluate() </strong>method receives the claim sets evaluated so far by other authorization policies. For example, it may include a claim set for each token passed in the request message, thus contain a WindowsClaimSet or UserNameClaimSet and so on.</li>
</ul>
<p>Evaluate() is the heart and soul of this implementation &ndash; responsible for inspecting claims based on the credentials provided, mapping those claims to normalized claims, and constructing a security principal for the request thread. The method should return false if this authorization policy was not able to complete its authorization. If false, the service model will invoke other authorization policies and then call this one once more, passing the updated claim sets. This gives the authorization policy another chance to authorize calls.</p>
<p>The <strong>EvaluationContext</strong> passed to Evaluate() provides access to the user identity through its Properties dictionary. If you are looking for a particular type of identity, such as a WindowsIdentity or GenericIdentity you can check for this before mapping the identity to custom claims. The following code expects a single identity of type GenericIdentity, for services that require UserName credentials:</p>
<pre>  object objIdentities = evaluationContext.Properties[&quot;Identities&quot;];
  IList&lt;IIdentity&gt; identities = objIdentities as IList&lt;IIdentity&gt;;
  if (identities != null &amp;&amp; identities.Count &gt; 0)
  {
    IIdentity identity = identities[0] as GenericIdentity;
    if (identity == null)
      // can�t authorize
    else
      // can authorize
  }
</pre>
<p>If you write an authorization policy that specifically handles normalizing claims for UserName credentials, this is acceptable. You can optionally change this to support different identity types.</p>
<p>Once you have the identity, you can decide how to map that identity to normalized claims, building a ClaimSet for the authorization context. One approach could be to map roles to claims, which means looking up the roles for the identity to achieve this. The following <strong>MapClaims()</strong> function accepts an identity, expecting to use the ASP.NET provider model to find its roles and map those roles to claims:</p>
<pre>protected virtual ClaimSet MapClaims(IIdentity identity)
{
  List&lt;Claim&gt; listClaims = new List&lt;Claim&gt;();

  if (Roles.IsUserInRole(identity.Name, &quot;Guests&quot;))
  {
    listClaims.Add(new Claim(ClaimsAuthorizationPolicy.ClaimTypes.Read,
ClaimsAuthorizationPolicy.Resources.Customers,
Rights.PossessProperty));
    listClaims.Add(new Claim(ClaimsAuthorizationPolicy.ClaimTypes.Read,
ClaimsAuthorizationPolicy.Resources.Orders,
Rights.PossessProperty));
  }
  else if (Roles.IsUserInRole(identity.Name, &quot;Users&quot;))
  {
    listClaims.Add(new Claim(ClaimsAuthorizationPolicy.ClaimTypes.Read,
ClaimsAuthorizationPolicy.Resources.Customers,
Rights.PossessProperty));
    listClaims.Add(new Claim(ClaimsAuthorizationPolicy.ClaimTypes.Read,
ClaimsAuthorizationPolicy.Resources.Orders,
Rights.PossessProperty));
    listClaims.Add(new Claim(ClaimsAuthorizationPolicy.ClaimTypes.Create,
ClaimsAuthorizationPolicy.Resources.Customers,
Rights.PossessProperty));
    listClaims.Add(new Claim(ClaimsAuthorizationPolicy.ClaimTypes.Create,
ClaimsAuthorizationPolicy.Resources.Orders,
Rights.PossessProperty));
    listClaims.Add(new Claim(ClaimsAuthorizationPolicy.ClaimTypes.Update,
ClaimsAuthorizationPolicy.Resources.Customers,
Rights.PossessProperty));
    listClaims.Add(new Claim(ClaimsAuthorizationPolicy.ClaimTypes.Update,
ClaimsAuthorizationPolicy.Resources.Orders,
Rights.PossessProperty));

  }
  else if (Roles.IsUserInRole(identity.Name, &quot;Administrators&quot;))
  {
    listClaims.Add(new Claim(ClaimsAuthorizationPolicy.ClaimTypes.Read,
ClaimsAuthorizationPolicy.Resources.Customers,
Rights.PossessProperty));
    listClaims.Add(new Claim(ClaimsAuthorizationPolicy.ClaimTypes.Read,
ClaimsAuthorizationPolicy.Resources.Orders,
Rights.PossessProperty));
    listClaims.Add(new Claim(ClaimsAuthorizationPolicy.ClaimTypes.Create,
ClaimsAuthorizationPolicy.Resources.Customers,
Rights.PossessProperty));
    listClaims.Add(new Claim(ClaimsAuthorizationPolicy.ClaimTypes.Create,
ClaimsAuthorizationPolicy.Resources.Orders,
Rights.PossessProperty));
    listClaims.Add(new Claim(ClaimsAuthorizationPolicy.ClaimTypes.Update,
ClaimsAuthorizationPolicy.Resources.Customers,
Rights.PossessProperty));
    listClaims.Add(new Claim(ClaimsAuthorizationPolicy.ClaimTypes.Update,
ClaimsAuthorizationPolicy.Resources.Orders,
Rights.PossessProperty));
    listClaims.Add(new Claim(ClaimsAuthorizationPolicy.ClaimTypes.Delete,
ClaimsAuthorizationPolicy.Resources.Customers,
Rights.PossessProperty));
    listClaims.Add(new Claim(ClaimsAuthorizationPolicy.ClaimTypes. Delete,
ClaimsAuthorizationPolicy.Resources.Orders,
Rights.PossessProperty));
  }

  return new DefaultClaimSet(ClaimSet.System, listClaims);
}
</pre>
<p>For each role associated with UserName credentials, the authorization policy has established a list of claims that are appropriate. At the end of the function a new ClaimSet is created, in this case a DefaultClaimSet. You must provide the list of claims and an issuer for the claim set. In this case, the issuer is the application, identified by ClaimSet.System. You can also construct a custom claim set to identify the issuer &ndash; to distinguish claims. For example, you can construct a name claim with a custom Uri as shown here:</p>
<pre>public const string IssuerName = &quot;http://www.thatindigogirl.com/samples/2006/06/issuer&quot;;

Claim c = Claim.CreateNameClaim(ClaimsAuthorizationPolicy.IssuerName);
Claim[] claims = new Claim[1];
claims[0] = c;
DefaultClaimSet issuerClaimSet = new DefaultClaimSet(claims);
</pre>
<p>This approach allows you to check for the application trusted claim set when authorizing requests.</p>
<p>Once the normalized claim set is generated, you must attach it to the EvaluationContext so that the service model can add it to the AuthorizationContext. In addition, you must add a security principal to the EvaluationContext so that the service model can attach it to the request thread, and to the security context as discussed earlier. The complete implementation of the Evaluate() function for this custom authorization policy, addressing these requirements, is shown here:</p>
<pre>public bool Evaluate(EvaluationContext evaluationContext,
ref object state)
{
  if (evaluationContext.Properties.ContainsKey(&quot;Identities&quot;))
  {
    List&lt;IIdentity&gt; identities =
evaluationContext.Properties[&quot;Identities&quot;] as List&lt;IIdentity&gt;;
    IIdentity identity = identities[0];

    ClaimSet claims = MapClaims(identity);

    GenericPrincipal newPrincipal = new
GenericPrincipal(identity, null);
    evaluationContext.Properties[&quot;Principal&quot;] = newPrincipal;

    if (claims != null)
      evaluationContext.AddClaimSet(this, claims);

    return true;
  }
  else
    return false;
}
</pre>
<p>MapClaims() returns the claim set to attach to the evaluation context and a new GenericPrincipal without any roles is constructed to provide a security principal for the request thread. In this case, role-based security will be useless since no roles are assigned &ndash; but the AuthorizationContext will support claims-based security.</p>
<p><em>NOTE: You do not have to look at roles to map claims. Instead, you could look at the claim sets attached to the evaluation context, and determine how to assign normalized claims from the generated claims. </em></p>
<p><strong>Configuring Custom Authorization Policies</strong></p>
<p>To configure a custom authorization policy you set the PrincipalPermissionMode to Custom for the service authorization behavior, and add the IAuthorizationPolicy type to the authorization policies section as follows:</p>
<pre>&lt;serviceAuthorization principalPermissionMode=&quot;Custom&quot; &gt;
  &lt;authorizationPolicies&gt;
    &lt;add policyType=
&quot;ClaimsBasedSecurityComponents.ClaimsAuthorizationPolicy, ClaimsBasedSecurityComponents&quot;/&gt;
  &lt;/authorizationPolicies&gt;
&lt;/serviceAuthorization&gt;
</pre>
<p><em>NOTE: this can also be done programmatically through the ServiceHost instance. </em></p>
<p>By stating you are performing custom authorization, you are expected to supply the security principal for the thread, as I have discussed. You can configure one or more authorization policy, in the order you want them executed. This can be useful if you support different types of credentials at the service, and want to provide different authorization policies to handle each credential type for better reuse.</p>
<p>Once configured, the authorization policy will be instantiated for each request to the service, and given a change to supply information for the security context.</p>
<p><strong>Working with Normalized Claims</strong></p>
<p>Earlier in the article I said that the goal was to allow developers to standardize on a set of claims to authorize calls to each operation. As discussed earlier, the traditional role-based security model meant applying authorization checks at the operation level using permission demands either in code or using the PrincipalPermissionAttribute. Once your custom authorization policy is in place, you can replace these permission demands with claims-based authorization checks against the AuthorizationContext.</p>
<p>Consider a DeleteCustomer() operation that requires callers are granted delete rights to the customers resource. Inside the operation you can check the AuthorizationContext for a claim issued by your custom application issuer that matches this requirement:</p>
<pre>public string DeleteCustomer()
{
  AuthorizationContext authContext =
ServiceSecurityContext.Current.AuthorizationContext;

  ClaimSet issuerClaimSet = null;
  foreach (ClaimSet cs in authContext.ClaimSets)
  {
    Claim issuerClaim = Claim.CreateNameClaim(
&quot;http://www.thatindigogirl.com/samples/2006/06/issuer&quot;);

    if (cs.Issuer.ContainsClaim(issuerClaim))
      issuerClaimSet=cs;
  }

  if (issuerClaimSet==null)
    throw new SecurityException(&quot;Access is denied. No claims were provided from the expected issuer.&quot;);

  Claim c = new Claim(&quot;http://schemas.thatindigogirl.com/
samples/2006/06/identity/claims/delete&quot;,
&quot;http://schemas.thatindigogirl.com/samples/2006/06/identity/
resources/customers&quot;, Rights.PossessProperty);

  if (!issuerClaimSet.ContainsClaim(c))
    throw new SecurityException(&quot;Access is denied. Required claims not
satisfied.&quot;);
</pre>
<p>This code traverses the AuthorizationContext for a claim set that matches the issuer identified by the name claim mentioned earlier: &quot;http://www.thatindigogirl.com/samples/2006/06/issuer&quot;. If a claim set from the expected issuer is present, the code proceeds to look for a particular claim. In this case, the delete claim for customers.</p>
<p>Of course, you probably wouldn&rsquo;t want to litter service operation code with this cumbersome block of code to authorize callers. That&rsquo;s where we get into other techniques for authorizing these normalized claims, to be discussed in the next part of this article.</p>
<h2>Summary</h2>
<p>In this article you learned how role-based security and claims-based security differ, and how to implement a claims-based security model. The goal of this first part was to educate you on claims and claim sets, help you understand how tokens map to claims, and educate you on the process of creating your own custom claims model. In addition, you learned how to create a custom authorization policy that can normalize claims for all tokens, and insert those new claims into the authorization context for evaluation in lieu of role-based security checks.</p>
<p>In the next part of this article, I&rsquo;ll discuss several techniques for refining the authorization of custom claims. Instead of performing authorization directly in the operation I&rsquo;ll show you how to extend the role-based security model of .NET for a claims-based model, I&rsquo;ll also compare that approach to a custom validation policy or custom security token manager implementation. In addition, I&rsquo;ll look at how the model works with SAML tokens issued by a custom security token service (STS).</p>
<h2>Resources</h2>
<p>Code for this article: <a href="http://www.dasblonde.net/downloads/tssclaimsbasedpart1.zip">http://www.dasblonde.net/downloads/tssclaimsbasedpart1.zip</a></p>
<p><strong>Michele Leroux Bustamante</strong></p>
]]></content:encoded>
			<wfw:commentRss>http://www.allfreetech.com/microsoft-net/building-a-claims-based-security-model-in-wcf-part-1-68.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

