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.
精彩评论