ASP.NET Security Provider实现(五)ProfileProvider

System.Web.Profile.ProfileProvider类

定义 ASP.NET 为使用自定义配置文件提供程序提供配置文件服务而实现的协定。

继承层次结构:
System.Object
  System.Configuration.Provider.ProviderBase
    System.Configuration.SettingsProvider
      System.Web.Profile.ProfileProvider
        System.Web.Profile.SqlProfileProvider


ASP.NET 配置文件提供对用户特定属性的持久性存储和检索。 配置文件属性值和信息按照由 ProfileProvider 实现确定的方式存储在数据源中。 您可以使用 .NET Framework 附带的配置文件提供程序(由派生自 ProfileProvider 抽象类的类表示),也可以通过创建派生自 ProfileProvider 的新类来实现自己的提供程序。

创建自定义配置文件提供程序有两个主要原因:

  • 您需要将配置文件信息存储在 .NET Framework 附带的配置文件提供程序不支持的数据源中,例如,FoxPro 数据库、Oracle 数据库或其他数据存储。
  • 您需要使用与 .NET Framework 附带的提供程序所用的数据库架构不同的数据库架构来管理配置文件信息。 例如,公司网络或网站的 SQL Server 数据库中已经存在的用户数据。

ProfileProvider 抽象类继承自 SettingsProvider 抽象类,后者继承自 ProviderBase 抽象类。 实现 ProfileProvider 的类也必须实现 SettingsProvider 和 ProviderBase 抽象类的必要成员。 有关实现配置文件提供程序的更多信息,请参见 实现配置文件提供程序。

 

MVCQuick的ProfileProvider实现

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using MVCQuick.Framework.Container;
using MVCQuick.Framework.Repository;

