0

我實現協作型Web畫廊,和我有每個用戶的幾個角色:在ASP.NET MVC中強制安全檢查?

  1. 聯繫
  2. 刪除圖像
  3. DeleteOwnImage
  4. 等。

對於任何控制器我們可以將[Authorize]標籤應用到他們以及我們想要允許的角色上,對嗎? Admin/DeleteImage是好的,因爲這兩個是全局的;但我的問題是,像DeleteOwnImage是一種情境的,以確定它是否有效,我們需要:

  1. 知道它是想什麼形象(從申請)刪除
  2. 檢索的所有者該圖像(從服務或資料庫)
  3. 比較當前用戶=該業主

顯然[授權]是不夠的,這樣做的,但有可能做到這一點自定義ActionFilters?任何提示?

回答

1

您可以在ActionFilter中輕鬆地添加這樣的內容,只需添加一個操作過濾器,並使用OnActionExecuting實現。

儘管取決於您的數據庫架構,但可以在數據庫級別使用您的查詢來實現。當所有者等於接收到的收件人ID時,您可以刪除。 (我的意思是,在行動方法,而不是在過濾器)

編輯: 如果您使用某種IOC容器的存儲庫,你應該四處尋找在MVC3新的IOC功能(如果你'重新使用MVC3)將依賴注入到您的動作過濾器中。

http://bradwilson.typepad.com/blog/2010/07/service-location-pt4-filters.html

EDIT2:

BTW,我自己真的不喜歡在ActionFilters做得太多業務邏輯,尤其是涉及到數據庫的調用。甚至更多的時候,它是一個非常具體的東西,將用於一個動作。

+0

也Ninject-mvc3可以做注射。我認爲你是對的,這已經進入商業邏輯。 – xandy 2011-03-05 02:42:34

4

是的,這可以通過自定義操作過濾器來實現。您可以從AuthorizeAttribute延伸,最基本的實施是這樣的:

public class OwnImageAuthorizeAttribute : AuthorizeAttribute { 
    public string ImageIdKey { get; set; } 

    protected override bool AuthorizeCore(HttpContextBase httpContext) { 
    bool authorized = false; 
    // Get the current user 
    var currentUser = ...; 
    // Get the image ID, whether it is in the route or querystring 
    int imageId 
    if(int.TryParse(httpContext.RouteData.Values(ImageIdKey), out imageId)) { 
     // From querystring: httpContext.Request.Querystring[ImageIdKey] 
     // Authorize the user 
     authorized = YourMethodToCheckIfUserIsOwner(currentUser, imageId); 
    } 

    return authorized; 
} 

然後,裝點您的方法:

[OwnImageAuthorize(ImageIdKey = "imageId")] 
public ActionResult MyAction() { } 

你可以找到一些更細節here

+0

如果您開始爲每次需要更新數據庫中的某些數據庫事務的數據庫執行此操作,您是否認爲這種授權方法可能會失控(請閱讀:處理非常特定問題的大量小類)? – Linkgoron 2011-03-05 02:07:10

+0

我擔心的一件事是屬性本身相當依賴於輸入routedata。在這個動作中,「imageId」被命名爲imageId,但在其他路由中它可能變成「Id」。但我認爲沒有辦法擺脫這種情況,對吧? – xandy 2011-03-05 02:39:40

+0

@xandy,看我的編輯,應該有所幫助。 – 2011-03-05 03:17:31