1
votes

Is it possible to set authorization on a specific field in MVC 3?

My initial thought (and MSDN research) indicates that the [Authorize] tag is only for controller level actions (create,edit,index,etc). I can do this on the controller action:

[Authorize(Roles = "RoleA,RoleB")]
   public ActionResult Create()
    {            
        return View(new Tracking());
    } 

The scenario is that two roles (RoleA and RoleB) can access the 'Edit' controller. But only RoleA can change the first field. The other role (B) can only view the field.

I would like to do something like this on a specific field:

[Required]
[Range(1, 99)]
[Authorize(Roles = "RoleA")]
public int Sequence { get; set; }

UPDATE1:

A little more research down the StackOverflow rabbit roles reveals that I need to use partial views.

So in my view I add this code:

<div>
    @if (Context.User.IsInRole("RoleA"))
    {
        @Html.Partial("_SequenceEdit")
    }
    else
    {
       @Html.Partial("_SequenceView")
    }

</div>

So if the user is RoleA they get a partial view that allows editing of the 'sequence' field. Otherwise they get a view only of the 'sequence' field.

My view only partial view looks like this:

<div class="editor-label">
        @Html.LabelFor(model => model.Sequence)
    </div>
    <div class="editor-field">
        @Html.DisplayFor(model => model.Sequence)
        @Html.HiddenFor(model => model.Sequence)
        @Html.ValidationMessageFor(model => model.Sequence)
    </div>
1
Sorry, but what do you mean an MVC 3 field? Do you mean setting [Authorize] on a specific action? Or some local variable (a field) that you don't want RoleB to be able to modify? - mfanto
@JamieDixon - I'm not sure where to try and put it. I'm guessing it might go in the controller but it is the view/model that are field specific. - John M
@mfanto - added some more detailed. - John M
How is the value supposed to be changed? Is there a corresponding input field in the view? Is this field visible for all roles or only for RoleA? Also how do you know that the user actually changed the value? Change compared to what? - Darin Dimitrov

1 Answers

1
votes

I see that you've already figured out how to modify the view in order to not show a text box to users in Role B. But you should also do server-side validation to make sure only users in Role A can edit the field.

[Authorize(Roles = "RoleA,RoleB")]
[HttpPost]
public ActionResult Edit(int trackingID, Tracking newTrackingObject)
{
    // grab the current version of the tracking object from your data repo
    var oldTrackingObject = trackingRepo.GetByID(trackingID);

    // check if the user is in role A and edit the sequence number
    if(Context.User.IsInRole("RoleA"))
        oldTrackingObject.Sequence = newTrackingObject.Sequence;

    // continue processing the new tracking object

    // after all processing is done, persist the edited tracking object back to the repo
    trackingRepo.Update(oldTrackingObject);
    trackingRepo.SaveChanges();
}

This will prevent users in Role B from changing the sequence field by manually editing the hidden form field (eg. with FireBug or a similar tool.)