title: How to protect a Web API from data retrieval not from the resource owner
body: <p>I have an asp.net web api.</p>
  
  <p>I want to own selfhost my Web API later on an azure website.</p>
  
  <p>A logged in user could do this in the browser <code>/api/bankaccounts/3</code></p>
  
  <p>to get all <strong>details</strong> about <code>bank account number 3</code>.</p>
  
  <p>But the logged in user is not the owner of <code>bank account number 3</code>.</p>
  
  <p>How do I have to design my Controllers and the services behind that the logged </p>
  
  <p>in user can only retrieve/modify his own resources in the database?</p>
  
  <p>UPDATE</p>
  
  <p>After I created a:</p>
  
  <pre><code>public class UserActionsAuthorizationFilter : AuthorizationFilterAttribute
  {
     public override void OnAuthorization(HttpActionContext actionContext)
     {
         if (actionContext != null)
         { 
             bool canUserExecuteAction = IsResourceOwner(actionContext);
             // stop propagation  
         }
     }
  
  private bool IsResourceOwner(HttpActionContext actionContext)
          {
              var principal = (ClaimsPrincipal)Thread.CurrentPrincipal; 
              var userIdAuthenticated = Convert.ToInt32(principal.Claims.Single(c =&gt; c.Type == ClaimTypes.Sid).Value);
  
              int targetId = Convert.ToInt32(actionContext.Request.GetRouteData().Values["Id"]);
              var requstScope = actionContext.ControllerContext.Request.GetDependencyScope();
              var service = (ISchoolyearService)requstScope.GetService(typeof(ISchoolyearService));
              bool canUserExecuteAction = service.HasUserPermission(userIdAuthenticated, targetId);
              return canUserExecuteAction;
          }
  }
  </code></pre>
  
  <p>The question is now that the IsResouceOwner is hardcoded to a certain service => SchoolyearService thus bound to the Schoolyear SQL table</p>
  
  <p>I need to keep the IsResourceOwner method generically working for all sql tables having a field UserId/UserEmail.</p>
  
  <p>The problem is  -and I really think nobody is doing that this way- that I have to map each Resource owner check to the correct Sql table in the HasUserPermission method.</p>
  
  <p>How should that mapping look like?</p>
  
  <p>Check Controller name "SchoolyearController" thus the table to check is the "schoolyear" table? thats ridiculous.</p>
  
  <p>This custom attribute "UserActionsAuthorizationFilter" will be on every "Data" controller.</p>
  
  <p>Whatever controller url the user triggers to fetch data, before I have to check wether he is resource owner.</p>
  
  <p>I guess I can not decide this inside a filter.</p>
  
  <p>I have to let the data retrieval/modification go through the controller and do the ResourceOwner check inside maybe in a Repository just before the data retrieval is done.</p>
  
  <p>What do you think of this:</p>
  
  <p><strong>API</strong></p>
  
  <pre><code>public async Task&lt;IHttpActionResult&gt; Delete(int id)
  {
     var result = await service.Delete(id, User.Identity.UserId);
      if (result == 0)
          return NotFound();
      return Ok();
  }
  </code></pre>
  
  <p><strong>REPO</strong></p>
  
  <pre><code>    public async Task&lt;int&gt; Delete(int id, int userId)
      {
          var schoolyerToDelete = await context.Schoolyears.SingleOrDefaultAsync(s =&gt; s.Id == id &amp;&amp; s.UserId == userId); 
  
  // If schoolyearToDelete is null nothing is removed, thus the affected rows are ZERO.
          context.Schoolyears.Remove(schoolyerToDelete);
         return await context.SaveChangesAsync();
      }
  </code></pre>
  
  <ul>
  <li>For the Get Method nothing is returned for the wrong UserId</li>
  <li>For the Create Method: no problem, everyone should be able to create a resource if logged in.</li>
  <li>For the Update Method: same as Delete method the schoolyear is retrieved by id and UserId.</li>
  </ul>
  
  <p>Generally spoken every method in my Repository should consider the UserId in the CRUD action.</p>
  
  <p>What do you think?</p>