2009-08-03 29 views
28

我需要知道如何去實現C#應用程序的一般安全性。我在這方面有什麼選擇?如果它滿足我的需求,我更願意使用現有的框架 - 我不想重新發明輪子。.NET中的身份驗證,授權,用戶和角色管理和常規安全性

我的要求如下:

  • 通常的用戶名/密碼驗證用戶
  • manageing - 將權限分配給用戶
  • 管理的角色 - 將用戶分配到角色,權限分配給角色
  • 基於用戶名和角色的用戶授權

我在尋找f或者.Net社區經過時間考驗和使用的免費/開源框架/庫。

我的應用程序採用客戶端/服務器方法,服務器作爲Windows服務運行,連接到SQL Server數據庫。客戶端和服務器之間的通信將通過WCF進行。

另一件很重要的事情是,我需要能夠爲查看/更新/刪除特定實體(無論是客戶還是產品等)分配特定的用戶或角色權限。傑克可以查看10位客戶中的某3位,但只能更新微軟,雅虎和谷歌客戶的詳細信息,並且只能刪除雅虎。

+2

只想確保您知道:C#是語言。它沒有安全性。 .NET是平臺。這是安全的地方。 – 2009-08-03 15:32:30

+0

thnx約翰 - 我明白不同之處。 – 2009-08-03 17:24:40

+0

要麼你不能擴展Asp.net成員資格,要麼你可以使用準備插入框架 - VisualGuard - http://www.visual-guard.com/EN/-source_soforum.html – 2017-02-27 11:07:41

回答

29

對於粗粒度安全性,您可能會發現內置主體代碼有用;用戶對象(及其角色)在.NET中由「主體」控制,但運行時本身可以強制執行此操作。

一個委託人的實現可以是實現定義的,你通常可以注入你自己的; for example in WCF

要查看運行時強制粗接入(即,功能可以被訪問,但不限於哪些具體數據):

static class Roles { 
    public const string Administrator = "ADMIN"; 
} 
static class Program { 
    static void Main() { 
     Thread.CurrentPrincipal = new GenericPrincipal(
      new GenericIdentity("Fred"), new string[] { Roles.Administrator }); 
     DeleteDatabase(); // fine 
     Thread.CurrentPrincipal = new GenericPrincipal(
      new GenericIdentity("Barney"), new string[] { }); 
     DeleteDatabase(); // boom 
    } 

    [PrincipalPermission(SecurityAction.Demand, Role = Roles.Administrator)] 
    public static void DeleteDatabase() 
    { 
     Console.WriteLine(
      Thread.CurrentPrincipal.Identity.Name + " has deleted the database..."); 
    } 
} 

然而,這並不與細幫助(即「Fred可以訪問客戶A但不訪問客戶B」)。


附加;當然,細粒度,你可以簡單地檢查所需的角色在運行時,通過檢查主要IsInRole

static void EnforceRole(string role) 
{ 
    if (string.IsNullOrEmpty(role)) { return; } // assume anon OK 
    IPrincipal principal = Thread.CurrentPrincipal; 
    if (principal == null || !principal.IsInRole(role)) 
    { 
     throw new SecurityException("Access denied to role: " + role); 
    } 
} 
public static User GetUser(string id) 
{ 
    User user = Repository.GetUser(id); 
    EnforceRole(user.AccessRole); 
    return user; 
} 

你也可以寫做的懶人測試/緩存自己的委託人/標識對象角色,而不必知道他們所有的前期:

class CustomPrincipal : IPrincipal, IIdentity 
{ 
    private string cn; 
    public CustomPrincipal(string cn) 
    { 
     if (string.IsNullOrEmpty(cn)) throw new ArgumentNullException("cn"); 
     this.cn = cn; 
    } 
    // perhaps not ideal, but serves as an example 
    readonly Dictionary<string, bool> roleCache = 
     new Dictionary<string, bool>(); 
    public override string ToString() { return cn; } 
    bool IIdentity.IsAuthenticated { get { return true; } } 
    string IIdentity.AuthenticationType { get { return "iris scan"; } } 
    string IIdentity.Name { get { return cn; } } 
    IIdentity IPrincipal.Identity { get { return this; } } 

    bool IPrincipal.IsInRole(string role) 
    { 
     if (string.IsNullOrEmpty(role)) return true; // assume anon OK 
     lock (roleCache) 
     { 
      bool value; 
      if (!roleCache.TryGetValue(role, out value)) { 
       value = RoleHasAccess(cn, role); 
       roleCache.Add(role, value); 
      } 
      return value; 
     } 
    } 
    private static bool RoleHasAccess(string cn, string role) 
    { 
     //TODO: talk to your own security store 
    } 
} 
3

調查ASP.NET's Membership Providers。我不認爲開箱即用的SQLMembershipProvider會適用於您的案例,但它很容易推出您自己的提供商。

+0

我推出了自己的內部應用程序,已經有用戶設置的數據庫。絕對推薦它。 – 2009-08-12 06:28:50

