开发者

MVC2 C# Restricting Access to a view based on an ID

I have two tables one with jobs one with managers, when a job ID is passed to the view 'Detail' the details of that job are accessible.

Job_id  Job_Title       Manager_id
23      Chimney Sweep   65
24      Rat Catcher     84

Managers    Email
65          arthur@work.com
66          fred@work.com

I want to restrict access to the view based on the manager_email - so for example if we're on http://jobsite/jobs/Detail/23 then only arthur can access the view.. will be using AD to 开发者_开发问答pick out the user's email..

Any pointers would be much appreciated!


You could write a custom model binder:

public class JobModelBinder : DefaultModelBinder
{
    public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
    {
        // fetch the job id from the request
        var jobId = controllerContext.RouteData.Values["id"];

        // fetch the currently connected username
        string user = controllerContext.HttpContext.User.Identity.Name;

        // Remark: You might need an additional step here
        // to query AD and fetch the email

        // Given the job id and the currently connected user, try 
        // to fetch the corresponding job
        Job job = FetchJob(jobId, user);

        if (job == null)
        {
            // We didn't find any job that corresponds to
            // the currently connected user
            // => we throw
            throw new HttpException(403, "Forbidden");
        }
        return job;
    }

    private Job FetchJob(int jobId, string user)
    {
        throw new NotImplementedException();
    }
}

and then have your controller:

public class JobsController : Controller
{
    [Authorize]
    public ActionResult Show([ModelBinder(typeof(JobModelBinder))]Job job)
    {
        return View(job);
    }
}

The custom model binder could also be registered in Application_Start:

protected void Application_Start()
{
    ...
    ModelBinders.Binders.Add(typeof(Job), new JobModelBinder());
}

which would simplify your controller action:

public class JobsController : Controller
{
    [Authorize]
    public ActionResult Show(Job job)
    {
        // If we get to that point it means that the
        // currently connected user has the necessary
        // permission to consult this view. The custom
        // model binder would have populated the Job model
        // and we can safely pass it to the view for display
        return View(job);
    }
}

Another advantage of this approach is that you could inject dependencies into the constructor of your custom model binder. It might require those dependencies when tries to communicate with the AD and the database.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