<!-- /* Font Definitions */ @font-face {font-family:Wingdings; panose-1:5 0 0 0 0 0 0 0 0 0; mso-font-charset:2; mso-generic-font-family:auto; mso-font-pitch:variable; mso-font-signature:0 268435456 0 0 -2147483648 0;} @font-face {font-family:宋体; panose-1:2 1 6 0 3 1 1 1 1 1; mso-font-alt:SimSun; mso-font-charset:134; mso-generic-font-family:auto; mso-font-pitch:variable; mso-font-signature:3 135135232 16 0 262145 0;} @font-face {font-family:新宋体; panose-1:2 1 6 9 3 1 1 1 1 1; mso-font-charset:134; mso-generic-font-family:modern; mso-font-pitch:fixed; mso-font-signature:3 135135232 16 0 262145 0;} @font-face {font-family:"/@宋体"; panose-1:2 1 6 0 3 1 1 1 1 1; mso-font-charset:134; mso-generic-font-family:auto; mso-font-pitch:variable; mso-font-signature:3 135135232 16 0 262145 0;} @font-face {font-family:"/@新宋体"; panose-1:2 1 6 9 3 1 1 1 1 1; mso-font-charset:134; mso-generic-font-family:modern; mso-font-pitch:fixed; mso-font-signature:3 135135232 16 0 262145 0;} /* Style Definitions */ p.MsoNormal, li.MsoNormal, div.MsoNormal {mso-style-parent:""; margin:0cm; margin-bottom:.0001pt; text-align:justify; text-justify:inter-ideograph; mso-pagination:none; font-size:10.5pt; mso-bidi-font-size:12.0pt; font-family:"Times New Roman"; mso-fareast-font-family:宋体; mso-font-kerning:1.0pt;} /* Page Definitions */ @page {mso-page-border-surround-header:no; mso-page-border-surround-footer:no;} @page Section1 {size:612.0pt 792.0pt; margin:72.0pt 90.0pt 72.0pt 90.0pt; mso-header-margin:36.0pt; mso-footer-margin:36.0pt; mso-paper-source:0;} div.Section1 {page:Section1;} /* List Definitions */ @list l0 {mso-list-id:652562762; mso-list-type:hybrid; mso-list-template-ids:203070638 -1283403936 67698713 67698715 67698703 67698713 67698715 67698703 67698713 67698715;} @list l0:level1 {mso-level-tab-stop:39.75pt; mso-level-number-position:left; margin-left:39.75pt; text-indent:-18.0pt;} @list l1 {mso-list-id:2019455122; mso-list-type:hybrid; mso-list-template-ids:-1561150094 67698689 67698691 67698693 67698689 67698691 67698693 67698689 67698691 67698693;} @list l1:level1 {mso-level-number-format:bullet; mso-level-text:; mso-level-tab-stop:42.75pt; mso-level-number-position:left; margin-left:42.75pt; text-indent:-21.0pt; font-family:Wingdings;} @list l2 {mso-list-id:2031178118; mso-list-type:hybrid; mso-list-template-ids:921082496 67698689 67698691 67698693 67698689 67698691 67698693 67698689 67698691 67698693;} @list l2:level1 {mso-level-number-format:bullet; mso-level-text:; mso-level-tab-stop:63.75pt; mso-level-number-position:left; margin-left:63.75pt; text-indent:-21.0pt; font-family:Wingdings;} @list l3 {mso-list-id:2145927690; mso-list-type:hybrid; mso-list-template-ids:-1731675372 67698689 67698691 67698693 67698689 67698691 67698693 67698689 67698691 67698693;} @list l3:level1 {mso-level-number-format:bullet; mso-level-text:; mso-level-tab-stop:63.75pt; mso-level-number-position:left; margin-left:63.75pt; text-indent:-21.0pt; font-family:Wingdings;} ol {margin-bottom:0cm;} ul {margin-bottom:0cm;} -->
<!-- /* Font Definitions */ @font-face {font-family:宋体; panose-1:2 1 6 0 3 1 1 1 1 1; mso-font-alt:SimSun; mso-font-charset:134; mso-generic-font-family:auto; mso-font-pitch:variable; mso-font-signature:3 135135232 16 0 262145 0;} @font-face {font-family:"/@宋体"; panose-1:2 1 6 0 3 1 1 1 1 1; mso-font-charset:134; mso-generic-font-family:auto; mso-font-pitch:variable; mso-font-signature:3 135135232 16 0 262145 0;} /* Style Definitions */ p.MsoNormal, li.MsoNormal, div.MsoNormal {mso-style-parent:""; margin:0cm; margin-bottom:.0001pt; text-align:justify; text-justify:inter-ideograph; mso-pagination:none; font-size:10.5pt; mso-bidi-font-size:12.0pt; font-family:"Times New Roman"; mso-fareast-font-family:宋体; mso-font-kerning:1.0pt;} /* Page Definitions */ @page {mso-page-border-surround-header:no; mso-page-border-surround-footer:no;} @page Section1 {size:612.0pt 792.0pt; margin:72.0pt 90.0pt 72.0pt 90.0pt; mso-header-margin:36.0pt; mso-footer-margin:36.0pt; mso-paper-source:0;} div.Section1 {page:Section1;} /* List Definitions */ @list l0 {mso-list-id:482889063; mso-list-type:hybrid; mso-list-template-ids:-1664609752 -1246323414 67698713 67698715 67698703 67698713 67698715 67698703 67698713 67698715;} @list l0:level1 {mso-level-number-format:chinese-counting-thousand; mso-level-text:%1、; mso-level-tab-stop:6.8pt; mso-level-number-position:left; margin-left:6.8pt; text-indent:-6.8pt;} ol {margin-bottom:0cm;} ul {margin-bottom:0cm;} -->
使用安全应用程序块实现权限管理
将要进行的操作
a. 添加引用
b. 在配置文件( Web.config/App.config )中添加 Security Application Block
c. 建立访问规则
1. 首先添加以下引用
Microsoft.Practices.EnterpriseLibrary.Security.dll
Microsoft.Practices.EnterpriseLibrary.Security.Cache.CachingStore.dll
Microsoft.Practices.Unity.dll
Microsoft.Practices.Unity.Configuration.dll
Microsoft.Practices.EnterpriseLibrary.Common.dll
Microsoft.Practices.ObjectBuilder2.dll
Microsoft.Practices. EnterpriseLibrary.Data.dll
说明 :使用安全应用程序块必须有的引用是Security.dll ,而Common.dll 、Unity.dll 和ObjecBuilder2.dll 文件是企业库的公共类库文件。使用企业库来架构系统时,无特殊情况都要使用这三个文件。所以,为避免不必要的麻烦和错误,还是先添加者三个引用。Security.Cache.CachingStore.dll 文件将为我们提供安全的缓存,待会儿在使用时就很明了了。最后,Data.dll 是与数据库交互用的。
2. 在配置文件( Web.config/App.config )中添加 Security Application Block 应用程序块
添加了 Security Application Block 之后,会看见 Authorization 和 Security Cache 两个节点。 Authorization 是授权模块, Security Cache 为我们提供缓存的支持。
如何添加 Security Application Block 应用程序块?
l 右键单击 Web.config/App.config 文件,选择 Edit Enterprise Library Configuration , 如图 2.1
图 2.1 打开 Web.config 文件
l 选择在配置文件编辑器中选择 *.Config 文件,右键单击,在弹出的菜单中依次选择, New->Security Application Block 。
3. 建立访问规则
Authorization 包括三个 Provider ,我们只使用 Authorization Role Provider, 这个 provider 可以方便我们快速建立 Forms 认证的访问规则。 AzMan Provider 和系统的关系比较密切,使用的是系统的账户认证,适合于基于 Windows 认证的内部局域网。 Customer Authorization Provider 是用户自定义的 Provider 。
那么应如何配置访问规则呢?
l 右键单击 Authorization 节点,依次选择 New->Authorization Rule Provider
l 出现 Rule Provider 节点后,右键单击此节点,依次选择 New->Rule
l 出现 Rule 节点后,查看 Rule 节点的属性,找到 Expression 属性,单击 Expression 的 (…) 省略号,会出现 Rule Expression Editor, 如图 3.0 。
图 3.0 Role Expression Editor
修改 Rule Name 为 r_AddRoleToUser 。单击 Role 按钮,输入 Manager , 单击 OR 按钮,单击 Role 按钮,输入 Administrator 。输入完成后如图 3.1 。
图 3.1 配置规则表达式
其他的规则可按需配置,操作步骤与此类似。配置好访问规则后的 Security Application Block 样式如下图 3.2
图 3.2 配置好的 Security Application Block
4. 建立 Security Application Block 的事件处理类
在我的这个项目中,我把这些事物处理类都放到了 Common 层 , 其他的如异常处理、日志、缓存等等都放在这个层里面,方便统一的管理。
这个类的主要的功能是对系统安全的统一设置和管理,如权限管理、角色管理、用户认证和授权,密码加密等等。下面我简单介绍一下这个类的创建和一些主要功能的实现。
如何建立 Security Application Block 的事件处理类?
l 在 Common 层新建一个文件夹,名称为 Security (可以任意命名,下同),再新建两个类,分别命名为 ContactRule.cs 和 SecurityHelper.cs 。
ContactRule.cs 文件保存的是所有的访问规则的名称,主要是为了能够对系统的访问规则有更有效的管理。
ContactRule.cs 示例代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Jxzcxx.ZCOA.Common.Security
{
public class ContactRule
{
public ContactRule() { }
public const string AddRoleToUser = "r_AddRoleToUser" ;
public const string CreateUser = "r_CreateUser" ;
public const string DeleteUser = "r_DeleteUser" ;
public const string ManageEmployees = "r_ManageEmployees" ;
}
}
我主要介绍一下 SecurityHelper.cs 文件。
添加如下引用
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web;
// 上面是系统自动产生的引用/ 下面是我们应该手动添加的引用
using System.Configuration;
using System.Configuration.Provider;
using System.Security;
using System.Security.Principal;
using System.Web.Security;
using Microsoft.Practices.EnterpriseLibrary.Security;
using Microsoft.Practices.EnterpriseLibrary.Security.Cache.CachingStore;
using Microsoft.Practices.Unity;
using Microsoft.Practices.Unity.Configuration;
认证 : 验证当前用户是否存在,若存在,则验证通过,并为当前用户创建一个Identity ,这个Identity 是网站为当前用户创建的一个包含验证信息的唯一标识。在网站中我们可以通过这个标识来获得用户信息。
public static bool Authenticate(string username, string password)
授权 : 验证当前用户是否被授权, 若被授权则允许用户进行操作。验证的过程是
1. 通过用户的Identity 获得用户所属的角色
2. 再通过Identity 和角色来生成用户的主体特征
3. 通过获得的主体特征和传入的规则(这个规则就是我们在Edit Enterprise Library Configuration 中配置的Rule )来对用户是否被授权进行验证。
public static bool Authorized(string rule)
在页面中怎样调用
请确保引用到了SecurityHelper.cs 的命名空间
如: using Jxzcxx.ZCOA.Common.Security;
判断代码如下:
if (!SecurityHelper .Authorized("RoleName" ))
{
验证未通过怎样处理
}
Else
{
验证通过怎样处理
}
注意: 差点忘了,我使用的是微软的Membership 的认证,所以必须先配置好数据库。关于如何配置aspnetdb 数据库,在后面会专门介绍。请到《如何配置aspnetdb 数据库》查看。
附:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web;
// 系统自动产生的引用/ 下面是我们应该添加的应用
using System.Configuration;
using System.Configuration.Provider;
using System.Security;
using System.Security.Principal;
using System.Web.Security;
using Microsoft.Practices.EnterpriseLibrary.Security;
using Microsoft.Practices.EnterpriseLibrary.Security.Cache.CachingStore;
using Microsoft.Practices.Unity;
using Microsoft.Practices.Unity.Configuration;
namespace Jxzcxx.ZCOA.Common.Security
{
public class SecurityHelper
{
#region initialise
private static IIdentity identity; // 用户的认证信息
private static IToken token; // 存储Identiry 信息到缓冲中
private static ISecurityCacheProvider securityCacheProvider = SecurityCacheFactory .GetSecurityCacheProvider("Caching Store Provider" );
// Providers
private static IAuthorizationProvider ruleProvider;
//private IRolesProvider rolesProvider;
//private IProfileProvider profileProvider; // 个性化设置
//private static MembershipProvider membership;
//securityCacheProvider = SecurityCacheFactory.GetSecurityCacheProvider("Caching Store Provider");
#endregion
private SecurityHelper() { }
//public static bool
#region 创建用户
public static bool CreateUser(string username, string password)
{
bool created = false ;
try
{
//foreach (MembershipUser user in GetAllUsers())
//{
// if (user.UserName == username)
// {
// WebMessageBox.Show(" 用户");
// }
//}
MembershipUser user = Membership .CreateUser(username, password);
if (user != null )
{
created = true ;
}
return created;
}
catch (Exception ex)
{
WebMessageBox .Show(" 在创建用户:" + username + " 时出现异常:" + ex.Message);
return false ;
}
}
#endregion
#region 检测用户名是否存在
public static bool CheckName(string name)
{
bool existed = false ;
foreach (MembershipUser user in SecurityHelper .GetAllUsers())
{
if (user.UserName == name)
{
existed = true ;
}
}
return existed;
}
#endregion
#region 删除用户
public static bool DeleteUser(string username)
{
bool deleted = false ;
try
{
deleted = Membership .DeleteUser(username, true );
return deleted;
}
catch (Exception ex)
{
WebMessageBox .Show(" 在删除用户:" + username + " 时出现异常:" + ex.Message);
return false ;
}
}
#endregion
#region 验证当前用户是否存在
public static bool Authenticate(string username, string password)
{
bool authenticated = false ;
try
{
// TODO: Authenticate Credentials
authenticated = Membership .ValidateUser(username, password);
if (!authenticated)
return false ;
identity = new GenericIdentity (username, Membership .Provider.Name);
return authenticated;
}
catch (Exception ex)
{
WebMessageBox .Show(" 在验证用户:" + username + " 时出现异常" + ex.Message);
return false ;
}
}
#endregion
#region 验证当前用户是否被授权
public static bool Authorized(string rule)
{
bool authorized = false ;
if (identity != null )
{
//IIdentity savedIdentity = null;
//savedIdentity = retrieveIdentity();
//if (savedIdentity != null)
//{
// if (savedIdentity.Name == identity.Name)
// {
// authorized = true;
// }
//}
//else
//{
// 通过用户的Identity 得到用户所属的角色信息
string [] roles = Roles .GetRolesForUser(identity.Name);
IPrincipal principal = new GenericPrincipal (identity, roles);
ruleProvider = AuthorizationFactory .GetAuthorizationProvider("RuleProvider" );
authorized = ruleProvider.Authorize(principal, rule);
// 将当前的用户Identity 存入token
//if (authorized)
//{
// saveIdentity(identity);
//}
//}
}
else
{
WebMessageBox .Show(" 不是有效的用户!" , true );
}
return authorized;
}
#endregion
#region 对Token 的操作
// 将用户的Identity 存储到token 中, 方便以后使用
public static void saveIdentity(IIdentity identity)
{
//cache = SecurityCacheFactory.GetSecurityCacheProvider("Caching Store Provider");
if (identity != null )
{
token = securityCacheProvider.SaveIdentity(identity);
}
}
// 以token 来获取当前用户的Identity
private static IIdentity retrieveIdentity()
{
IIdentity savedIdentity = null ;
if (token != null )
{
savedIdentity = securityCacheProvider.GetIdentity(token);
}
return savedIdentity;
}
// 使当前用户的token 过期
private void expireToken()
{
if (token != null )
{
securityCacheProvider.ExpireIdentity(token);
}
}
#endregion
#region 授权 ,将用户添加到特定的角色
public static bool AddUserToRole(string username, string Role)
{
bool added = false ;
try
{
Roles .AddUsersToRole(new string [] { username }, Role);
added = true ;
return added;
}
catch (ProviderException ex)
{
WebMessageBox .Show(" 给用户:" + username + " 失败!" , ex.ToString());
return false ;
}
}
#endregion
#region 移除用户角色
public static bool RemoveUserFromRole(string name, string role)
{
bool removed = false ;
try
{
if (Roles .IsUserInRole(name, role))
{
Roles .RemoveUserFromRole(name, role);
//Roles.RoleExists(role);
removed = true ;
}
else
{
WebMessageBox .Show(name + " 用户不属于" + role + " 角色" );
}
return removed;
}
catch (Exception ex)
{
WebMessageBox .Show(" 在删除用户:" + name + " 时出现异常,删除失败!" , ex.ToString());
return false ;
}
}
#endregion
#region 添加角色
public static bool CreateRoles(string role)
{
bool added = false ;
if (!Roles .RoleExists(role))
{
Roles .CreateRole(role);
added = true ;
}
else {
WebMessageBox .Show(" 您要创建的角色已经存在。" );
}
return added;
}
#endregion
#region 删除角色
public static bool DeleteRoles(string role)
{
bool deleted = false ;
if (Roles .RoleExists(role))
{
Roles .DeleteRole(role);
deleted = true ;
}
else
{
WebMessageBox .Show(" 您要删除的角色已经存在。" );
}
return deleted;
}
#endregion
#region 验证用户是否在角色中
public static bool UserIsInRole(string name,string role)
{
if (Roles .IsUserInRole(name, role))
{
return true ;
}
else
{
return false ;
}
}
#endregion
#region 得到所有用户
public static MembershipUserCollection GetAllUsers()
{
return Membership .GetAllUsers();
}
#endregion
#region 得到所有的角色
public static string [] GetAllRoles()
{
string [] roles = Roles .GetAllRoles();
return roles;
}
#endregion
#region 得到单个用户所在的角色
public static string [] GetRolesbyName(string username)
{
if (username != null )
{
string [] roles = Roles .GetRolesForUser(username); return roles;
}
return null ;
}
#endregion
}
}