Authorization in ASP.NET MVC
I'm facing a case for which I've researched a lot and I still couldn't find a solution for. I've been given the task of finishing the implementation of roles in an ASP.NET MVC 1 application. The case here is against what is generally done when it comes to permissions in applications. Let's imagine that we have two roles, Operator and Manager, in a 5 pages website. Having an user which inherits the two roles, I want to allow and deny permission to view pages according to the following pattern:
For page 1, the Operator role allows the user to view but the Manager role denies; in this case I want to let the user having these 2 roles view the page;
For page 2, the Operator role denies the user to view and the Manager role denies as well; this is the only situation where I really want to deny a role, when both roles have denied the user from viewing the page.
So, whenever a user inherits multiple roles, what should determine that he can't view a page is a Full Deny (being denied for all his roles), and whenever he has a role that allows, even if all his other roles deny, he will still be able to view the page.
Does anyone know how is it possible to implement this?
EDIT:
Below is just a glimpse of how Authorization is done in our application, besides what's used in the sitemap. You can see the Rule below is using more than one profile. The situation I described above needs to work with the said implementation below.
<Rules xmlns="urn:artemis.runtime.web.security">
<!-- RUNTIME -->
<Rule roles="*" resource="^Artemis\.Runtime\.Web\.FilesController\..*" permission="Allow" />
<!-- ABERTURA GERAL -->
<Rule roles="*" resource="^Tagus\.Logistics\.Web\.Controllers\..*" permission="Allow" />
<Rule roles="Gestor Cliente,DUN" resource="^Tagus\.Logistics\开发者_运维百科.Web\.Controllers\.PlanningVsEffectiveController\..*" permission="Deny" />
</Rules>
[Authorize(Roles = "Operator")]
public ViewResult PageOne(){
return View();
}
[Authorize(Roles = "SomeOneElse")]
public ViewResult PageTwo(){
return View();
}
If I understand correctly you dont wont either of the roles to view the second page?
Authorize is used to decide who to ALLOW not deny. If you wanted to add deny functionality I guess you could make a custom Authorize attribute. Something like:
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, Inherited=true, AllowMultiple=true)]
public class DenyRolesAttribute : AuthorizeAttribute
{
public DenyRolesAttribute(string roles) : base()
{
Roles = roles;
}
protected override bool AuthorizeCore(HttpContextBase httpContext)
{
if (httpContext == null)
{
throw new ArgumentNullException("httpContext");
}
IPrincipal user = httpContext.User;
if (!string.IsNullOrEmpty(Roles) && Enumerable.Any<string>(Roles.Split(','), new Func<string, bool>(user, (IntPtr) user.IsInRole)))
{
return false;
}
return true;
}
}
I made this up on the spot so make sure you test and tidy it up. Or maybe add an AllowRoles and a DenyRoles property so you can do a bit of both in the overridden AuthorizeCore method. You get the idea though
精彩评论