Question

I'm creating an ASP.Net MVC 5 application. In my website, 3 different types of users exist.

  • Admin
  • Normal users
  • Restaurants

Each of these users have its own capabilities and access rights. Meaning, the view for each of them should be different.

I have created the models for both of the normal and restaurant. I was wondering how I can modify my existing structure to support this functionality.

public class User : IUser
{
    public User()
        : this(String.Empty)
    {
    }

    public User(string userName)
    {
        UserName = userName;
        Id = Guid.NewGuid().ToString();
    }

    [Key]
    public string Id { get; set; }

    [Required]
    public string UserName { get; set; }

    [Required]
    public string FirstName { get; set; }

    [Required]
    public string LastName { get; set; }

    public string Phone { get; set; }
    public string MobilePhone { get; set; }

    [Required]
    [DataType(DataType.EmailAddress)]
    public string Email { get; set; }

    public virtual IList<UserAddress> Addresses { get; set; }
}

public class Restaurant
{
    [Key]
    public int ID { get; set; }

    [Required]
    public string Name { get; set; }

    public virtual IList<RestaurantAddress> Addresses { get; set; }

    public virtual IList<RestaurantFood> Menu { get; set; }

    public virtual IList<Review> Reviews { get; set; }

    [DataType(DataType.Url)]
    public string Website { get; set; }

    [DataType(DataType.PhoneNumber)]
    public string Phone { get; set; }

    [DataType(DataType.PhoneNumber)]
    public string Fax { get; set; }

    [DataType(DataType.EmailAddress)]
    public string Email { get; set; }

    public int Seats { get; set; }

    public double AverageRating { get; set; }
    public double AveragePrice { get; set; }
}
Was it helpful?

Solution

I'm not sure that I've got your Q correctly, But if you are using internet application template, you can simply manage access controls of your app using role management.

First of all, add some roles to the webpages_Roles table of your db.

Then, simply add users to those roles:

Role.AddUserToRole("role1");

Now, for filtering contents, you just need to do two jobs:

1) filter controller request to appropriate roles by use of [Authorize] attrib:

[Authorize(Roles = "role1, role2, ...")]

2) Render the appropriate content to the relative user. First retrieve the roles of the current user:

var roles = Roles.GetRolesForUser(User.Identity.Name);

Then, according to his/her roles, Render contents for him/her:

bool hasRole1 = roles.Contain("role1") | roles.Contain("admin");
// ...
@if (hasRole1)
{
    // Show content for role1 users...
}

OTHER TIPS

Authorization can be done based on user roles.

While creating authorization, we always keep in mind that it should dynamic. New user group will come having different permissions. So what I am suggesting is to have the information in a database.

For eg

User Group Admin Normal Users Resturants

Roles All Privileage Basic Privilage Intermediate Privileage

You need to use action filters to obtain this. http://msdn.microsoft.com/en-us/library/dd410209(v=vs.100).aspx

Next we need to assign privilages to each roles

All Privileage - addUser, addResturant, etc (you can use friendly names for administrative purpose. It can be displayed in UI, but we need to store controller name and action name.In case of addUser , friendly name will be Add User and we store like below

ActionsTable (actionId, friendName, Controller, Action)
1 -Add User - Users - Add 

RolesActionMapTable (roleId, actionID)
1-1

RolesTable (RoleId,Role Name,Desc)
1-AllPrivileage

GroupsTable (GroupId, GroupName)
1-Admin

GroupRoleMap (groupId, roleID)
1-1

Create a custom Autorize attriute by inheriting authorize attribute and apply it as filter for all methods. There is an overloaded function, and you can check the user is allowed to access that action there. Hence you can block the unauthorized access.

EDIT

From the route data we can identify the controller and action, so we can query db using the userID, controller and action that whether is allowed or you can get the users group and check that it was included the permission to access this

EDIT 2

public class CustomAuthorizeAttribute: AuthorizeAttribute
{
   protected virtual bool AuthorizeCore(
    HttpContextBase httpContext)
 {
   // 1.Httpcontext can gives you the controller and action
   // 2. retrive the group of user and check the user is allowed to execute this action
   // 3. if allowed, then return true else return false.
   // 4. You can redirect to another page saying you are not allowed to access this action
  }
)
}


//In controller
public class EmployeeController: Controller {

 [CustomAuthorize]
  public Create()
   {
   }

}

Hope this helps

To achieve this in a scalable fashion with granular control you need permission-based authorization. You can try something like ASP Security Kit. ASP Security Kit is built from ground up to build systems like this.

Edit: This is how it can work:

  1. You define a unique permission code with every action method. For example, CreateRestaurant, ReserveRestaurant
  2. These permission codes are stored in a master Permissions table in the database.
  3. You can create a seperate roles table and associate permissions appropriately. However, ASP Security Kit introduces a new concept of implied permissions so you don't need role as a separate construct; you just create a higher-level permission, for example, 'RestaurantOwner', and make other permissions implied by it.
  4. There's a UserPermit table which associates permissions with users. For a specific type of users, E.G. restaurant owner, you will assign applicable permissions as the user is created.
  5. As user logs in, you load his permissions in the memory.
  6. You need a mechanism by which each controller's action is executed only if user possesses the unique permission code associated with that action. If user does not, you'll redirect him to a default page with message stating "unauthorized action"
  7. You can also look into the user permissions loaded to display or hide menu options.

ASP Security Kit does most of the above for you; for example, it can automatically infer permission code for authorization so you don't have to hard code it. In addition, you need resource checks so that different users and restaurant owners do not fiddle with each other data.

Disclosure: I'm the creator of ASP Security Kit.

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