从webapi2控制器返回403

时间:2015-09-04 21:41:01

标签: c# asp.net-web-api2

我的API有以下路线

GET:api / departments

获取:api / departments / {departmentID} / employees

第二个路线映射到以下控制器操作

public IEnumerable<Employee> Get(int departmentID)
{
  return GetEmployees(departmentID);
}

可以使用不存在的departmentID或用户没有访问权限来调用此路由。发生这种情况时,处理它的正确方法是什么?目前,我已经修改了我的控制器动作以返回403,如下所示

public HttpResponseMessage Get(int departmentID)
{
  var isDepartmentValid = CheckIfDepartmentIsAccessible(username, departmentID);
  if(!isDepartmentValid)
  {
    return Request.CreateResponse(HttpStatusCode.Forbidden);
  }

   Request.CreateResponse(HttpStatusCode.OK, GetEmployees(departmentID));
}

这是正确的方法吗?似乎方法签名的更改使得理解从控制器操作返回的内容类型变得更加困难。有没有办法让方法签名保持不变但仍然需要返回403?

3 个答案:

答案 0 :(得分:7)

要添加Rob Davis的答案,我建议您这样做,这样您就不需要更改方法的签名,并且返回的响应对客户端更有意义:

public IEnumerable<Employee> Get(int departmentID)
{
   try
   {
      return GetEmployees(departmentID);
   }
   catch(Exception ex) //assuming invalid dept or unauthorized throw Argument & Security Exceptions respectively
   {
        if(ex is SecurityException)
            throw new HttpResponseException(HttpStatusCode.Forbidden);
        else if(ex is ArgumentException)
            throw new HttpResponseException(HttpStatusCode.NotFound);
        else
             //handle or throw actual unhandled exception
    }
}

这假设您正在使用例外,但显然可以进行任何其他类型的检查以查看该部门是否存在或者是否具有访问权限。然后返回正确的响应。由于这是一个WebAPI,性能损失可以忽略不计,因为您最大的瓶颈很可能就是网络本身。

答案 1 :(得分:3)

您可以执行以下操作:

public IEnumerable<Employee> Get(int departmentID)
{
    var isDepartmentValid = CheckIfDepartmentIsAccessible(username, departmentID);
    if (!isDepartmentValid)
    {
        throw new HttpResponseException(HttpStatusCode.Forbidden);
    }

    return Request.CreateResponse(HttpStatusCode.OK, GetEmployees(departmentID));
}

答案 2 :(得分:0)

对我来说,放置各种身份验证/授权的最佳位置可能是OWIN中间件或一些授权操作过滤器;但取决于您的要求,因为如果您没有任何需要auth的路由,我可能会保留解决方案,并在控制器操作本身内进行检查。