Improving WIF’s Claims-based Authorization - Part 2

Posted by Your DisplayName here! on Least Privilege See other posts from Least Privilege or by Your DisplayName here!
Published on Wed, 04 May 2011 10:05:20 GMT Indexed on 2011/06/20 16:38 UTC
Read the original article Hit count: 741

Filed under:

In the last post I showed you how to take control over the invocation of ClaimsAuthorizationManager. Then you have complete freedom over the claim types, the amount of claims and the values.

In addition I added two attributes that invoke the authorization manager using an “application claim type”. This way it is very easy to distinguish between authorization calls that originate from WIF’s per-request authorization and the ones from “within” you application.

The attribute comes in two flavours: a CAS attribute (invoked by the CLR) and an ASP.NET MVC attribute (for MVC controllers, invoke by the MVC plumbing). Both also feature static methods to easily call them using the application claim types.

The CAS attribute is part of Thinktecture.IdentityModel on Codeplex (or via NuGet: Install-Package Thinktecture.IdentityModel). If you really want to see that code ;) There is also a sample included in the Codeplex donwload.

The MVC attribute is currently used in Thinktecture.IdentityServer – and I don’t currently plan to make it part of the library project since I don’t want to add a dependency on MVC for now.

You can find the code below – and I will write about its usage in a follow-up post.

public class ClaimsAuthorize : AuthorizeAttribute
{
   
private string
_resource;
   
private string
_action;
   
private string
[] _additionalResources;

   
/// <summary>
    /// Default action claim type.
    /// </summary>
    public const string ActionType = "http://application/claims/authorization/action"
;


   
/// <summary>
    /// Default resource claim type
    /// </summary>
    public const string ResourceType = "http://application/claims/authorization/resource"
;

   
/// <summary>
    /// Additional resource claim type
    /// </summary>
    public const string AdditionalResourceType = "http://application/claims/authorization/additionalresource"

>>>    

    public ClaimsAuthorize(string action, string resource, params string[] additionalResources)
    {
        _action = action;
        _resource = resource;
        _additionalResources = additionalResources;
    }

   
public static bool CheckAccess(
     
string action, string resource, params string
[] additionalResources)
    {
       
return
CheckAccess(
           
Thread.CurrentPrincipal as IClaimsPrincipal
,
            action,
            resource,
            additionalResources);
    }

   
public static bool CheckAccess(
     
IClaimsPrincipal principal, string action, string resource, params string
[] additionalResources)
    {
       
var
context = CreateAuthorizationContext(
            principal,
            action,
            resource,
            additionalResources);

       
return ClaimsAuthorization
.CheckAccess(context);
    }

   
protected override bool AuthorizeCore(HttpContextBase
httpContext)
    {
       
return
CheckAccess(_action, _resource, _additionalResources);
    }

   
private static WIF.AuthorizationContext CreateAuthorizationContext(
     
IClaimsPrincipal principal, string action, string resource, params string
[] additionalResources)
    {
       
var actionClaims = new Collection<Claim
>
        {
           
new Claim
(ActionType, action)
        };

       
var resourceClaims = new Collection<Claim
>
        {
           
new Claim
(ResourceType, resource)
        };

       
if (additionalResources != null
&& additionalResources.Length > 0)
        {
            additionalResources.ToList().ForEach(ar => resourceClaims.Add(
             
new Claim
>(AdditionalResourceType, ar)));
        }

       
return new WIF.AuthorizationContext(
            principal,
            resourceClaims,
            actionClaims);
    }
}

© Least Privilege or respective owner

Related posts about IdentityModel