在Web应用程序中使用[membership,roleManager]这两个配置实现并和配置文件中的验证配置有效集合来实现身份验证.
一般使用中,可以采用继承System.Web.Security.MembershipUser,System.Web.Security.MembershipProvider,System.Web.Security.RoleProvider实现自身的功能.
然而Windows应用程序中不存在这两个配置,与以上提到的基类.只有自己去实现.
需求出现,我想通过数据库管理我的用户,角色,权限等.又想实现与WEB配置的一致性,在将代码实现时可以容易过度到WEB应用.
在WEB应用中,我已经实现了自己的基于数据库的身份验证.那么现在只能安照WEB这个老虎来画自己的猫.
必须实现成员资格配置的支持.
DbMembershipElement,DbMembershipProvider,DbMembershipProviderCollection
实现成员资格 membership 节点
与实现成员资格的代码一样去实现这三个类,具体代码省略
为实现与WEB一致的代码,则需要Membership静态类
成员验证的事例代码
一般使用中,可以采用继承System.Web.Security.MembershipUser,System.Web.Security.MembershipProvider,System.Web.Security.RoleProvider实现自身的功能.
然而Windows应用程序中不存在这两个配置,与以上提到的基类.只有自己去实现.
需求出现,我想通过数据库管理我的用户,角色,权限等.又想实现与WEB配置的一致性,在将代码实现时可以容易过度到WEB应用.
在WEB应用中,我已经实现了自己的基于数据库的身份验证.那么现在只能安照WEB这个老虎来画自己的猫.
首先看一下,app.config的最终结果
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<configSections>
<section name="membership" type="NXDO.WinUI.User.DbMembershipProvider, NXDO.WinUI.V2011, Version=1.0.0.0, Culture=neutral, PublicKeyToken=a3a15b70fe786e3e" />
<section name="roleManager" type="NXDO.WinUI.User.DbRoleProvider, NXDO.WinUI.V2011, Version=1.0.0.0, Culture=neutral, PublicKeyToken=a3a15b70fe786e3e" />
</configSections>
<membership ConfigSource="App.win.member.config"/>
<roleManager ConfigSource="App.win.role.config"/>
</configuration>
必须实现成员资格配置的支持.
DbMembershipElement,DbMembershipProvider,DbMembershipProviderCollection
//App.win.member.config
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<section name="membership" type="NXDO.WinUI.User.DbMembershipProvider, NXDO.WinUI.V2011, Version=1.0.0.0, Culture=neutral, PublicKeyToken=a3a15b70fe786e3e" />
</configSections>
<membership>
<providers>
<clear/>
<add
name="DbMembershipProvider"
type="NXDO.WinUI.User.DbMembershipProvider"
enablePasswordRetrieval="true"
enablePasswordReset="true"
requiresQuestionAndAnswer="false"
requiresUniqueEmail="false"
userOrmAssembly ="LYTemple.DbOrm.MgrUser;LYTemple.DbOrm"
userOrmAnswerName ="RealName"
userOrmActiveName ="StateFlag=1"
userOrmPasswordName ="Password"
userOrmDefaultValue="UserName='';StateFlag=1;RoleID=0"
userOrmPropertyMap="UserName=UserName;ProviderUserKey=UserID;Email,PasswordQuestion;Comment;IsApproved;IsLockedOut;CreationDate;LastLoginDate;LastActivityDate;LastPasswordChangedDate;LastLockoutDate"
/>
<!--
userOrmActiveName说明:实体类中属性为何值时是激活用户
userOrmPasswordName说明:实体类中保存密码的字段名称 (必须配置)
userOrmAnswerName说明:实体类中保存问题答案的字段名称
requiresQuestionAndAnswer=true,
1)必须设置PasswordQuestion映射
2)必须设置userOrmAnswerName的值
requiresUniqueEmail=true,
1)必须设置Email映射
userOrmDefaultValue说明: (可以不配置,但必须保证实体类的必填属性都有值)
如果不存在对应的赋值映射设置,则采用默认设置的值(为解决ORM执行添加时有必填项)
userOrmPropertyMap说明: A(MembershipUser属性名) = B(Orm实体类属性名),
这个映射配置为了在CreateUser方法中,将MembershipUser的值赋给Orm实体类
注意:ProviderUserKey = [Orm关键字字段的映射]
-->
</providers>
</membership>
</configuration>
实现成员资格 membership 节点
public sealed class DbMembershipElement : ConfigurationElement
{
public DbMembershipElement() : this("DbMembershipProvider") { }
public DbMembershipElement(string elementName)
{
Name = elementName;
}
[ConfigurationProperty("name", DefaultValue = "DbMembershipProvider", IsRequired = true, IsKey = true)]
public string Name
{
get
{
return (string)this["name"];
}
set
{
this["name"] = value;
}
}
[ConfigurationProperty("type", DefaultValue = "NXDO.WinUI.User.DbMembershipProvider", IsRequired = true)]
public string Type
{
get
{
return (string)this["type"];
}
set
{
this["type"] = value;
}
}
[ConfigurationProperty("minRequiredPasswordLength", DefaultValue = 6)]
public int MinRequiredPasswordLength
{
get
{
return (int)this["minRequiredPasswordLength"];
}
set
{
this["minRequiredPasswordLength"] = value;
}
}
[ConfigurationProperty("passwordStrengthRegularExpression", DefaultValue = "")]
public string PasswordStrengthRegularExpression
{
get
{
return (string)this["passwordStrengthRegularExpression"];
}
set
{
this["passwordStrengthRegularExpression"] = value;
}
}
[ConfigurationProperty("maxInvalidPasswordAttempts", DefaultValue = 3)]
public int MaxInvalidPasswordAttempts
{
get
{
return (int)this["maxInvalidPasswordAttempts"];
}
set
{
this["maxInvalidPasswordAttempts"] = value;
}
}
[ConfigurationProperty("passwordAttemptWindow", DefaultValue = 10)]
public int PasswordAttemptWindow
{
get
{
return (int)this["passwordAttemptWindow"];
}
set
{
this["passwordAttemptWindow"] = value;
}
}
[ConfigurationProperty("minRequiredNonAlphanumericCharacters", DefaultValue = 1)]
public int MinRequiredNonAlphanumericCharacters
{
get
{
return (int)this["minRequiredNonAlphanumericCharacters"];
}
set
{
this["minRequiredNonAlphanumericCharacters"] = value;
}
}
[ConfigurationProperty("enablePasswordRetrieval", DefaultValue = true)]
public bool EnablePasswordRetrieval
{
get
{
return (bool)this["enablePasswordRetrieval"];
}
set
{
this["enablePasswordRetrieval"] = value;
}
}
[ConfigurationProperty("enablePasswordReset", DefaultValue = true)]
public bool EnablePasswordReset
{
get
{
return (bool)this["enablePasswordReset"];
}
set
{
this["enablePasswordReset"] = value;
}
}
[ConfigurationProperty("requiresQuestionAndAnswer", DefaultValue = false)]
public bool RequiresQuestionAndAnswer
{
get
{
return (bool)this["requiresQuestionAndAnswer"];
}
set
{
this["requiresQuestionAndAnswer"] = value;
}
}
[ConfigurationProperty("requiresUniqueEmail", DefaultValue = false)]
public bool RequiresUniqueEmail
{
get
{
return (bool)this["requiresUniqueEmail"];
}
set
{
this["requiresUniqueEmail"] = value;
}
}
[ConfigurationProperty("userOrmAssembly", IsRequired = true)]
public string UserOrmAssembly
{
get
{
return (string)this["userOrmAssembly"];
}
set
{
this["userOrmAssembly"] = value;
}
}
[ConfigurationProperty("userOrmActiveName")]
public string UserOrmActiveName
{
get
{
return (string)this["userOrmActiveName"];
}
set
{
this["userOrmActiveName"] = value;
}
}
[ConfigurationProperty("userOrmAnswerName")]
public string UserOrmAnswerName
{
get
{
return (string)this["userOrmAnswerName"];
}
set
{
this["userOrmAnswerName"] = value;
}
}
[ConfigurationProperty("userOrmPasswordName")]
public string UserOrmPasswordName
{
get
{
return (string)this["userOrmPasswordName"];
}
set
{
this["userOrmPasswordName"] = value;
}
}
[ConfigurationProperty("userOrmDefaultValue")]
public string UserOrmDefaultValue
{
get
{
return (string)this["userOrmDefaultValue"];
}
set
{
this["userOrmDefaultValue"] = value;
}
}
[ConfigurationProperty("userOrmPropertyMap", IsRequired = true)]
public string UserOrmPropertyMap
{
get
{
return (string)this["userOrmPropertyMap"];
}
set
{
this["userOrmPropertyMap"] = value;
}
}
}
实现成员资格提供程序集合
public sealed class DbMembershipProviderCollection : ConfigurationElementCollection
{
public DbMembershipProviderCollection()
{
DbMembershipElement elem = (DbMembershipElement)CreateNewElement("");
this.Add(elem);
}
public override ConfigurationElementCollectionType CollectionType
{
get
{
return ConfigurationElementCollectionType.AddRemoveClearMap;
}
}
protected override ConfigurationElement CreateNewElement()
{
return new DbMembershipElement();
}
protected override ConfigurationElement CreateNewElement(string elementName)
{
return new DbMembershipElement(elementName);
}
protected override Object GetElementKey(ConfigurationElement element)
{
return ((DbMembershipElement)element).Name;
}
public new string AddElementName
{
get
{ return base.AddElementName; }
set
{ base.AddElementName = value; }
}
public new string ClearElementName
{
get
{ return base.ClearElementName; }
set
{ base.AddElementName = value; }
}
public new string RemoveElementName
{
get
{ return base.RemoveElementName; }
}
public new int Count
{
get { return base.Count; }
}
public DbMembershipElement this[int index]
{
get
{
return (DbMembershipElement)BaseGet(index);
}
set
{
if (BaseGet(index) != null)
{
BaseRemoveAt(index);
}
BaseAdd(index, value);
}
}
new public DbMembershipElement this[string Name]
{
get
{
return (DbMembershipElement)BaseGet(Name);
}
}
public int IndexOf(DbMembershipElement elem)
{
return BaseIndexOf(elem);
}
public void Add(DbMembershipElement elem)
{
BaseAdd(elem);
}
protected override void BaseAdd(ConfigurationElement element)
{
BaseAdd(element, false);
}
public void Remove(DbMembershipElement elem)
{
if (BaseIndexOf(elem) >= 0)
BaseRemove(elem.Name);
}
public void RemoveAt(int index)
{
BaseRemoveAt(index);
}
public void Remove(string name)
{
BaseRemove(name);
}
public void Clear()
{
BaseClear();
}
}
实现成员资格提供程序 membership 节点下的 add信息的配置
public sealed class DbMembershipProvider : ConfigurationSection , IMembershipProvider
{
//省略初始化数据等代码
void initData()
{
...
}
internal static DbMembershipProvider Get()
{
Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
DbMembershipProvider dbMember = config.GetSection("membership") as DbMembershipProvider;
if (dbMember == null)
{
config = ConfigurationManager.OpenExeConfiguration(System.Windows.Forms.Application.ExecutablePath);
dbMember = config.GetSection("membership") as DbMembershipProvider;
if (dbMember == null)
throw new ConfigurationErrorsException("请检查您的应用程序配置文件中是否设置了membership支持!");
}
//不为空,则说明:在其它配置文件中对应
if (!string.IsNullOrEmpty(dbMember.ConfigSource))
{
string tmpSource = dbMember.ConfigSource;
string fileName = AppDomain.CurrentDomain.BaseDirectory;
fileName = Path.Combine(fileName, tmpSource);
if (!File.Exists(fileName))
throw new FileNotFoundException(string.Format("当前运行目录下缺少用户对应的配置文件,{0}.", tmpSource));
ExeConfigurationFileMap ecfm = new ExeConfigurationFileMap();
ecfm.ExeConfigFilename = fileName;
Configuration conf = ConfigurationManager.OpenMappedExeConfiguration(ecfm, ConfigurationUserLevel.None);
dbMember = conf.GetSection("membership") as DbMembershipProvider;
//System.Diagnostics.Debug.WriteLine(dbMember.Providers[0].Name);
}
dbMember.initData();
return dbMember;
}
#region config元素的属性
/// <summary>
/// 配置的文件源
/// <remarks>(ConfigSource,注意WEB配置中为小写,自定义的不能使用config小写,为系统所保留)</remarks>
/// </summary>
[ConfigurationProperty("ConfigSource" )]
public string ConfigSource
{
get { return (string)this["ConfigSource"]; }
set { this["ConfigSource"] = value; }
}
[ConfigurationProperty("providers", IsDefaultCollection = false)]
public DbMembershipProviderCollection Providers
{
get
{
DbMembershipProviderCollection pCollection = (DbMembershipProviderCollection)base["providers"];
return pCollection;
}
}
#endregion
//用户验证
public bool ValidateUser(string username, string password)
{
return this.ValidateUser(username, password, false);
}
//用户验证
internal bool ValidateUser(string username, string password, bool updateLastLoginDate)
{
//根据数据库配置,搜索成员等代码省略
...
string[] roleNames = new string[] { };
//角色提供程序,在下面的文章中说明
DbRoleProvider dbRoleProvider = null;
bool bIsAdmin = false;
if (DbRoleProvider.IsExistsConfig(out dbRoleProvider))
{
roleNames = Role.GetRolesForUser(username);
bIsAdmin = Role.GetRoleIsAdministrator(roleNames);
}
//在下面的文章中说明
MemberIdentity mbmIdentity = new MemberIdentity(username, "application");
MemberPrincipal mbmPrincipal = new MemberPrincipal(mbmIdentity, roleNames);
mbmPrincipal.IsAdministrator = bIsAdmin;
System.Threading.Thread.CurrentPrincipal = mbmPrincipal;
return true;
}
}
角色提供程序的支持,实现三个类:DbRoleElement,DbRoleProvider,DbRoleProviderCollection
//App.win.role.config
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<section name="roleManager" type="NXDO.WinUI.User.DbRoleProvider, NXDO.WinUI.V2011, Version=1.0.0.0, Culture=neutral, PublicKeyToken=a3a15b70fe786e3e" />
</configSections>
<roleManager>
<providers>
<clear />
<add
name="DbRoleProvider"
type="NXDO.WinUI.User.DbRoleProvider"
applicationName="LYTemple.Mgr"
userOrmAssembly ="LYTemple.DbOrm.MgrUser;LYTemple.DbOrm"
roleOrmAssembly ="LYTemple.DbOrm.MgrRole;LYTemple.DbOrm"
userOrmUserName="UserName"
roleOrmRoleName="RoleName"
roleOrmDefaultValue=""
roleOrmItemName="RoleItem"
roleOrmValueName="RoleValue"
roleOrmAdminName="IsAdmin"
roleOrmPropertyMap="RoleID=RoleID"
/>
<!--
//userRoleSubOrmAssembly ="ClassLibrary1.Test_UserRoles;ClassLibrary1"
userOrmAssembly:成员实体类定义
roleOrmAssembly:角色实体类定义
userRoleSubOrmAssembly:成员对应多个角色的子表实体类定义
//userRoleSubOrmAssembly详细说明如下:
1)userRoleSubOrmAssembly的设置,标识一个成员:多个角色(1:n)
2)userRoleSubOrmAssembly不设置,则在成员表将角色关键字段作为一个外键字段,通过[roleOrmPropertyMap]设置关联
3)目前版本不支持1:n
userOrmUserName:成员实体类中,用户名对应的属性名称
roleOrmRoleName:角色实体类中,角色名对应的属性名称
roleOrmDefaultValue:添加角色时,所使用的默认值,使用;分割
roleOrmItemName:角色实体类中,角色权限项所对应的属性名称
roleOrmValueName:角色实体类中,角色中存放权限值所对应的属性名称
roleOrmAdminName:角色实体类中,角色中存放是否为管理员所对应的属性名称
roleOrmPropertyMap说明: A(成员实体类属性名) = B(角色实体类属性名),
//角色与成员通过哪个字段进行关联的
-->
</providers>
</roleManager>
</configuration>
与实现成员资格的代码一样去实现这三个类,具体代码省略
public sealed class DbRoleElement : ConfigurationElement
{
...
}
public sealed class DbRoleProviderCollection : ConfigurationElementCollection
{
...
}
//参考System.Web.Security.RoleProvider的方法,去实现本类
IRoleProvider接口的方法为[System.Web.Security.RoleProvider的方法]
public sealed class DbRoleProvider : ConfigurationSection, IRoleProvider
{
...
}
为实现与WEB一致的代码,则需要Membership静态类
//参考System.Web.Security.Membership的方法,来实现本类
public static class Membership
{
static Membership()
{
DbMembershipProvider provider = DbMembershipProvider.Get();
shipProvider = provider;
}
static DbMembershipProvider shipProvider;
/// <summary>
/// 获取对应用程序的默认成员资格提供程序的引用
/// </summary>
public static IMembershipProvider Provider
{
get
{
return shipProvider;
}
}
/// <summary>
/// 验证提供的用户名和密码是有效的
/// </summary>
/// <param name="username">要验证的用户的名称</param>
/// <param name="password">指定的用户的密码</param>
/// <returns>如果提供的用户名和密码有效,则返回 true;否则返回 false</returns>
public static bool ValidateUser(string username, string password)
{
return shipProvider.ValidateUser(username, password);
}
//省略其它代码
...
}
成员验证的事例代码
bool b = Membership.ValidateUser(this.tUser.Text, this.tPwd.Text);
if (!b)
{
//"用户名与密码验证错误.";
return;
}
MembershipUser user = Membership.GetUser(this.tUser.Text);
if (!user.IsApproved)
{
//string.Format("用户{0}已被禁用.",this.tUser.Text);
return;
}
this.DialogResult = System.Windows.Forms.DialogResult.OK;