在上篇讲Asp.net MVC权限设计的文章中,利用了微软企业库的安全模块。该设计可以适用于其他winform,asp.net程序。

http://www.cnblogs.com/huyq2002/archive/2012/01/17/2324609.html

但是它有一个问题,所有规则都保存在配置文件 - web.config或app.config中在生产环境中系统需要从数据库中加载规则允许在运行时修改安全规则

下面详细如何扩展安全模块 Microsoft Enterprise Library Security Application Block,SQL Server数据库加载权限规则

要运行示例代码,需要安装VS2010+ ASP.NET MVC3SQLSERVER 2000及以上数据库

1) 创建规则表 - AuthorizationRule和插入3条规则。

数据库脚本如下 (需要修改数据库名)
USE [VehicleMDM] 
GO

/****** Object: Table [dbo].[AuthorizationRule] Script Date: 03/20/2012 11:34:41 ******/
IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[AuthorizationRule]') AND type in (N'U'))
DROP TABLE [dbo].[AuthorizationRule]
GO

USE [VehicleMDM]
GO

/****** Object: Table [dbo].[AuthorizationRule] Script Date: 03/20/2012 11:34:41 ******/
SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

CREATE TABLE [dbo].[AuthorizationRule](
[Id] [int] IDENTITY(1,1) NOT NULL,
[Name] [nvarchar](50) NULL,
[Description] [nvarchar](200) NULL,
[Expression] [nvarchar](100) NULL,
[Parent] [int] NULL,
CONSTRAINT [PK_AuthorizationRule] PRIMARY KEY CLUSTERED
(
[Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]

GO

INSERT INTO [AuthorizationRule]
([Name]
,[Description]
,[Expression]
,[Parent])
VALUES
('IsAdministrator','Is Administrator Check','R:Administrator',null)


INSERT INTO [AuthorizationRule]
([Name]
,[Description]
,[Expression]
,[Parent])
VALUES
('IsDataSteward','Is DataSteward Check','R:Administrator OR R:DataSteward',null)

INSERT INTO [AuthorizationRule]
([Name]
,[Description]
,[Expression]
,[Parent])
VALUES
('IsUser','Is User Check','R:User OR R:DataSteward OR R:Administrator',null)

GO
2)组件设计
 
类图
  • IAuthorizationRepository: 接口,描述rule repository, 包含属性 Name, Connectionstring
  • SqlAuthorizationData: IAuthorizationRepository接口针对SQL Server的实现.
  • SqlAuthorizationProviderData:该类扩展了原组件里面的AuthorizationProviderData类的方法GetRegistrations,并且会保存一组iSqlAuthorizationData 类的实例
  • IAuthorizationRule: 规则的主要接口,包含属性Name, Expression
  • SqlAuthorizationRule: 规则接口的SQL Server的实现
  • SqlAuthorizationRuleProvider:扩展了原组件的AuthorizationProvider类, 它从配置文件中读取SqlAuthorizationProviderData,获得数据库连接串,利用 ADO.net 实例化SqlAuthorizationRule数组,并且利用Cache Application Block实现规则的缓存来提高性能。 
代码示例
   
        /// <summary> 
/// Evaluates the specified authority against the specified context.
/// </summary>
/// <param name="principal">Must be an <see cref="IPrincipal"/> object.</param>
/// <param name="ruleName">The name of the rule to evaluate.</param>
/// <returns><c>true</c> if the expression evaluates to true,
/// otherwise <c>false</c>.</returns>
public override bool Authorize(IPrincipal principal, string ruleName)
{
if (principal == null) throw new ArgumentNullException("principal");
if (ruleName == null || ruleName.Length == 0) throw new ArgumentNullException("ruleName");

//get the rules from the cache
if (m_CacheManager.ContainsKey(CACHEKEY))
{
GetAuthorizationRulesFromCache();
}
else
{
GetAuthorizationRules();
}

InstrumentationProvider.FireAuthorizationCheckPerformed(principal.Identity.Name, ruleName);

BooleanExpression booleanExpression = GetParsedExpression(ruleName);
if (booleanExpression == null)
{
throw new InvalidOperationException(string.Format("Authorization Rule Not Found", ruleName));
}

bool result = booleanExpression.Evaluate(principal);

if (result == false)
{
InstrumentationProvider.FireAuthorizationCheckFailed(principal.Identity.Name, ruleName);
}
return result;
}
3)部署
(1)修改App.config/Web.config中的权限模块的配置,类似于下( 修改数据库连接)
<securityConfiguration defaultAuthorizationInstance="RulesProvider" defaultSecurityCacheInstance=""> 
<authorizationProviders>
<add type="VehicleMaster.Infrastructure.Common.Utilities.Security.SqlAuthorizationRuleProvider, Utilities" name="RulesProvider">
<repositories>
<add name="default" connectionstring="Data Source=10.234.58.172\SQL_DEV;Initial Catalog=VehicleMDM;User Id=sa;Password=Passw0rd;"/>
</repositories>
</add>
</authorizationProviders>
</securityConfiguration>
(2) 修改NHibernate.config的数据库连接
(3) 要模拟不同的客户权限访问, 修改代码中UserService类的下面代码(示例程序利用域帐号模拟不同的角色)
else 
{
//user.AddRole(new UserRole(UserRoleConstants.Administrator));
user.AddRole(new UserRole(UserRoleConstants.DataSteward));
user.AddRole(new UserRole(UserRoleConstants.User));
user.CurrentUserRoleIndex = 0;
}
return user;
(4) 基于规则的权限设置于MVC controller层, 下面设置保证只有administrator才可以访问about页面.
[RuleAuthorize("IsAdministrator")] 
public ActionResult About()
{
return View();
}
 如果用户无该角色,访问About页面会得到以下信息
(5)Cache的配置也保存在Web.Config/App.config中
<cachingConfiguration defaultCacheManager="CacheManager"> 
<cacheManagers>
<add name="CacheManager" type="Microsoft.Practices.EnterpriseLibrary.Caching.CacheManager, Microsoft.Practices.EnterpriseLibrary.Caching, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
expirationPollFrequencyInSeconds
="60" maximumElementsInCacheBeforeScavenging="1000"
numberToRemoveWhenScavenging
="10" backingStoreName="Cache" />
</cacheManagers>
<backingStores>
<add name="Cache" type="Microsoft.Practices.EnterpriseLibrary.Caching.Database.DataBackingStore, Microsoft.Practices.EnterpriseLibrary.Caching.Database, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
encryptionProviderName
="" databaseInstanceName="CacheDB" partitionName="AuthorizationCache" />
</backingStores>
</cachingConfiguration>
<connectionStrings>
<add name="CacheDB" connectionString="Data Source=10.234.58.172\SQL_DEV;Initial Catalog=VehicleMDM;Persist Security Info=True;User ID=sa;Password=Passw0rd;MultipleActiveResultSets=True" providerName="System.Data.SqlClient" />
<add name="ApplicationServices" connectionString="Data Source=10.234.58.172\SQL_DEV;Initial Catalog=VehicleMDM;User Id=sa;Password=Passw0rd;" providerName="System.Data.SqlClient" />
</connectionStrings>
该版本未实现对规则的增删改功能,读者可以自己实现。
 
代码从下面的链接下载(抱歉原文是英文的)
 
 
posted on 2012-03-22 13:22  胡以谦  阅读(2266)  评论(1编辑  收藏  举报