2016-06-07 78 views
1

示例:在MVC(ASP)中的相同數據上實現多個角色

我們有兩種用戶類型。

  • SupplierUser
  • FactoryUser

他們用基本相同的數據,但一般FactoryUsers可以編輯更多的信息比SupplierUser兩個接口。

使用ASP.NET 4.5,我正在使用MVC實現所有這些。

一些總結的用例:(假設登錄)

FactoryUser:

  • 可編輯的郵件頁面,該頁面顯示供應商的最新公告。
  • 訂單確認頁面和訂單查看頁面。
  • 供應商編輯頁面(用於更新地址的多個供應商等)

SupplierUser: - 可以看到特定工廠的消息。 - 可以創建訂單,發送和查看。 - 可以編輯他們自己的信息

正如你所看到的,這只是許多具有不同權限的信息編輯。我的問題是,我應該在哪裏開始分色?

至於:

  1. 模型 - 我覺得這一個保持爲一個與數據庫
  2. 的ViewModels - 我寫的每個角色不同的看法?如果是這樣,2個文件/類?
  3. 控制器 - 相同,我可以編寫不同的功能嗎?類?如果是這樣,那麼[授權角色]有什麼意義,只是爲了防止未經授權的訪問&不打算分裂?
  4. 觀點 - 我是否嘗試對大多數部分使用相同的視圖,並且只是包含關於他們是否具有「編輯」按鈕的邏輯?
  5. 部分視圖 - 它們可以用於可能或不可能位於視圖上的「編輯」按鈕嗎?
  6. 查看佈局 - ?
  7. 過濾器 - 我可以做一些花哨的邏輯,並將所有內容放在完全2個不同的文件夾中(整個MVC),然後將其分割爲路由/授權級別
  8. 路由 - ?

在上面的每一個,我可以看到根據用戶類型拆分邏輯的可能性。但是,當然,我想以最簡單,最健全的方式來做到這一點。

是否有一些文件指定應該如何完成,或者是否有任何聰明的人在那裏做過這些事情,並遇到過所有問題?

感謝 (第一個問題!)

+1

{授權]只允許或不允許訪問動作/控制器。您可以在視圖中檢查用戶角色,並根據角色隱藏或顯示不同的操作, –

回答

2

的一種方式做,這是打造特色。例如View Orders, Create Order, Update Order, Delete Order

這些features將被分配到一個Role - 和角色可以被分配到一個User

所以DB會是這個樣子:

enter image description here

現在,當用戶登錄後,讀取分配給用戶的所有功能並將它們保存在會話中(創建SessionHandler類)。 UserDTO類

樣品 SessionHandler

public class SessionHandler 
{ 
    private const string SessionKey = "UserSession"; 

    public static UserDTO UserSession 
    { 
     get 
     { 
      return HttpContext.Current.Session[SessionKey] != null 
         ? (UserDTO)HttpContext.Current.Session[SessionKey] 
         : null; 
     } 
     set { HttpContext.Current.Session[SessionKey] = value; } 
    } 
} 

所以在你的控制器

public class UserDTO 
{ 
    public int UserId {get;set;} 
    public List<string> Features {get;set;} 
} 

// Login Function - You can call from Controller 
public UserDTO Login(string username, string password) 
{ 
var user = dbContext.Users.FirstOrDefault(s => s.Username == username && s.Password == password); 

if(user == null) return null; // login failed 

var model = new UserDTO() 
{ 
    UserId = user.UserId, 
    Features = user.Role.Features.Select(s => s.FeatureName).ToList() 
}; 


return model; 

} 

樣品致電Login功能和SessionHandler

[HttpPost] 
public ActionResult Login(LoginModel model) 
{ 
    var user = Login(model.username, model.password); 

    if(user == null) return View(model); 

    SessionHandler.UserSession = user; 

    // TODO: redirect to Home Page - after login 

    return RedirectToAction("Index", "Home"); 
} 
分配給

然後,您可以在視圖中執行的操作是檢查用戶是否可以執行特定操作,例如,如果你是查看訂單頁面上 - 你可以隱藏創建訂單按鈕,如果用戶沒有權限:

@model WhateverDTO 

    // Check if user has Create Order Feature in Role 

    @if (SessionHandler.UserSession.Features.Contains("Create Order")) 
    { 
// Yes, User has permission - then Render the Button 

    <button> Create Order </button> 

    } 

您也可以在控制器(服務器端)添加檢查 - 這將提供額外的安全性您應用程序,使用該授權屬性:

public class CustomAuthorizeAttribute : AuthorizeAttribute 
{ 

    protected override bool AuthorizeCore(HttpContextBase httpContext) 
    { 
     if (httpContext == null) 
      throw new ArgumentNullException("httpContext"); 
     if (httpContext.Session == null) 
      return false; 

     // Checking Authenticaiton 
     var userSettings = SessionHandler.UserSession; 
     if (userSettings == null) 
      return true; 

     //Checking Authorization 
     if (Roles.Length == 0) 
      return true; 


     var actionFeatures = Roles.Split(','); 
     if (!actionFeatures.Any(s => userSettings.Features.Contains(s))) 
      throw new UnauthorizedAccessException("You do not have permission to perform this action."); 
     return true; 
    } 
} 

,然後裝點您的操作,

[CustomAuthorize(Roles = "Create Order")] 
// Pass feature name for Roles - if user doesn't have permission to Create Order - the "You do not have permission to perform this action." exception will get thrown 
public ActionResult CreateOrder() 
{ 
    return View(new CreateOrderDTO()); 
} 

[HttpPost] 
[CustomAuthorize(Roles = "Create Order")] 
// Pass feature name for Roles - if user doesn't have permission to Create Order - the "You do not have permission to perform this action." exception will get thrown 
public ActionResult CreateOrder(CreateOrderDTO model) 
{ 

    return View(model); 
} 

關於上述方法的好處 - 是,你可以添加儘可能多的用戶角色因爲你需要 - 而不需要改變代碼。


模型 - 我覺得這一個保持爲一個與數據庫

模型是相同的 - 相同的DB同型號

的ViewModels - 我寫的每個角色不同的看法?如果是這樣,2個文件/類?

不,不要複雜的事情 - 用同一視圖模型/ DTO

控制器 - 一樣,不用我寫不同的功能?類?如果是這樣,那麼[授權角色]有什麼意義,只是爲了防止未經授權的訪問&不打算分裂?

無需單獨行動/觀點或控制器

意見 - 我嘗試使用的大部分地區相同的看法,只是不知何故包括邏輯,如果他們有「編輯」按鈕或不?

是,使用同樣的觀點 - 隱藏/基於用戶角色/顯示操作功能

局部視圖 - 它們可以被用於「編輯」按鈕,可能會或可能不會對看法?

無需爲按鈕

視圖佈局部分觀點 - 過濾器 - 我可以做一些花哨的邏輯,並將所有內容放在完全2個不同的文件夾中(整個MVC),然後在路由/授權級別分割它 路由 - ?

+0

您可以給我一點方向,理想情況下應放置這些文件的位置嗎? (MVC結構明智) – Worthy7

+0

我已經實現了這個,它的工作原理,謝謝:)讓我知道我應該把類放在命名空間/文件夾/文件 – Worthy7

+1

@ Worthy7完全依賴於你的應用程序的體系結構 - SessionHandler應該被添加到MVC Web應用程序的子文件夾中,例如助手。除此之外,如果您有一個單獨的DTO Enums項目,請將它們放在那裏 - 否則將它們添加到MVC Web項目中的子文件夾中。 –

相關問題