我需要为我正在编写的WPF应用程序实现某种RBAC.由于V2.0 ASP.NET已经具备了安全,成员和角色管理基础设施(如描述这里的例子),虽然我可以用它仍然认为使用它在这方面将是一个有点哈克.我会欢迎任何使用它并在类似环境中取得成功的人的反馈.
我也考虑过使用AD LDS,阅读TechNet文章并查看了一些MSDN代码示例,但我想知道是否有任何组件(用于.NET)可以消除创建数据库背后的一些固有复杂性,将其设置为部署和正在进行的维护.在这种情况下,免费或商业是可以的.
关于SO的其他问题提到了客户端应用程序服务,但这需要将IIS添加到组合中,虽然不超出可能性范围,但这是我在项目开始时没有想到的.
在这种情况下,最佳做法是什么?该应用程序是典型的n层类型事件,它与远程SQL Server数据库进行通信,因此如果需要,可以将角色存储在那里
您可以查看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"))
Run Code Online (Sandbox Code Playgroud)
以下是一些其他代码,可以让您了解我是如何做到的(使用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;
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
8429 次 |
| 最近记录: |