Reputation: 1941
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>
Upvotes: 2
Views: 860
Reputation: 13349
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
Upvotes: 1
Reputation: 2811
[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?
Upvotes: 3