Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>The first thing to test is whether the LINQ query returned a Move. If it didn't it means that the user is trying to display a move that doesn't belong to him, because in your query you have a <code>.Where</code> clause which restricts to the current user moves only. </p> <p>Right now you're gonna get a NullReferenceException.</p> <p>So:</p> <pre><code>[Authorize] public ActionResult Details(int id) { MembershipUser currentUser = Membership.GetUser(); Guid currentUserId = (Guid)currentUser.ProviderUserKey; Move move = db.Moves.Where(m =&gt; m.UserId == currentUserId &amp;&amp; m.MoveId == id).FirstOrDefault(); if (!currentUser.IsApproved || move == null) { // the user is trying to display a move that doesn't belong to him =&gt; // redirect him or throw a 403 HTTP exception return RedirectToAction("Oops", new RouteValueDictionary(new { controller = "Account", action = "Oops", area = "", id = UrlParameter.Optional })); } // at this stage we can grant access to the user because we know // that he is authenticated, he is approved and that the move he is // trying to consult belongs to him return View(move); } </code></pre> <p>Obviously if you need to repeat this logic in many controller actions it is worth writing a custom Authorize attribute:</p> <pre><code>[EnsureUserAllowedToConsultMove] public ActionResult Details(Move move) { // at this stage we can grant access to the user because we know // that he is authenticated, he is approved and that the move he is // trying to consult belongs to him return View(move); } </code></pre> <p>And here's how this custom Authorize attribute might look like:</p> <pre><code>public class EnsureUserAllowedToConsultMoveAttribute : AuthorizeAttribute { protected override bool AuthorizeCore(HttpContextBase httpContext) { var authorized = base.AuthorizeCore(httpContext); if (!authorized) { return false; } if (!httpContext.Request.RequestContext.RouteData.Values.ContainsKey("id")) { return false; } var id = (string)httpContext.Request.RequestContext.RouteData.Values["id"]; var currentUser = Membership.GetUser(); var currentUserId = (Guid)currentUser.ProviderUserKey; return db.Moves.Any(m =&gt; m.UserId == currentUserId &amp;&amp; m.MoveId == id); } protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext) { var values = new RouteValueDictionary(new { controller = "account", action = "oops", area = "" }); filterContext.Result = new RedirectToRouteResult(values); } } </code></pre> <p>Now you have managed to separate the concerns and externalize the authorization logic into a custom authorization attribute. Your controller no longer needs to be polluted with such code.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload