最近在強化權限控管,發現在Area找不到Controller的時候,竟然會去其他的Area找有沒有符合名稱的Controller(如何切換 Area 的 Web Api 路由)
對規劃的權限區分來說,這一個非常嚴重的問題
舉個例子:
(角色=>Area)
人員管理者=>People
薪資管理者=>Salary
王小明有人員管理者這個角色,所以他可以使用People裡的所有Controller, 碰巧王小明知道了Salary的某隻Api路徑可以取得全公司員工的薪資(api/Salary/AllPeople), 就權限管理機制,王小明沒有Salary的Area權限,所以被判定為無權限(401)。
到這邊都很沒問題,一切都很美好...
偏偏王小明很有求知的精神,想說只要是People就會被放行,那如果把Salary改成People不知道可不可以?
於是原本的路徑(api/Salary/AllPeople)變成了(api/People/AllPeople)。
這時候權限機制判斷王小明是人員管理者,可以訪問People的Area,所以放行讓他通過, 殊不知在People下沒有AllPeople的Controller,但對權限機制來說並不重要,有沒有是ControllerSelector的問題。
這時候AreaHttpControllerSelector出馬了,經過一連串的檢查,發現People下沒有AllPeople的Controller,沒辦法走下去,那就交給老爸(DefaultHttpControllerSelector)去處理吧。
而老爸是不管這些Area的,只要符合ControllerName就好,所以找到了Salary的AllPeople,然後就跟小弟(ApiControllerActionSelector)說,從Salary的AllPeople找符合的Action來執行吧。
接著就會發現王小明引發
這樣是不行的,如果Route有接到area的話,就只能從指定的Area下找Controller,沒找到就丟錯誤出去,所以修改一下AreaHttpControllerSelector:
...略... private HttpControllerDescriptor GetApiController(HttpRequestMessage request) { var controllerName = base.GetControllerName(request); var areaName = GetAreaName(request); if (string.IsNullOrEmpty(areaName)) { return null; } var type = GetControllerTypeByArea(areaName, controllerName); if (type == null) { //原本回傳null是為了向老爸求救,今天兒子要獨當一面了 //return null; throw new HttpResponseException(request.CreateErrorResponse(HttpStatusCode.NotFound, string.Format("No route providing a controller name was found to match request URI \"{0}\"", new object[] { request.RequestUri }))); } return new HttpControllerDescriptor(_configuration, controllerName, type); }
參考:
如何切換 Area 的 Web Api 路由
DefaultHttpControllerSelector.cs Source Code
ApiControllerActionSelector.cs Source Code
沒有留言 :
張貼留言