Question

I want to build a Registration system where, while adding an user u can select the type of role you can give to him/her. And depending upon the role he/she it would be decided whether certain action in controller can be accessed or not.

For example, let's say there are two roles, admin and developer. And having something like mentioned below would only allow user with roles as admin to acces following action.

[Authorize(Roles = "admin"]
public ActionResult CreateUser()
{
   return View();
}

As far as I know I have to implement my custom RoleProvider or IPrincipal? I tried to find some example on that but didn't quite get what i'm exactly looking for. Here is how my RegisterModel currently looks like

public class RegisterModel
    {
        [Key]
        public Guid Id;
        [Required]
        [Display(Name="First Name")]
        public string FirstName {get; set;}

        [Required]
        [Display(Name="Last Name")]
        public string LastName {get; set;}

        [Required]
        [Display(Name="Email Id")]
        [DataType(DataType.EmailAddress)]
        public string EmailId {get; set;}

        [Required]
        [Display(Name = "User name")]
        public string UserName { get; set; }

        [Required]
        [Display(Name = "Password")]
        [DataType(DataType.Password)]
        public string Password { get; set; }

        [Required]
        [Display(Name = "Confirm Password")]
        [DataType(DataType.Password)]
        public string ConfirmPassword { get; set; }

       [Required]
       [Display(Name = "Role")]
       public UserRole Role { get; set; }

    }



  public class UserRole
    {
        [Key]
        public int RoleId { get; set; }

        public string RoleName { get; set; }
    }

Thing is I want the role to be decided when adding a user and use the Custom Authorize attribute. Any article or blog that anyone knows that can solve my issue? Or any suggestions, how to do it?

Was it helpful?

Solution

Recently i implemented Role authorization without using Memberhip provider. Thought this might help you.I have a database table with UserName, Password and a Role and i needed to check the role against the database.

Below is my custom RoleFilter class.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace MvcApplicationrazor.Models.ActionFilters
{
    public class RoleFilter : ActionFilterAttribute
    {
        public override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            if (GetCurrentUserRole() != "Admin")// Check the Role Against the database Value
            {
                filterContext.Result = new RedirectResult("~/Redirect/NoPermission");
                return;
            }
        }
    }
}

Controller:

[RoleFilter]//Check the Role, if not allowed redirect to NoPermission view
public ActionResult Index()
{
   return View();
}

OTHER TIPS

MVC 4 uses some helper classes from WebMatrix to implement Security and Memberhip. You can read a very nice tutorial here: http://www.asp.net/web-pages/tutorials/security/16-adding-security-and-membership

If you don't have any special requirements, it's usually not worth it to come up with your own implementation of a Role Provider.

Good Luck!

EDIT: A QUICK TUTORIAL

The following is based on a Model class called "UserProfile" with a corresponding table named the same. This table has a column called "UserId" for the id and one called "UserName" for login. Of course it can have all the info you need, but these are the only ones needed by the WebSecurity to initialize the DB.

Step 1: the web.config. Put this in the system.web section. This instructs ASP.NET to use the two Simple providers for Role and Membership:

 <roleManager enabled="true" defaultProvider="simple">
     <providers>
         <clear/>
         <add name="simple" type="WebMatrix.WebData.SimpleRoleProvider, WebMatrix.WebData"/>
     </providers>
 </roleManager>
 <membership defaultProvider="simple">
     <providers>
         <clear/>
         <add name="simple" type="WebMatrix.WebData.SimpleMembershipProvider, WebMatrix.WebData"/>
     </providers>
 </membership>

Step 2: Application_Start. Add the initialization for your DB for roles and membership tables:

protected void Application_Start()
{
     try
     {
         // Initializes the DB, using the "DefaultConnection" connection string from the web.config,
         // the "UserProfile" table, the "UserId" as the column for the ID,
         // the "UserName" as the column for usernames and will create the tables if they don't exists.
         // Check the docs for this. Basically the table you specify
         // is a table that already exists and where you already save your user information.
         // WebSecurity will simply link this to its own security info.
         if (!WebSecurity.Initialized)
             WebSecurity.InitializeDatabaseConnection("DefaultConnection", "UserProfile", "UserId", "UserName", autoCreateTables: true);
     }
     catch (Exception ex)
     {
         throw new InvalidOperationException("Cannot init ASP.NET Simple Membership database", ex);
     }        
}

When the InitializeDatabaseConnection fires for the first time, it will create 4 tables:

webpages_Membership
webpages_OAuthMembership
webpages_Roles
webpages_UsersInRoles

Step 3: You can now use the Authorize attribute:

    [Authorize(Roles="Admin")]

Also, you will now have a lot of methods to create and login your users:

WebSecurity.CreateUserAndAccount(model.UserName, model.Password); // to create users. You can also pass extra properties as anonymous objects

WebSecurity.Login(model.UserName, model.Password, persistCookie: model.RememberMe); // for logins

WebSecurity.Logout();

WebSecurity.ChangePassword(User.Identity.Name, model.OldPassword, model.NewPassword);

// and so on...

I find this approach to be a lot more flexible (and quicker) than rolling your own implementation.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top