Skip to content

Instantly share code, notes, and snippets.

@portal7
Created March 18, 2016 19:22
Show Gist options
  • Save portal7/1ca492237b7cd5cc7a59 to your computer and use it in GitHub Desktop.
Save portal7/1ca492237b7cd5cc7a59 to your computer and use it in GitHub Desktop.
Granular permissions with certain requirements for an MVC site
public class ApplicationUser : IPrincipal
{
private readonly RoleSet roles;
public ApplicationUser(RoleSet roles)
{
this.roles = roles;
}
public bool IsInRole(string role)
{
return roles.Includes(role);
}
public IIdentity Identity
{
get { return new GenericIdentity("User"); }
}
}
public class AuthorizeRolesAttribute : AuthorizeAttribute
{
private readonly RoleSet authorizedRoles;
public AuthorizeRolesAttribute(params Role[] roles)
{
authorizedRoles = new RoleSet(roles);
}
protected override bool AuthorizeCore(HttpContextBase httpContext)
{
return authorizedRoles.Includes(httpContext.User);
}
}
public class CompositeRoleSet
{
public static CompositeRoleSet CreateDefault()
{
var set = new CompositeRoleSet();
set.Register(Role.ReadWrite, Role.Read, Role.Write);
return set;
}
private readonly Dictionary<Role, Role[]> compositeRoles = new Dictionary<Role, Role[]>();
private void Register(Role composite, params Role[] contains)
{
compositeRoles.Add(composite, contains);
}
public RoleSet Resolve(params Role[] roles)
{
return new RoleSet(roles.SelectMany(Resolve));
}
private IEnumerable<Role> Resolve(Role role)
{
Role[] roles;
if (compositeRoles.TryGetValue(role, out roles) == false)
{
roles = new[] {role};
}
return roles;
}
}
public MvcApplication()
{
AuthenticateRequest += OnAuthenticateRequest;
}
private void OnAuthenticateRequest(object sender, EventArgs eventArgs)
{
var allRoles = CompositeRoleSet.CreateDefault();
var roles = allRoles.Resolve(Role.ReadWrite);
Context.User = new ApplicationUser(roles);
}
public class HomeController : Controller
{
[AuthorizeRoles(Role.Read)]
public ActionResult Index()
{
ViewData["Message"] = "Welcome to ASP.NET MVC!";
return View();
}
[AuthorizeRoles(Role.Write)]
public ActionResult About()
{
return View();
}
}
public enum Role
{
Read,
Write,
ReadWrite
}
public class RoleSet
{
public RoleSet(IEnumerable<Role> roles)
{
Names = roles.Select(role => role.ToString());
}
public bool Includes(IPrincipal user)
{
return Names.Any(user.IsInRole);
}
public bool Includes(string role)
{
return Names.Contains(role);
}
public IEnumerable<string> Names { get; private set; }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment