Improving WIF’s Claims-based Authorization - Part 2
- by Your DisplayName here!
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);
}
}