Search code examples
asp.net-mvcpermissionsopenidmembershipdotnetopenauth

How to authorize an OpenID user on MVC Controller


I'm looking at the [Authorize(Roles = "DefaultUser")] available in MVC, but I can't seem to figure out if I can use it with DotNetOpenAuth.

I'm using OpenID as my sole membership provider, but I have a few generic items in a UserProfile table. I don't want anyone except the appropriate user to be able to access the edit controller.

EXAMPLE:
UserID 2 should not be able to access /Users/Edit/1, but they CAN access /Users/Edit/2


Solution

  • Edit/Rewrite for clearer understanding

    public class AdvancedAuthorizeAttribute : AuthorizeAttribute
        {
                public string RouteDataValue
                {
                    get;
                    set;
                }
    
                protected override bool AuthorizeCore(HttpContextBase httpContext)
                {
                    if(base.AuthorizeCore(httpContext))
                    {
                        MvcHandler mvcHandler = httpContext.CurrentHandler as MvcHandler;
                        if (mvcHandler != null)
                        {
                            var paramValue = mvcHandler.RequestContext.RouteData.Values[RouteDataValue];
                            if (paramValue != null)
                            {
                                // Inside this IF-statement is where you'll have to customize for your code.
    
                                //I use the default user from HttpContext
                                string UserPrincipalName = httpContext.User.Identity.Name;
                                // I use email as login name, and here I try to fetch a user from my repository with that email.
                                User userObject = new Repository<User>().GetOne(x => x.Email == UserPrincipalName);
                                // If I find a user, and that user's UserID is equal to the value in paramValue, it's Ok! Otherwise, not.
                                return (userObject != null && userObject.UserID.ToString() == paramValue.ToString());
                            }
                        }
                    }
                    return false;
                }
        }
    

    And then, using it:

    // Example usage (for instance from UserController)
    [AdvancedAuthorize(RouteDataValue="userID")]
    public ActionResult Edit(int userID)
    {
         // everything as normal
    }
    
    [AdvancedAuthorize(RouteDataValue="userEmail")]
    public ActionResult Delete(string userEmail)
    {
         // everything as normal
    }
    

    Of course, for it to work, userID and userEmail in the action examples need to be bound by the modelbinder (the parameters have to exist in the RouteData.Values) for it to work.