namespace MVCQuick.Framework.Security
{
///<summary>
/// 对 ASP.NET 应用程序的配置文件信息的存储进行管理。
///</summary>
public class ClassicProfileProvider : System.Web.Profile.ProfileProvider
{
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">要初始化的 ProfileProvider 实例的名称。</param>
///<param name="config">
/// 一个 NameValueCollection,包含配置文件提供程序的配置选项的名称和值。
///</param>
public override void Initialize(string name,
System.Collections.Specialized.NameValueCollection config)
{
if (config == null)
{
throw new ArgumentNullException("config");
}

if (String.IsNullOrEmpty(name))
{
name = "ClassicProfileProvider";
}

if (String.IsNullOrEmpty(config["description"]))
{
config.Remove("description");
config.Add("description", "MVCQuick.Framework.Security Profile 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="authenticationOption">
/// ProfileAuthenticationOption 值之一,指定是删除匿名配置文件、
/// 已验证的配置文件还是同时删除这两种类型的配置文件。
///</param>
///<param name="userInactiveSinceDate">
/// 一个 DateTime,确定将哪些用户配置文件视为处于不活动状态。
/// 如果用户配置文件的 LastActivityDate 与此日期和时间相同,
/// 或在此日期和时间之前,则此配置文件被视为处于不活动状态。
///</param>
///<returns>从数据源中删除的配置文件的数目。</returns>
public override int DeleteInactiveProfiles(
System.Web.Profile.ProfileAuthenticationOption authenticationOption,
DateTime userInactiveSinceDate)
{
return new ProfileService(repository).DeleteInactiveProfiles(this.applicationName,
authenticationOption, userInactiveSinceDate);

}

///<summary>
/// 从数据源中删除提供的一系列配置文件的配置文件属性和信息。
///</summary>
///<param name="profiles">一个 ProfileInfoCollection,包含要删除的配置文件的配置文件信息。</param>
///<returns>从数据源中删除的配置文件的数目。</returns>
public override int DeleteProfiles(System.Web.Profile.ProfileInfoCollection profiles)
{
if (profiles == null)
{
throw new ArgumentNullException("profiles");
}
if (profiles.Count < 1)
{
throw new ArgumentException("Parameter collection empty.");
}
string[] usernames = new string[profiles.Count];
int index = 0;
foreach (System.Web.Profile.ProfileInfo profileInfo in profiles)
{
usernames[index++] = profileInfo.UserName;
}
return DeleteProfiles(usernames);

}

///<summary>
/// 从数据源中删除提供的一系列用户名的配置文件属性和信息。
///</summary>
///<param name="usernames">要删除的配置文件的用户名字符串数组。</param>
///<returns>从数据源中删除的配置文件的数目。</returns>
public override int DeleteProfiles(string[] usernames)
{
SecUtility.CheckArrayParameter(ref usernames, true, true, true, 0x100, "usernames");

return new ProfileService(repository).DeleteProfiles(this.applicationName, usernames);

}

///<summary>
/// 检索一些配置文件的配置文件信息,在这些配置文件中,
/// 上次活动日期与指定的日期和时间相同或在其之前,而且配置文件的用户名与指定的名称匹配。
///</summary>
///<param name="authenticationOption">
/// ProfileAuthenticationOption 值之一,
/// 指定是返回匿名配置文件、经过身份验证的配置文件还是同时返回这两种类型的配置文件。
///</param>
///<param name="usernameToMatch">要搜索的用户名。</param>
///<param name="userInactiveSinceDate">
/// 一个 DateTime,确定将哪些用户配置文件视为处于不活动状态。
/// 如果用户配置文件的 LastActivityDate 与此日期和时间相同,
/// 或在此日期和时间之前,则此配置文件被视为处于不活动状态。
///</param>
///<param name="pageIndex">要返回的结果页的索引。pageIndex 从零开始。</param>
///<param name="pageSize">要返回的结果页的大小。</param>
///<param name="totalRecords">
/// 此方法返回时,会包含一个表示配置文件总数的整数。该参数未经初始化即被传递。
///</param>
///<returns>
/// 包含不活动配置文件的用户配置文件信息的 ProfileInfoCollection,
/// 这些不活动配置文件中的用户名与提供的 usernameToMatch 参数相匹配。
///</returns>
public override System.Web.Profile.ProfileInfoCollection FindInactiveProfilesByUserName(
System.Web.Profile.ProfileAuthenticationOption authenticationOption,
string usernameToMatch,
DateTime userInactiveSinceDate,
int pageIndex,
int pageSize,
out int totalRecords)
{
SecUtility.CheckParameter(ref usernameToMatch, true, true, false, 0x100, "username");

System.Web.Profile.ProfileInfoCollection profileInfoCollection =
new System.Web.Profile.ProfileInfoCollection();

IList<System.Web.Profile.ProfileInfo> profileInfos =
new ProfileService(repository).FindProfiles(
this.applicationName,
authenticationOption,
usernameToMatch,
userInactiveSinceDate,
pageIndex,
pageIndex,
out totalRecords);

foreach (var profileInfo in profileInfos)
{
profileInfoCollection.Add(profileInfo);
}

return profileInfoCollection;

}

///<summary>
/// 检索用户名与指定名称匹配的配置文件的配置文件信息。
///</summary>
///<param name="authenticationOption">
/// ProfileAuthenticationOption 值之一,
/// 指定是返回匿名配置文件、经过身份验证的配置文件还是同时返回这两种类型的配置文件。
///</param>
///<param name="usernameToMatch">要搜索的用户名。</param>
///<param name="pageIndex">要返回的结果页的索引。pageIndex 从零开始。</param>
///<param name="pageSize">要返回的结果页的大小。</param>
///<param name="totalRecords">
/// 此方法返回时,会包含一个表示配置文件总数的整数。该参数未经初始化即被传递。
///</param>
///<returns>
/// 包含配置文件中的用户配置文件信息的 ProfileInfoCollection,
/// 其中的用户名与提供的 usernameToMatch 参数相匹配。
///</returns>
public override System.Web.Profile.ProfileInfoCollection FindProfilesByUserName(
System.Web.Profile.ProfileAuthenticationOption authenticationOption,
string usernameToMatch,
int pageIndex, int pageSize, out int totalRecords)
{
SecUtility.CheckParameter(ref usernameToMatch, true, true, false, 0x100, "username");

System.Web.Profile.ProfileInfoCollection profileInfoCollection =
new System.Web.Profile.ProfileInfoCollection();

IList<System.Web.Profile.ProfileInfo> profileInfos =
new ProfileService(repository).FindProfiles(
this.applicationName,
authenticationOption,
usernameToMatch,
pageIndex,
pageIndex,
out totalRecords);

foreach (var profileInfo in profileInfos)
{
profileInfoCollection.Add(profileInfo);
}

return profileInfoCollection;
}

///<summary>
/// 对于上次活动日期与指定的日期和时间相同或在其之前的配置文件,检索它们的用户配置文件数据。

///</summary>
///<param name="authenticationOption">
/// ProfileAuthenticationOption 值之一,
/// 指定是返回匿名配置文件、经过身份验证的配置文件还是同时返回这两种类型的配置文件。
///</param>
///<param name="userInactiveSinceDate">
/// 一个 DateTime,确定将哪些用户配置文件视为处于不活动状态。
/// 如果用户配置文件的 LastActivityDate 与此日期和时间相同,
/// 或在此日期和时间之前,则此配置文件被视为处于不活动状态。
///</param>
///<param name="pageIndex">要返回的结果页的索引。pageIndex 从零开始。</param>
///<param name="pageSize">要返回的结果页的大小。</param>
///<param name="totalRecords">
/// 此方法返回时,会包含一个表示配置文件总数的整数。该参数未经初始化即被传递。
///</param>
///<returns>
/// 一个 ProfileInfoCollection,包含有关不活动的配置文件的用户配置文件信息。
///</returns>
public override System.Web.Profile.ProfileInfoCollection GetAllInactiveProfiles(
System.Web.Profile.ProfileAuthenticationOption authenticationOption,
DateTime userInactiveSinceDate,
int pageIndex, int pageSize, out int totalRecords)
{
System.Web.Profile.ProfileInfoCollection profileInfoCollection =
new System.Web.Profile.ProfileInfoCollection();

IList<System.Web.Profile.ProfileInfo> profileInfos =
new ProfileService(repository).GetAllInactiveProfiles(
this.applicationName,
authenticationOption,
userInactiveSinceDate,
pageIndex,
pageIndex,
out totalRecords);

foreach (var profileInfo in profileInfos)
{
profileInfoCollection.Add(profileInfo);
}

return profileInfoCollection;
}

///<summary>
/// 在数据源中检索配置文件的用户配置文件数据。
///</summary>
///<param name="authenticationOption">
/// ProfileAuthenticationOption 值之一,
/// 指定是返回匿名配置文件、经过身份验证的配置文件还是同时返回这两种类型的配置文件。
///</param>
///<param name="pageIndex">要返回的结果页的索引。pageIndex 从零开始。</param>
///<param name="pageSize">要返回的结果页的大小。</param>
///<param name="totalRecords">
/// 此方法返回时,会包含一个表示配置文件总数的整数。该参数未经初始化即被传递。
///</param>
///<returns>
/// 一个 ProfileInfoCollection,包含数据源中所有配置文件的用户配置文件信息。
///</returns>
public override System.Web.Profile.ProfileInfoCollection GetAllProfiles(
System.Web.Profile.ProfileAuthenticationOption authenticationOption,
int pageIndex, int pageSize, out int totalRecords)
{
System.Web.Profile.ProfileInfoCollection profileInfoCollection =
new System.Web.Profile.ProfileInfoCollection();

IList<System.Web.Profile.ProfileInfo> profileInfos =
new ProfileService(repository).GetAllProfiles(
this.applicationName,
authenticationOption,
pageIndex,
pageIndex,
out totalRecords);

foreach (var profileInfo in profileInfos)
{
profileInfoCollection.Add(profileInfo);
}

return profileInfoCollection;
}

///<summary>
/// 获取数据源中上次活动日期与指定的 userInactiveSinceDate 相同或在其之前的配置文件的数量。
///</summary>
///<param name="authenticationOption">
/// ProfileAuthenticationOption 值之一,
/// 指定是返回匿名配置文件、经过身份验证的配置文件还是同时返回这两种类型的配置文件。
///</param>
///<param name="userInactiveSinceDate">
/// 数据源中上次活动日期出现在指定日期和时间之前的配置文件的数量。
///</param>
///<returns>数据源中上次活动日期出现在指定日期和时间之前的配置文件的数量。</returns>
public override int GetNumberOfInactiveProfiles(
System.Web.Profile.ProfileAuthenticationOption authenticationOption,
DateTime userInactiveSinceDate)
{
return new ProfileService(repository).GetNumberOfInactiveProfiles(
this.applicationName,
authenticationOption,
userInactiveSinceDate);
}

///<summary>
/// 从配置文件数据库检索配置文件属性信息和值。
///</summary>
///<param name="sc">包含用户配置文件信息的 SettingsContext。</param>
///<param name="properties">
/// 一个 SettingsPropertyCollection,包含要检索的属性的配置文件信息。
///</param>
///<returns>包含配置文件属性信息和值的 SettingsPropertyValueCollection。</returns>
public override System.Configuration.SettingsPropertyValueCollection GetPropertyValues(
System.Configuration.SettingsContext sc,
System.Configuration.SettingsPropertyCollection properties)
{
System.Configuration.SettingsPropertyValueCollection settingsPropertyValueCollection =
new System.Configuration.SettingsPropertyValueCollection();

if (properties.Count < 1)
{
return settingsPropertyValueCollection;
}

string username = (string)sc["UserName"];

foreach (System.Configuration.SettingsProperty settingsProperty in properties)
{
if (settingsProperty.SerializeAs
== System.Configuration.SettingsSerializeAs.ProviderSpecific)
{
if (settingsProperty.PropertyType.IsPrimitive
|| (settingsProperty.PropertyType == typeof(string)))
{
settingsProperty.SerializeAs =
System.Configuration.SettingsSerializeAs.String;
}
else
{
settingsProperty.SerializeAs =
System.Configuration.SettingsSerializeAs.Xml;
}
}
settingsPropertyValueCollection.Add(
new System.Configuration.SettingsPropertyValue(settingsProperty));
}
if (!String.IsNullOrEmpty(username))
{
new ProfileService(repository).GetProperties(
this.applicationName,
username,
settingsPropertyValueCollection,
DateTime.UtcNow);
}


return settingsPropertyValueCollection;
}

///<summary>
/// 利用指定的属性值更新配置文件数据库。
///</summary>
///<param name="sc">包含用户配置文件信息的 SettingsContext。</param>
///<param name="properties">
/// 一个 SettingsPropertyValueCollection,包含要更新的属性的配置文件信息和值。
///</param>
public override void SetPropertyValues(System.Configuration.SettingsContext sc,
System.Configuration.SettingsPropertyValueCollection properties)
{
string username = (string)sc["UserName"];
bool isAuthenticated = (bool)sc["IsAuthenticated"];
if (username == null || username.Length < 1 || properties.Count < 1)
{
return;
}

new ProfileService(repository).SetProperties(
this.applicationName,
username,
properties,
isAuthenticated,
DateTime.UtcNow);

}
}
}

使用方法

Web Application项目中,修改Web config 配置文件。

    <profile defaultProvider="ClassicProfileProvider">
<providers>
<clear/>
<add name="ClassicProfileProvider" type="VCQuick.Framework.Security.ClassicProfileProvider" />
</providers>
<properties>
<add name="FirstName" allowAnonymous="true" />
<add name="LastName" allowAnonymous="true" />
</properties>
</profile>

 

源代码下载:http://mvcquick.codeplex.com/   

 

posted @ 2011-10-20 10:15  GuYoung  阅读(444)  评论(0编辑  收藏  举报