我可以爲您提供另一種請求授權方法。 MVC是一個核心原則的狀態機。狀態機有動作,觸發器和警衛。 MVC中已經存在這樣一個'警衛',目的是攔截控制器操作並檢查用戶權限。這是AuthorizeAttribute。該課程實施IAuthorizationFilter。另一方面是授權和身份驗證應在他們到達您的服務之前進行。我的意思到底是有兩種類型的授權:
- 動作授權和
- 數據授權。
您可以使用AuthorizeAttribute或您的自定義屬性實現IAuthorizationFilter + FilterAttribute來實現第一種類型的授權。下面是一個例如實現了SPA(單頁應用)這樣的屬性,與Ajax請求的工作原理:
屬性:
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = false)]
public class LoggedOrAuthorizedAttribute : AuthorizeAttribute
{
public override void OnAuthorization(AuthorizationContext filterContext)
{
base.OnAuthorization(filterContext);
CheckIfUserIsAuthenticated(filterContext);
}
private void CheckIfUserIsAuthenticated(AuthorizationContext filterContext)
{
// If Result is null, we’re OK: the user is authenticated and authorized.
if (filterContext.Result == null)
return;
// If here, you’re getting an HTTP 401 status code. In particular,
// filterContext.Result is of HttpUnauthorizedResult type. Check Ajax here.
// User is logged in but this operation is not allowed
if (filterContext.HttpContext.User.Identity.IsAuthenticated && filterContext.HttpContext.Request.IsAjaxRequest())
{
//filterContext.HttpContext.Response.StatusCode = 401;
JsonNetResult jsonNetResult = new JsonNetResult();
jsonNetResult.Data = JsonUtils.CreateJsonResponse(ResponseMessageType.info, "msgOperationForbiddenYouAreNotInRole");
filterContext.Result = jsonNetResult;
//filterContext.HttpContext.Response.End();
}
}
}
如果使用純MVC有一個例子執行here。 用法:
在你的控制器
[LoggedOrAuthorized(Roles = Model.Security.Roles.MyEntity.Create)]
public ActionResult CreateMyEntity(MyEntityDto myEntityDto)
{
...
}
您可以在每個控制器的行動應用此並達到塊控制器甚至在用戶。
您可以通過Castle Windsor在您的過濾器內提供記錄儀和其他'管道'來記錄事件。
一個非常好的和重要的鏈接和評論可在this答案類似的問題。這些鏈接也爲正確實施提供了很好的指導。
其他類型的授權 - 數據訪問授權可以在服務或控制器中處理。我個人更喜歡儘快處理各種授權。
一般做法是不向用戶顯示他未授權查看或執行命令的任何數據或操作。當然,你必須仔細檢查,因爲用戶可以修改POST和GET請求。
您可以通過傳遞用戶ID和實體ID來實現IDataAccessService和控制數據訪問的簡單接口。
重要的是,當用戶沒有被授權時,你不應該拋出異常,因爲這根本就不是例外。異常意味着您的程序處於意外狀態,禁止其正常執行。當用戶沒有被授權時,這並不意外 - 這是非常好的預期。這就是爲什麼在示例實現中返回消息而不是異常。
另一個微妙之處在於,.NET框架對「異常」的處理方式不同,它們花費的資源也更多。這意味着您的網站將非常容易受到DDOS中斷的影響,甚至可能無法執行。一般規則是,如果你通過例外來控制預期的程序流程,那麼你沒有做好 - 重新設計就是治癒。
我希望這會指導您在場景中正確實施。
請提供您想要達到的授權類型和您手邊的參數,以便我可以建議更具體的實施。
你能解釋一下你想達到什麼嗎?我的意思是需要什麼。有一個真正的機會,有一種不同的設計方法可以更好地滿足您的要求。我這樣說是因爲你試圖通過攔截器實現間接。如果你想要純粹的間接尋址,你可以在typeFactory中調用適當的控制器方法,然後檢查這些混雜的參數。 – 2015-04-04 07:38:46
我想攔截一個服務調用,我正在查看它的'ResponseCode',並且'ResponseCode'是UsrNotAuth,然後在Mvc層上拋出一個unathorized異常。如果你在應用程序服務層拋出一個觀點,它只能停留在那裏。我想通知Mvc層這個例外。所以我想清除用戶會話(Http會話)。所以我寫了一個共享控制器的操作方法,我想攔截服務調用並在這裏調用控制器操作。那麼我該如何處理這個問題呢? – 2015-04-04 20:37:41