2009-11-05 203 views
0

我用這段代碼看到的問題是,它將被重用很多;任何被認證用戶(除了網站管理員)編輯/創建的內容都只能訪問他們的「工作室」對象。ASP.NET MVC - 授權重構

我的問題給大家;你將如何重新考慮這一點,以便服務層可以從客戶的知識中抽象出來。我打算稍後在獨立桌面應用程序中重用服務層。

請闡明我錯誤的方式!我非常感謝。

AuthorizeOwnerAttribute.cs(AuthorizeAttribute)

protected override bool AuthorizeCore(HttpContextBase httpContext) 
{ 
    // Get the authentication cookie 
    string cookieName = FormsAuthentication.FormsCookieName; 
    HttpCookie authCookie = httpContext.Request.Cookies[cookieName]; 

    // If the cookie can't be found, don't issue the ticket 
    if (authCookie == null) return false; 

    // Get the authentication ticket and rebuild the principal & identity 
    FormsAuthenticationTicket authTicket = FormsAuthentication.Decrypt(authCookie.Value); 
    string[] userData = authTicket.UserData.Split(new[] { '|' }); 

    int userId = Int32.Parse(userData[0]); 
    int studioID = Int32.Parse(userData[1]); 
    GenericIdentity userIdentity = new GenericIdentity(authTicket.Name); 
    WebPrincipal userPrincipal = new WebPrincipal(userIdentity, userId, studioID); 
    httpContext.User = userPrincipal; 

    return true; 
} 

內部我的 「用戶」 控制器此屬性附加到需要一個所有者的任何方法的現在

[AuthorizeOwner] 
    public ActionResult Edit(int Id) 
    { 
     IUser user = userService.GetById(HttpContext.User, Id); 
     return View(user); 
    } 

,在我的服務層是我正在檢查傳入的IPrincipal是否有權訪問請求的對象。 這是它變得臭:

UserService.cs

public IUser GetById(IPrincipal authUser, int id) 
    { 
     if (authUser == null) throw new ArgumentException("user"); 

     WebPrincipal webPrincipal = authUser as WebPrincipal; 
     if (webPrincipal == null) throw new AuthenticationException("User is not logged in"); 

     IUser user = repository.GetByID(id).FirstOrDefault(); 
     if (user != null) 
     { 
      if (user.StudioID != webPrincipal.StudioID) throw new AuthenticationException("User does not have ownership of this object"); 
      return user; 
     } 

     throw new ArgumentException("Couldn't find a user by the id specified", "id"); 
    } 

回答

2

我不知道我會被存儲在cookie中的實際的ID,這有點太暴露。我更傾向於使用會話哈希來存儲數據,從而保持它在服務器上,而不是暴露。

我也會使用Model(通過傳遞userID)來確定要返回哪些對象,即那些具有匹配studioID的對象。這樣,如果你的控制器沒有權限訪問任何東西,那麼你只需要調用「GetObjects(int id)」,那麼你就會得到一個空的或空的集合。這讓我感覺更清潔。

+0

你能詳細講解會話哈希部分嗎? – 2009-11-05 15:41:23

+0

看看這裏:http://msdn.microsoft.com/en-us/library/ms178581.aspx – Lazarus 2009-11-05 16:13:13

+0

你能給我一個使用會話哈希的例子嗎?我不確定我是否關注你。哪裏來玩? – 2009-11-05 17:02:29