ASP.NET Security Provider实现(四)RoleProvider
System.Web.Security.RoleProvider类
定义 ASP.NET 为使用自定义角色提供程序提供角色管理服务而实现的协定。
继承层次结构:
System.Object
System.Configuration.Provider.ProviderBase
System.Web.Security.RoleProvider
System.Web.ClientServices.Providers.ClientRoleProvider
System.Web.Security.AuthorizationStoreRoleProvider
System.Web.Security.SqlRoleProvider
System.Web.Security.WindowsTokenRoleProvider
ASP.NET 角色管理旨在使您可以轻松地将多个不同的角色提供程序用于您的 ASP.NET 应用程序。 您可以使用 .NET Framework 附带的角色提供程序,也可以实现自己的提供程序。
实现自定义角色提供程序时,需要继承 RoleProvider 抽象类。
主要有两个原因需要创建自定义角色提供程序:
- 您需要将角色信息存储在 .NET Framework 附带的角色提供程序不支持的数据源中,例如,FoxPro 数据库、Oracle 数据库或其他数据源。
- 需要使用不同于 .NET Framework 包含的提供程序所使用的数据库架构来管理角色信息。 一个常见的例子就是公司网络或网站的 SQL Server 数据库中已经存在的角色数据。
MVCQuick的RoleProvider实现
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using MVCQuick.Framework.Repository;
using System.Collections.Specialized;
using MVCQuick.Framework.Container;
namespace MVCQuick.Framework.Security
{
///<summary>
/// ASP.NET 应用程序的角色成员资格信息的存储进行管理。
///</summary>
public class ClassicRoleProvider : System.Web.Security.RoleProvider
{
private string applicationName;
private IRepository repository;
///<summary>
/// 获取或设置要存储和检索其角色信息的应用程序的名称。
///</summary>
public override string ApplicationName
{
get
{
return applicationName;
}
set
{
if (String.IsNullOrEmpty(value))
{
throw new ArgumentNullException("Provider application name not null.");
}
if (value.Length > 255)
{
throw new System.Configuration.Provider.ProviderException("Provider application name too long.");
}
applicationName = value;
}
}
///<summary>
/// 利用在 ASP.NET 应用程序的配置文件中指定的属性值初始化角色提供程序。
/// 此方法不应从代码直接使用。
///</summary>
///<param name="name"></param>
///<param name="config"></param>
public override void Initialize(string name, NameValueCollection config)
{
if (config == null)
{
throw new ArgumentNullException("config");
}
if (String.IsNullOrEmpty(name))
{
name = "HibernateRoleProvider";
}
if (String.IsNullOrEmpty(config["description"]))
{
config.Remove("description");
config.Add("description", "MVCQuick.Framework.Security Role Provider");
}
base.Initialize(name, config);
this.applicationName = config["applicationName"];
if (String.IsNullOrEmpty(this.applicationName))
{
this.applicationName = SecUtility.GetDefaultAppName();
}
if (this.applicationName.Length > 255)
{
throw new System.Configuration.Provider.ProviderException(
"Provider application name is too long, max length is 255.");
}
string strRepository = config["repository"];
if (strRepository != null)
{
repository = ClassicContainer.GetObject(strRepository) as IRepository;
}
else
{
repository = ClassicContainer.GetObject<IRepository>() as IRepository;
}
if (!new ApplicationService(repository).ApplicationExists(this.applicationName))
{
new ApplicationService(repository).CreateApplication(this.applicationName);
}
config.Remove("repository");
config.Remove("applicationName");
if (config.Count > 0)
{
string attribUnrecognized = config.GetKey(0);
if (!String.IsNullOrEmpty(attribUnrecognized))
{
throw new System.Configuration.Provider.ProviderException(
"Provider unrecognized attribute: " + attribUnrecognized);
}
}
}
///<summary>
/// 将指定用户名添加到每个指定的角色。
///</summary>
///<param name="usernames">一个字符串数组,其中包含要添加到指定角色的用户名。</param>
///<param name="roleNames">一个字符串数组,其中包含要将指定用户名添加到的角色名称。</param>
public override void AddUsersToRoles(string[] usernames, string[] roleNames)
{
SecUtility.CheckArrayParameter(ref usernames, true, true, true, 255, "usernames");
SecUtility.CheckArrayParameter(ref roleNames, true, true, true, 255, "roleNames");
int status = new RoleService(repository).AddUsersToRoles(
this.applicationName,
usernames,
roleNames);
if (status != 0)
{
string errText = this.GetExceptionText(status);
throw new System.Configuration.Provider.ProviderException(errText);
}
}
///<summary>
/// 将新的角色添加到角色数据库。
///</summary>
///<param name="roleName">要创建的角色的名称。</param>
public override void CreateRole(string roleName)
{
SecUtility.CheckParameter(ref roleName, true, true, true, 255, "roleName");
int status = new RoleService(repository).CreateRole(
this.applicationName,
roleName);
if (status != 0)
{
string errText = this.GetExceptionText(status);
throw new System.Configuration.Provider.ProviderException(errText);
}
}
///<summary>
/// 从角色数据库移除一个角色。
///</summary>
///<param name="roleName">要删除的角色的名称。</param>
///<param name="throwOnPopulatedRole">
/// 如果为 true,则当 roleName 包含一个或多个成员时将引发异常。
///</param>
///<returns>如果成功删除角色,则为 true;否则为 false。</returns>
public override bool DeleteRole(string roleName, bool throwOnPopulatedRole)
{
SecUtility.CheckParameter(ref roleName, true, true, true, 255, "roleName");
int status = new RoleService(repository).DeleteRole(
this.applicationName,
roleName,
throwOnPopulatedRole);
if (status != 0)
{
return false;
}
return true;
}
///<summary>
/// 获取属于某个角色且与指定的用户名相匹配的用户名的数组。
///</summary>
///<param name="roleName">作为搜索范围的角色。</param>
///<param name="usernameToMatch">要搜索的用户名。</param>
///<returns>
/// 一个字符串数组,包含用户名与 usernameToMatch 匹配且用户是指定角色的成员的所有用户的名称。
///</returns>
public override string[] FindUsersInRole(string roleName, string usernameToMatch)
{
SecUtility.CheckParameter(ref roleName, true, true, true, 255, "roleName");
SecUtility.CheckParameter(ref usernameToMatch, true, true, false, 255, "usernameToMatch");
return new RoleService(repository).FindUsersInRole(
this.applicationName,
roleName,
usernameToMatch);
}
///<summary>
/// 获取应用程序的所有角色的列表。
///</summary>
///<returns>一个字符串数组,包含在特定应用程序的数据库中存储的所有角色的名称。</returns>
public override string[] GetAllRoles()
{
return new RoleService(repository).GetAllRoles(
this.applicationName);
}
///<summary>
/// 获取一个用户所属角色的列表。
///</summary>
///<param name="username">要为其返回角色列表的用户。</param>
///<returns>一个字符串数组,其中包含指定用户所属的所有角色的名称。</returns>
public override string[] GetRolesForUser(string username)
{
SecUtility.CheckParameter(ref username, true, false, true, 255, "username");
return new RoleService(repository).GetRolesForUser(
this.applicationName,
username);
}
///<summary>
/// 获取属于指定角色的用户的列表。
///</summary>
///<param name="roleName">一个角色名称,将获取该角色的用户列表。</param>
///<returns>一个字符串数组,其中包含指定角色拥有的所有成员的用户名。</returns>
public override string[] GetUsersInRole(string roleName)
{
SecUtility.CheckParameter(ref roleName, true, true, true, 255, "roleName");
return new RoleService(repository).GetUsersInRole(
this.applicationName,
roleName);
}
///<summary>
/// 获取一个指示指定用户是否属于指定角色的值。
///</summary>
///<param name="username">要搜索的用户名。</param>
///<param name="roleName">作为搜索范围的角色。</param>
///<returns>如果指定的用户名属于指定角色,则为 true;否则为 false。 </returns>
public override bool IsUserInRole(string username, string roleName)
{
SecUtility.CheckParameter(ref roleName, true, true, true, 255, "roleName");
SecUtility.CheckParameter(ref username, true, false, true, 255, "username");
return new RoleService(repository).IsUserInRole(this.applicationName, username, roleName);
}
///<summary>
/// 移除指定角色中的指定用户名。
///</summary>
///<param name="usernames">一个字符串数组,其中包含要从指定角色中移除的用户名。</param>
///<param name="roleNames">一个字符串数组,其中包含要将指定用户名从中移除的角色的名称。</param>
public override void RemoveUsersFromRoles(string[] usernames, string[] roleNames)
{
SecUtility.CheckArrayParameter(ref usernames, true, true, true, 255, "usernames");
SecUtility.CheckArrayParameter(ref roleNames, true, true, true, 255, "roleNames");
int status = new RoleService(repository).RemoveUsersFromRoles(this.applicationName, usernames, roleNames);
if (status != 0)
{
string errText = this.GetExceptionText(status);
throw new System.Configuration.Provider.ProviderException(errText);
}
}
///<summary>
/// 获取一个值,该值指示指定的角色名称是否已存在于角色数据库中。
///</summary>
///<param name="roleName">要在数据库中搜索的角色的名称。</param>
///<returns>如果角色名称已存在于数据库中,则为 true;否则为 false。 </returns>
public override bool RoleExists(string roleName)
{
SecUtility.CheckParameter(ref roleName, true, true, true, 255, "roleName");
return new RoleService(repository).RoleExists(this.applicationName, roleName);
}
private string GetExceptionText(int status)
{
string errText;
switch (status)
{
case 0:
return String.Empty;
case 1:
errText = "User not found.";
break;
case 2:
errText = "Role not found.";
break;
case 3:
errText = "This user already in role.";
break;
case 4:
errText = "Role is not empty.";
break;
case 5:
errText = "Role already exists.";
break;
default:
errText = "Provider error.";
break;
}
return errText;
}
}
}
使用方法
在Web Application项目中,修改Web config 配置文件。
<roleManager enabled="true" defaultProvider="ClassicRoleProvider" cacheRolesInCookie="true" cookieName=".ASPXROLES" cookieTimeout="60" cookiePath="/" cookieRequireSSL="false" cookieSlidingExpiration="true" cookieProtection="All">
<providers>
<clear/>
<add name="ClassicRoleProvider" type="MVCQuick.Framework.Security.ClassicRoleProvider" applicationName="MVCQuick"/>
</providers>
</roleManager>
创建角色
Roles.CreateRole("Administrator");
将用户加入到角色
Roles.AddUserToRole("admin", "Administrator");