http://www.microsoft.com/china/MSDN/library/enterprisedevelopment/softwaredev/dnpag2entlib.mspx?mfr=true
http://msdn2.microsoft.com/en-us/library/aa480465.aspx
1 简介
开发人员经常编写需要安全功能的应用程序。这些应用程序通常需要执行一系列不同的安全操作,而且它们还经常与不同的基础安全提供程序(如 Microsoft Active Directory 目录服务、授权管理器、Active Directory 应用程序模式 (ADAM) 和自定义数据库等)进行交互。
安全应用程序块通过收集开发人员必须执行的许多最常见的安全任务,来简化开发人员的工作。每个任务都以一致的方式处理,从特定的安全提供程序中抽象出应用程序代码并使用最佳做法。您甚至可以通过更改配置来更改基础提供程序,而无需更改基础应用程序代码。
安全应用程序块提供的代码提供如下功能:
(1) 身份验证
(2) 授权
(3) 角色管理
(4) 配置文件管理
(5) 缓存主体
2. 几个基本概念(Form MSDN):
(1) Ticket:提供对票证的属性和值的访问,这些票证用于Forms身份验证对用户进行标识。可以使用FormsIdentity 类的 Ticket 属性访问当前经过身份验证的用户的 FormsAuthenticationTicket。通过将当前User 的 Identity 属性强制转换为类型 FormsIdentity,可以访问当前 FormsIdentity 对象。
(2) Token:与当前执行线程关联的访问标记的句柄,用于获取用户的Windows帐户标记。通常,通过调用非托管代码(如调用 Win32 API LogonUser 函数)来检索该帐户标记。
(3) Identity:Identity封装有关正在验证的用户或实体的信息。在最基本的级别上,Identity包含名称和身份验证类型。名称可以是用户名或 Windows 帐户名,而身份验证类型可以是所支持的登录协议(如 Kerberos V5)或自定义值。.NET Framework 定义了一个 GenericIdentity 对象和一个更专用的 WindowsIdentity 对象;前者可用于大多数自定义登录方案,而后者可用于在希望应用程序依赖于 Windows 身份验证的情况中。此外,您还可以定义自己的标识类来封装自定义用户信息。
(4) Principal:Principal表示代码运行时所在的安全上下文。实现基于角色的安全性的应用程序将基于与主体对象关联的角色来授予权限。同标识对象类似,.NET Framework 提供 GenericPrincipal 对象和 WindowsPrincipal 对象。您还可以定义自己的自定义主体类。
IPrincipal 定义一个属性和一种方法,前者用于访问关联的 Identity 对象,而后者用于确定 Principal 对象所标识的用户是否为给定角色的成员。所有 Principal 类都实现 IPrincipal 接口以及任何必需的附加属性和方法。
Principal对象在应用程序域(AppDomain)中绑定到调用上下文(CallContext)对象。默认的调用上下文总是用每个新的AppDomain创建的,因此总是存在可用于接受Principal对象的调用上下文。创建新线程的同时也为该线程创建CallContext对象。Principal 对象引用从创建线程自动复制到新线程的CallContext中。如果运行库无法确定哪个 Principal 对象属于线程的创建者,它将遵循Principal和Identity对象创建的默认策略。
可配置的应用程序域特定策略定义了一些规则,用以决定同新的应用程序域关联的 Principal 对象类型。在安全策略的允许范围内,运行库可创建 Principal 和 Identity 对象来反射同当前执行线程关联的操作系统标记。默认情况下,运行库使用 Principal 和 Identity 对象表示未经身份验证的用户。运行库不创建这些默认的 Principal 和 Identity 对象,除非代码试图访问它们。
创建应用程序域的受信任代码可设置应用程序域策略,以控制默认 Principal 和 Identity 对象的构造。此应用程序域特定的策略适用于该应用程序域中的所有执行线程。
3. 使用:
(0) 使用EntLib配置工具配置App.config/web.config:
a) 创建Cacheing Application Block(缓存Identity、Principal或Profile时要用到CAB)和Security Application Block;
b) Security Application Block->Security Cache->New->Caching Store Provider->将CacheManager指定到上面创建的Cacheing Application Block;
c) Security Application Block->Security Cache->New->RuleProvider。
(1) SaveIdentity(用户登录时,缓存用户所对应的Identity):
IIdentity identity = null;
if (Membership.ValidateUser("username", "password"))//验证用户是否合法
{
identity = new GenericIdentity("username", Membership.Provider.Name);//为合法用户创建Identity
}
IToken token = null;
if (identity != null)
{
token = cache.SaveIdentity(identity); // Cache the identity.
}
//我们也可以调用SavePrincipal或SaveProfile来缓存Pricipal或Profile,这些对象是通过同一个Token进行关联的。
(2) 根据Token验证用户是否合法:
IIdentity savedIdentity = cache.GetIdentity(token);//返回与token关联的Identity,如果token过期或者不合法,则返回null
(3) 终止Session:
cache.ExpireIdentity(token);
(4) 检测用户是否有权限执行某个操作:
IPrincipal principal = new GenericPrincipal(new GenericIdentity(userName), roles);
bool authorized = ruleProvider.Authorize(principal, "Submit Order");
4. Security Application Block的设计: