How to control access to forms fields on a ASP.Net

2019-07-08 05:56发布

问题:

Example

User "jtirado" is assigned role "HR-Assistant", can access route "mymvcapp/employeee/edit/1452" to edit employee (id:1452) data.

Being "HR-Assistant", this user can change employee telephone number and e-mail, can view employee salary but not edit the amount.

Telephone number, email, salary are dabatase fields and are represented/rendered by a "asp.net-mvc-control" or "HTML-control" on the View. So I want to restrict access to these controls based on user's role.

Previous experience

I've done this before for a classic 3-tier ASP.Net 3.5 web forms application, using a MasterPage, a BasePage class and a RoleBasedAccessControl database model.

MasterPage builds the options menu the user has access according to his assigned role.

BasePage class checks if the user has access to the required page, and if so, checks which controls (ex: DdlClientType, TxtLastName,ChkIsActive) the user can edit.

This way, I don't have to use if-then sentences to check permissions and, I can create as many roles as I want, giving them any permissions, without having to change any C# code.

I'm planning to use the same RoleBasedAccessControl database model for this new MVC app.

Problem

So my dubts are about how to implement the MasterPage and BasePage class using ASP.Net MVC 3 or if there's another way of achieving this, and if I should do it other way.

It seems to me that ViewMasterPage is the MVC-equivalent to Web-Forms-MasterPages. I've also heard about Razor layout pages.

Anyway, I suppose I should handle all of this in a Controller.

I will be using:

  1. ASP.NET MVC 3.0
  2. Razor

I've checked these posts:

asp.net mvc user permissions and views

Best Practices for controlling access to form fields

Best practices for control permissions?

ASP.NET MVC Master Pages

Implement secure ASP.NET MVC applications

But they don't fully fit my case.

回答1:

One issue with the Razor engine is that there is no "Controls" collection on a page, as there is in WebForms. Thus you wouldn't be able to iterate through all of the controls in a page and do something with them.

That said, you can still use a "Base View" idea by subclassing System.Web.Mvc.WebViewPage and/or System.Web.Mvc.WebViewPage<TModel> as outlined in a previous question. Likewise, inheriting from Controller will help for a base controller as well.

I'm not sure I have a concrete answer here, but one thing I've done is add custom attributes on my model properties indicating which roles can access them. Then I overload the built-in methods like @Html.TextBoxFor(), passing in the current user's roles. In the overload I check the roles argument against the attribute on the property.

In your case, attributes may not work, and instead you'll read the authorization from a database; same idea, just a different implementation.

Hope that gets you going in the right direction.



回答2:

It sounds like you could use a custom editor template, and have your logic in there.

In your Viewmodel, you can use attributes to determine which template will get used - either with UIHint, or by setting the DataType attribute and having your custom template for that.

Then your editor template can determine whether to render the edit or display value (or hide it entirely). Don't forget to enforce the same rules in your binders, or you open up the possibility of having users manipulate data that they should not have access to.