3

我的答案很可能取決於這個問題的答案:這是一個企業應用程序,它生活在Active Directory中的網絡內?

如果答案是肯定的,那麼這些是我能提供的步驟:

1)爲應用程序創建全局組,於我而言,我有一個APPUSER組和APPADMIN組。

2)您的SQL Server能夠以MIXED AUTHENTICATION模式進行訪問,然後將您的APPUSER組作爲SQL SERVER LOGIN分配給您的數據庫,並具有相應的DB的CRUD權限,確保您在連接字符串中使用Trusted Connection = True訪問SQL SERVER。

此時,您的AD商店將負責認證。因爲,您通過TRUSTED CONNECTION訪問應用程序,它會將運行應用程序的任何帳戶的身份傳遞給SQL Server。

現在,對於AUTHORIZATION(即告訴您的應用程序允許登錄的用戶執行什麼操作),查詢AD獲取登錄用戶所屬的組列表是一個簡單的事情。然後檢查適當的組名,並根據成員資格構建您的用戶界面。

方式我的應用程序的工作是這樣的:

  1. 啓動應用程序,憑證是基於登錄的用戶,這是認證的主要方面(即,它們可以登錄因此它們存在)
  2. 我得到的所有組對於Windows身份問題
  3. 我檢查標準用戶組 - 如果此組沒有對Windows標識有問題存在,那麼這就是一個認證失敗
  4. 我檢查管理員用戶集團 - 有了這個前在用戶的組isting,我修改UI以允許訪問管理組件
  5. 顯示UI

然後我有或者與在其上的確定權限的/ etc一個主要目的,或我利用全局變量我可以在構建表單時確定適當的用戶界面(即,如果我的用戶不是ADMIN組的成員,那麼我會隱藏所有的DELETE按鈕)。

爲什麼我會這麼建議?

這是部署的問題。

我的經驗是,大多數企業應用程序是由網絡工程師而不是程序員部署的 - 因此,認證/授權是AD的責任是有意義的,因爲這是網絡人員在討論身份驗證時去的地方/授權。

此外,在爲網絡創建新用戶期間,網絡工程師(或負責創建新網絡用戶的人員)在AD AD中執行組分配時比他們具有的事實更容易記住進入十幾個應用程序來分析授權的分配。

這樣做有助於解決新僱員需要被授予的權限和權限的迷宮,或者需要拒絕那些離開公司的人員,並且在其所屬的中央存儲庫中維護認證和授權(即在AD @ Domain控制器級別)。

0

我認爲你在這裏看到幾個單獨的問題 - 大多數安全系統分離認證和授權並非偶然。

對於驗證,更大的問題是後勤。或者,這些用戶是否有合適的位置,可以在應用程序本地,Active Directory,其他LDAP存儲或其他應用程序中使用。究竟哪裏非常不重要 - 我們只需要能夠牢固地識別用戶,並且最好能夠讓這個任務成爲別人的問題。每天結束時,您真的只需要一個唯一的標識符,而來自會計的鮑勃實際上是來自會計的鮑勃的安慰。

授權是這個問題中更有趣的部分。我認爲,如果它真的很細緻,那麼無論用戶來自哪裏,您都希望完全在您的應用程序中管理它。 Marc Gravell確實創建了一個很好的方法來模擬至少其中一些 - 使用IPrincipal和PrincipalPermission的一些自定義實現來管理事情是一種非常乾淨的入門方法。除此之外,您可以使用諸如this one之類的技術以相當乾淨的方式做出更復雜的授權決策。

0

我會使用術語'RBAC'(基於角色的訪問控制系統)作爲解決方案滿足您的所有需求。

我不會在這裏詳細解釋'RBAC',而是在下面簡單介紹一下。

它基本上包含3個功能。

1)身份驗證 - 它確認用戶的身份。通常通過用戶帳戶和密碼或憑證完成。

2)授權 - 它定義了用戶可以在應用程序中執行和不能執行的操作。防爆。 '修改訂單'是允許的,但'創建新訂單'是不允許的。

3)審覈用戶對應用程序的操作。 - 它跟蹤用戶對應用程序的操作,以及誰已授予哪些用戶的訪問權限?

你可以在這裏查看wiki上的RBAC。

https://en.wikipedia.org/wiki/Role-based_access_control

現在,關於回答您的需求 - 可能的解決方法之一是延長Asp.Net會員按需求。

關於一些隨時可以使用的框架,我會推薦VisualGuard爲此我工作,您應該檢查一下,它能夠非常簡單地完成您所需要的一切,最重要的是它管理所有用戶,角色,權限和應用程序,並且爲了定義權限,管理員不需要開發人員的知識,即他/她可以通過UI創建活動限制。

你也可以查看這篇文章,以更多地瞭解權限和基於角色的系統。

http://www.visual-guard.com/EN/net-powerbuilder-application-security-authentication-permission-access-control-rbac-articles/dotnet-security-article-ressources/role-based-access-control-source_soforum.html