views:

168

answers:

3

We know that authorization's stuff is a cross cutting concern, and we do anything we could to avoid merge business logic in our views.

But I still not find an elegant way to filter UI components (e.g. widgets, form elements, tables, etc) using the current user roles without contaminate the view with business logic. same applies for model binding.


Example

Form: Product Creation

Fields:

  • Name
  • Price
  • Discount

Roles:

  • Role Administrator

    • Is allowed to see and modify the Name field
    • Is allowed to see and modify the Price field
    • Is allowed to see and modify the Discount
  • Role Administrator assistant

    • Is allowed to see and modify the Name
    • Is allowed to see and modify the Price

Fields shown in each role are different, also model binding needs to ignore the discount field for 'Administrator assistant' role.

How would you do it?

+1  A: 

On way I could think to do this is create your own versions of the input extension methods. For example instead of TextBox you could create TextBoxRoles and define it like this:

public static MvcHtmlString TextBoxRoles(
    this HtmlHelper htmlHelper,
    string name,
    string RolesEdit,
    string RolesView
)

Then in code it would look like this:

<%= Html.TextBoxRoles("Price", "Administrator","Administrator,Assistant") %>

Then your implementation of TextBoxRoles would check the roles of the current user via User.IsInRole() to determine what should appear on the page.

Of course you would have to do this for every input extension method you use.

Keltex
Hi Keltex, Good workaroud +1!, nonetheless, using this approach you would still have to define the authorization roles in your views : |. I wonder if we could move all this logic to other layer. what do you think?Thank you again Keltex! : D
SDReyes
+1  A: 

What about something like LinFu, an AOP framework? If it's crosscutting, then declare it is so and treat it as such.

Scott Hanselman
Hi Scott, AOP looks like a very nice approach +1, thank you!. you mean, something like intercepting the rendering methods from helpers and add the authorization logic?
SDReyes
+1  A: 

Since you already have both the current user and access to the authorization provider in your controllers this is an ideal responsibility for them. Using a naive implementation you might pass a collection of widgets to your view after you filtered which widgets the current user has access to. In the case of your form field, things might get hairy when you consider client side validation.

The binding part would be the most straight forward of all, having a custom binder for these special cases will do the trick specially well since it will have access to the controller context and you can grab the current user from there and bind the values according to your role definitions.

JoseMarmolejos
Hi Jose, in the MVC context, I agree with you on putting the `UI` and `ModelBinding` logic on the controllers. (they have access to all the components we need, besides the custom ModelBinders already exist for these cases). Nice approach +1
SDReyes