Skip to content

Instantly share code, notes, and snippets.

@leniency
Created March 13, 2012 15:38
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save leniency/2029462 to your computer and use it in GitHub Desktop.
Save leniency/2029462 to your computer and use it in GitHub Desktop.
Helper class for checking controller permissions.
/// <summary>
/// Helper methods for checking permissions on a controller.
/// </summary>
internal static class PermissionsHelper
{
/// <summary>
/// Internal IsAuthorized helper
/// </summary>
/// <param name="context"></param>
/// <param name="targetControllerType"></param>
/// <param name="targetActionExpression"></param>
/// <returns></returns>
public static bool IsAuthorized(ControllerContext context, Type targetControllerType, MethodCallExpression targetActionExpression)
{
// If the call doesn't exist, then something's wrong.
if (targetActionExpression == null)
return false;
var controllerDescriptor = new ReflectedControllerDescriptor(targetControllerType);
var actionDescriptor = new ReflectedActionDescriptor(targetActionExpression.Method, targetActionExpression.Method.Name, controllerDescriptor);
var authorizationContext = new AuthorizationContext(context, actionDescriptor);
// Get all attributes for the action and controller
var controllerAttributes = targetActionExpression.Object.Type.GetCustomAttributes(typeof(AuthorizeAttribute), true).Cast<AuthorizeAttribute>();
var methodAttributes = targetActionExpression.Method.GetCustomAttributes(typeof(AuthorizeAttribute), true).Cast<AuthorizeAttribute>();
// Merge all unique authorizers from the action and the controller
var authorizers = controllerAttributes.Union<AuthorizeAttribute>(
methodAttributes,
(a, b) =>
// IEQuality comparer - checks if roles, users and authorizer type are the same.
// If the roles or users are in a different order, then they'll flag as different.
a.Roles == b.Roles &&
a.Users == b.Users &&
a.GetType().FullName == b.GetType().FullName);
// No authorize attributes, must be true
if (authorizers.Count() == 0)
return true;
// Check all authorization filters
return authorizers.All(authorizationFilter =>
{
authorizationFilter.OnAuthorization(authorizationContext);
return (authorizationContext.Result == null);
});
}
}
/// <summary>
/// Extension methods for System.Web.Mvc.HtmlHelper for checking if the user is
/// authorized to reach an target controller and action.
/// </summary>
public static class PermissionExtensions
{
/// <summary>
/// Check if the user is authorized to access a controller action
/// </summary>
/// <typeparam name="TController"></typeparam>
/// <param name="helper">HTML Helper</param>
/// <param name="action">The target action</param>
/// <returns></returns>
public static bool IsAuthorized<TController>(this HtmlHelper helper, Expression<Action<TController>> action)
where TController : ControllerBase
{
return PermissionsHelper.IsAuthorized(helper.ViewContext.Controller.ControllerContext, typeof(TController), action.Body as MethodCallExpression);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment