views:

56

answers:

1

I'm trying to write an ASP.NET MVC application where user privilege is based upon points rather than by a hard-coded role per se. I've tried researching authorization and membership providers but all the information I find points back to role based authentication which isn't really part of my model.

While writing this question I'm wondering if I'm even researching the right things. Would this be a custom role-provider? Does such a thing exist? It suddenly occurs to me that having a custom role provider which checks the user's points to determine if they're in a particular role or not might be the simplest way to go but I have no idea of the keywords I need to use with relation to ASP.NET MVC to find the right information.

What is the best way to achieve this goal?

+4  A: 

I would suggest that a custom authorize attribute that extends AuthorizeAttribute would be a better route. Your attribute would support the ability to do authorization based on Roles, User, or Points, with the former two being provided by the base class and the latter implemented in your custom attribute.

public class PointAuthorizeAttribute : AuthorizeAttribute
{
    public int PointsRequired { get; set; }

    protected override bool AuthorizeCore( HttpContextBase httpContext )
    {
         if (base.AuthorizeCore( httpContext ))
         {
             var name = httpContext.User.Identity.Name;
             using (var db = new SomeDataContext())
             {
                 var userPoints = db.Users
                                    .Where( u => u.UserName == name )
                                    .Select( u => u.Points )
                                    .SingleOrDefault();
             }
             return (userPoints >= PointsRequired);
         }
         return false;
    }
}

Used as

[PointAuthorize( PointsRequired = 50 )]
public ActionResult Comment( string comment )
{
}

You may want to customize it further so that failing a points requirement redirects to an error message rather than to the login page. In this case you'd have to override the OnAuthorization method as well and, perhaps, determine there if the user's point level is too small and then replace the result on the AuthorizationContext with your error view.

tvanfosson
+1 That's outstanding, thank you so much. You have no idea how much work you've just saved me. Next time I'm in Iowa, I'm gonna look you up and buy you a beer or two.
BobTheBuilder
I wish I could up-vote you more than once for that.
BobTheBuilder
Can you daisy-chain Authorization providers in an OR fashion? Where I have multiple providers such that you've immediately got permission if you're a site admin - thus not requiring any points, or should that be coded right into the custom authorization provider?
BobTheBuilder
You can have multiple Authorization attributes. They would be applied in order, though, and would function as an AND not an OR. That is, you'd have to pass all of them before you'd be allowed to execute the action. You could, however, structure the code differently so that your custom attribute implements an OR.
tvanfosson
That's good to know - so if I wanted to authorize based on whether or not a user is an admin OR has at least 500 points, then it would have to be done by my custom authorization attribute. That's good to know, thank you.
BobTheBuilder