2012-03-04 60 views
3

我需要爲目前正在編寫的WPF應用程序實現某種RBAC。由於v2.0 ASP.NET具有安全性,成員資格和角色管理基礎結構(例如,如here所述),雖然我可以使用它,但仍然覺得在這種情況下使用它會有點冒失。我會歡迎任何使用過它並在類似環境中取得成功的人的反饋。WPF應用程序的基於角色的訪問控制 - 最佳實踐

我也考慮過使用AD LDS,閱讀TechNet文章,並查看了一些MSDN代碼示例,但我想知道是否有任何組件(用於.NET),它可以消除一些固有的複雜性創建數據庫,將其設置爲部署和持續維護。在這種情況下免費或商業可以。

有關SO提及客戶端應用服務的其他問題,但這需要將IIS添加到組合中,儘管沒有超出可能性範圍,但在項目開始時我並沒有設想到這一點。

這種情況下的最佳做法是什麼?該應用程序是一種典型的n層類型事務,與遠程SQL Server數據庫進行通信,以便在需要時可以將角色存儲在那裏

+1

對於AD LDS,如果您有適當的權限,則可以將數據託管到AD存儲中。希望這會爲你簡化問題? – code4life 2012-03-05 16:12:33

+0

@ code4life在此網站上的任何示例? – noonand 2012-03-05 20:54:39

+1

我會從這裏開始:http://msdn.microsoft.com/en-us/library/aa772138.aspx。作爲參考,AD LDS不一定比數據庫簡單,只是不同而已。 – code4life 2012-03-05 21:16:23

回答

5

您可以查看P & P指導/代碼(或你可以使用他們的塊)。 http://msdn.microsoft.com/en-us/library/ff953196(v=pandp.50).aspx

我在SQLServer中實現了自己的後端存儲。它並不那麼難,像User,UserRole,SecurityItem,SecurityItemUser,SecurityItemRole這樣的表。我根據AD對用戶的Windows登錄進行身份驗證,但只將其登錄名存儲在數據庫中(例如用戶表的密鑰)。

通過接口/提供者模型將事物抽象出來是一個好主意。這樣,如果你的應用程序在未來發生變化,它不會需要太多的重構。

我構建了一個增長很多的2層應用程序(WPF - > SQLServer),並且管理層決定他們現在需要一個3層應用程序(WCF中間層)。我現在正在處理這個問題,而且這是一個真正的痛苦,因爲我將授權代碼與客戶端應用程序密切配合。現在很明顯授權應該發生在服務層,但需要很多工作。

關於如何識別特定的'安全',我想出了一個很好的竅門,節省了大量的工作。具有諷刺意味的是,雖然這是問題的一部分,但我現在試圖對其進行3層重新設計。訣竅是作爲唯一的標識符使用完全合格的名稱類的一個可靠的,那麼你可以使用一些簡單的代碼每次檢查:

_secUtil.PromptSecurityCheck(_secUtil.GetFullyQualifiedObjectName(this, "Save")) 

下面是一些其他的代碼給你一個想法如何我做到了(使用P & P框架)。

public class SecurityUtil : ISecurityUtil 
{ 
    public string DatabaseUserName { get { return LocalUserManager.GetUserName(); } } 

    public bool PromptSecurityCheck(string securityContext) 
    { 
     bool ret = IsAuthorized(securityContext); 

     if (!ret) 
     { 
      MessageBox.Show(string.Format("You are not authorised to perform the action '{0}'.", securityContext), Settings.Default.AppTitle, 
             MessageBoxButton.OK, MessageBoxImage.Error); 
     } 

     return ret; 
    } 

    public bool IsAuthorized(string securityContext) 
    { 
     IAuthorizationProvider ruleProvider = AuthorizationFactory.GetAuthorizationProvider("MyAuthorizationProvider"); 

     //bool ret = ruleProvider.Authorize(LocalUserManager.GetThreadPrinciple(), securityContext); 
     bool ret = ruleProvider.Authorize(LocalUserManager.GetCurrentPrinciple(), securityContext);    
     return ret; 
    } 

    public string GetFullyQualifiedName(object element) 
    { 
     return element.GetType().FullName; 
    } 

    public string GetFullyQualifiedObjectName(object hostControl, string objectName) 
    { 
     return GetFullyQualifiedName(hostControl) + "." + objectName; 
    } 
} 

[ConfigurationElementType(typeof(CustomAuthorizationProviderData))] 
public class MyAuthorizationProvider : AuthorizationProvider 
{ 
    public SitesAuthorizationProvider(NameValueCollection configurationItems) 
    { 
    } 

    public override bool Authorize(IPrincipal principal, string context) 
    { 

     bool ret = false; 

     if (principal.Identity.IsAuthenticated) 
     { 
      // check the security item key, otherwise check the screen uri 
      ret = LocalCacheManager.GetUserSecurityItemsCache(LocalUserManager.UserId, false).Exists(
       si => si.SecurityItemKey.Equals(context, StringComparison.InvariantCultureIgnoreCase)); 

      if (!ret) 
      { 
       // check if this item matches a screen uri 
       ret = LocalCacheManager.GetUserSecurityItemsCache(LocalUserManager.UserId, false).Exists(
       si => si.Uri.Equals(context, StringComparison.InvariantCultureIgnoreCase)); 
      } 
     } 

     return ret; 

    } 
} 
+0

錯過了關於該主題的PnP指導,但之前曾遇到過AzMan。感謝那! – noonand 2012-03-05 12:00:00

+1

就像任何人回過頭來閱讀這篇文章一樣。安全應用程序塊已在EntLib的v6中被棄用。有關更多詳細信息,請參閱http://go.microsoft.com/fwlink/p/?LinkID=290906上的遷移指南 – noonand 2013-11-26 10:08:21