ASP.NET Provider模型(三)

本文将自定义自己的两个 Providers-- 一个是成员 membership Provider ,另外一个是角色 Role Provider

 

为什么开发自定义MembershipRoleProvider

怎么说呢,原因可能很多,下面列出了部分原因:

你使用了其它数据库(也就是不是SQL Server或者Access数据库)来存放你的数据

你使用了一些非标准的数据库而这些数据库并没有内置的membershiprole Providers模型

你想要执行数据在包含和检索过程具有加密的功能

你想要自己写数据库的处理而非以来于membershiprole Provider模型

需求

现在让我们决定自定的membershiprole Provider需要什么要求:

我们想要使用我们自己的数据库来存放membershiprole信息,这就意味者我们不需要使用中间数据存储应用程序的名称

我们使用自定义的Users表来存放成员关系的详细信息

我们使用自定义的Roles表存放系统里可以使用的角色

我们使用UserRoles表来映射User-Role的关联

为了简化本示例,我们不再提供如下功能

密码的“加密-解密”功能

用户注册时主要输入用户名,密码和邮件即可,不用输入安全提问和答案

我们不需要诸如密码恢复,账号锁定等功能

数据访问

 这里我们使用BinaryIntellect DatabaseHelper 来完成本模块的数据库访问

建立Web站点

 首先,建立一个Web站点,然后在App_Code目录学建立两个类:MyMembershipProvider MyRoleProvider。为了简化应用程序,我们建立webSite本身需要的必要类。在实际的应用中,你可以建立单独的类来包含这些类。

配置Web应用程序使用自定义Providers

 打开web.config并增加如下的标记:

<membership defaultProvider="mymembershipprovider">

<providers>

<add name="mymembershipprovider"

type="MyMembershipProvider"

connectionStringName="connstr"/>

</providers>

</membership>

<roleManager enabled="true" defaultProvider="myrolesprovider">

<providers>

<add name="myrolesprovider"

type="MyRolesProvider"

connectionStringName="connstr"/>

</providers>

</roleManager>

在这两段代码里,我们告诉ASP.NET系统使用MyMembershipProvider类来作为成员关系的提供者,使用MyRolesProvider类来作为角色的提供者,建立自定义成员关系的Provider

回忆一下第二部分介绍的程序关系Provider模型,我们需要从System.Web.Security.MembershipProvider 类派生出自定义的成员类

MembershipProvider类又是从ProviderBase类继承而来。MembershipProvider类包含几个抽象的方法,你可以在你自定义的类中使用这些方法

如果你使用的是VS.NET开发环境,那么你可以减轻开发的工作。在MembershipProvider类的定义处右击属性,转到MembershipProvider类的定义可以看到其属性/方法

下面列出了改类属性/方法以及意义的列表

(天天注:这里的意义翻译并没有取之原文,因为中文版本的MSDN已经提供了,你可以查看Member Provider类的成员列表)

属性/方法

意义

Initialize()*

初始化提供程序。在这里获取web.config里数据库链接字符串的值,我们需要在自己的类里进行数据库处理

Name*

这里程序自定义Provider的名称。

CreateUser()*

建立一个用户

UpdateUser()*

保护注册用户资料的更改

DeleteUser()*

删除一个用户

GetUser()*

获取一个MembershipUser对象实例

GetAllUsers()*

获取MembershipUserCollection里用户的集合

ChangePassword()*

更改密码

GetPassword()*

从数据源获取指定用户名所对应的密码。

ValidateUser()*

验证数据源中是否存在指定的用户名和密码。

EnablePasswordReset*

指示成员资格提供程序是否配置为允许用户重置其密码。

EnablePasswordRetrieval*

指示成员资格提供程序是否配置为允许用户检索其密码。

RequiresQuestionAndAnswer*

获取一个值,该值指示成员资格提供程序是否配置为要求用户在进行密码重置和检索时回答密码提示问题。

RequiresUniqueEmail*

获取一个值,指示成员资格提供程序是否配置为要求每个用户名具有唯一的电子邮件地址。

ApplicationName

使用自定义成员资格提供程序的应用程序的名称。

MaxInvalidPasswordAttempts

获取锁定成员资格用户前允许的无效密码或无效密码提示问题答案尝试次数。

MinRequiredNonAlphanumericCharacters

获取有效密码中必须包含的最少特殊字符数。

MinRequiredPasswordLength

获取密码所要求的最小长度。

ChangePasswordQuestionAndAnswer()

处理更新成员资格用户的密码提示问题和答案的请求。

FindUsersByEmail()

获取一个成员资格用户的集合,这些用户的电子邮件地址包含要匹配的指定电子邮件地址。

FindUsersByName()

获取一个成员资格用户的集合,这些用户的用户名包含要匹配的指定用户名。

GetNumberOfUsersOnline()

获取当前访问该应用程序的用户数。

GetUser()

从数据源获取成员资格用户的信息。

GetUserNameByEmail()

利用邮件获取用户名

PasswordAttemptWindow

指示密码输入间隔的时间

PasswordFormat

密码格式,例如明文,Hash表等

PasswordStrengthRegularExpression

密码使用的正则表达式

ResetPassword()

重置用户密码

UnlockUser()

接锁用户

在我们的代码里,我们将重载上面列出的前面具有“*”标记的属性或者方法,其它的属性方法只简单的抛出一个“没有执行”的异常

完整的源代码请见下载文件里的MyMembershipProvider.cs,部分代码如下

(天天注:这里引用了更多的源代码)

 

  1 using  BinaryIntellect.DataAccess;
  2
  3 public   class  MyMembershipProvider:MembershipProvider
  4 {
  5    private DatabaseHelper db = null;
  6public override void Initialize(string name, System.Collections.Specialized.NameValueCollection config)
  7    {
  8string connstr = ConfigurationManager.ConnectionStrings[config["connectionStringName"]].ConnectionString;
  9        db = new DatabaseHelper(connstr);
 10    }

 11
 12    public override string Name
 13    {    
 14        get 
 15        
 16           return "MyMembershipProvider";     }

 17    }

 18
 19    public override MembershipUser CreateUser(string username, string password, string email, string passwordQuestion, string passwordAnswer, bool isApproved, object providerUserKey, out MembershipCreateStatus status)
 20    {
 21        MembershipUser user = new MembershipUser(Name, username, providerUserKey, email, passwordQuestion, null, isApproved, false, DateTime.Now, DateTime.Now, DateTime.Now, DateTime.Now, DateTime.Now);
 22        string sql = "INSERT INTO USERS(USERNAME,PASSWORD,EMAIL,ISACTIVE) VALUES(@UID,@PWD,@EMAIL,@ISACTIVE)";
 23        db.AddParameter("@UID", username);
 24        db.AddParameter("@PWD", password);
 25        db.AddParameter("@EMAIL", email);
 26        db.AddParameter("@ISACTIVE", (isApproved == true ? "Y" : "N"));
 27        int i = db.ExecuteNonQuery(sql);
 28        if (i > 0)
 29        {
 30            status = MembershipCreateStatus.Success;
 31            return user;
 32        }

 33
 34        else
 35        {
 36            status = MembershipCreateStatus.ProviderError;
 37            return null;
 38        }

 39    }

 40
 41    public override void UpdateUser(MembershipUser user)
 42    {
 43        string sql = "UPDATE USERS SET EMAIL=@EMAIL,ISACTIVE=@ISACTIVE WHERE USERNAME=@UID";
 44        db.AddParameter("@EMAIL", user.Email);
 45        db.AddParameter("@ISACTIVE", (user.IsApproved ? "Y" : "N"));
 46        db.AddParameter("@UID", user.UserName);
 47        int i = db.ExecuteNonQuery(sql);
 48    }

 49
 50    public override bool DeleteUser(string username, bool deleteAllRelatedData)
 51    {
 52        string sql = "DELETE FROM USERS WHERE USERNAME=@UID";
 53        db.AddParameter("@UID", username);
 54        int i = db.ExecuteNonQuery(sql);
 55        if (i > 0)
 56            return true;
 57        else
 58            return false;
 59    }

 60
 61    public override MembershipUser GetUser(string username, bool userIsOnline)
 62    {
 63        MembershipUser user = null;
 64
 65        string sql = "SELECT * FROM USERS WHERE USERNAME=@UID AND ISACTIVE='Y'";
 66
 67        db.AddParameter("@UID", username);
 68
 69        SqlDataReader reader = (SqlDataReader)db.ExecuteReader(sql);
 70
 71        while (reader.Read())
 72        {
 73            user = new MembershipUser(Name, reader.GetString(reader.GetOrdinal("username")), null, reader.GetString(reader.GetOrdinal("email")), nullnull, (reader.GetString(reader.GetOrdinal("isactive")) == "Y" ? true : false), false, DateTime.MinValue, DateTime.MinValue, DateTime.MinValue, DateTime.MinValue, DateTime.MinValue);
 74        }

 75
 76        reader.Close();
 77        return user;
 78    }

 79
 80    public override MembershipUserCollection GetAllUsers(int pageIndex, int pageSize, out int totalRecords)
 81    {
 82        MembershipUserCollection users = new MembershipUserCollection();
 83
 84        object obj=db.ExecuteScalar("SELECT COUNT(*) FROM USERS");
 85
 86        int reccount=0;
 87
 88        if (obj != null)
 89            reccount = (int)obj;
 90
 91        SqlDataReader reader = (SqlDataReader)db.ExecuteReader("SELECT * FROM USERS ORDER BY USERNAME");
 92
 93        while (reader.Read())
 94        {
 95            MembershipUser user = new MembershipUser(Name, reader.GetString(reader.GetOrdinal("username")), null, reader.GetString(reader.GetOrdinal("email")), nullnull, (reader.GetString(reader.GetOrdinal("isactive")) == "Y" ? true : false), false, DateTime.MinValue, DateTime.MinValue, DateTime.MinValue, DateTime.MinValue, DateTime.MinValue);
 96            users.Add(user);
 97        }

 98        reader.Close();
 99        totalRecords = reccount;
100        return users;
101    }

102
103    #endregion
104
105    Password Management#region Password Management
106
107    public override bool ChangePassword(string username, string oldPassword, string newPassword)
108    {
109        string sql = "UPDATE USERS SET PASSWORD=@NEWPWD WHERE USERNAME=@UID AND PASSWORD=@OLDPWD";
110        db.AddParameter("@NEWPWD", newPassword);
111        db.AddParameter("@UID", username);
112        db.AddParameter("@OLDPWD", oldPassword);
113        int i = db.ExecuteNonQuery(sql);
114        if (i > 0)
115            return true;
116        else
117            return false;
118    }

119
120    public override string GetPassword(string username, string answer)
121    {
122        string sql = "SELECT PASSWORD FROM USERS WHERE USERNAME=@UID";
123        db.AddParameter("@UID", username);
124        object obj = db.ExecuteScalar(sql);
125        if (obj != null)
126            return obj.ToString();
127        else
128            return "";
129    }

130
131    #endregion

132
133    Authentication#region Authentication
134
135    public override bool ValidateUser(string username, string password)
136    {
137        string sql = "SELECT USERNAME FROM USERS WHERE USERNAME=@UID AND PASSWORD=@PWD";
138
139        db.AddParameter("@PWD", password);
140
141        db.AddParameter("@UID", username);
142
143        string uid = db.ExecuteScalar(sql) as string;
144
145        if (uid == null)
146        {
147            return false;
148        }

149
150        else
151        {
152            return true;
153        }

154    }

155
156    #endregion

157
158    Provider Configuration#region Provider Configuration
159
160    public override bool EnablePasswordReset
161    {
162        get
163        {
164            return false;
165        }

166    }

167
168    public override bool EnablePasswordRetrieval
169    {
170        get 
171        {
172            return true;
173        }

174    }

175
176    public override bool RequiresQuestionAndAnswer
177    {
178        get
179        {
180            return false;
181        }

182    }

183
184    public override bool RequiresUniqueEmail
185    {
186        get
187        {
188            return false;
189        }

190    }

191    #endregion

192}

193
194

建立自定义的角色Provider

 该类完成列表请参考MSDN:RoleProvider

属性/方法

意义

Initialize()*

初始化提供程序。

Name*

显示自定义Provider的名称

CreateRole*

在数据源中为已配置的 applicationName 添加一个新角色。

DeleteRole*

从数据源中移除已配置的 applicationName 的角色。

GetAllRoles*

获取已配置的 applicationName 的所有角色的列表。

RoleExists*

获取一个值,该值指示指定角色名是否已存在于已配置的 applicationName 的角色数据源中。

AddUsersToRoles*

将指定用户名添加到已配置的 applicationName 的指定角色名。

RemoveUsersFromRoles*

移除已配置的 applicationName 的指定角色中的指定用户名。

GetRolesForUser*

获取指定用户对于已配置的 applicationName 所属于的角色的列表。

GetUsersInRole*

获取属于已配置的 applicationName 的指定角色的用户的列表。

IsUserInRole*

获取一个值,指示指定用户是否属于已配置的 applicationName 的指定角色。

ApplicationName

获取或设置要存储和检索其角色信息的应用程序的名称。

FindUsersInRole

获取属于某个角色且与指定的用户名相匹配的用户名的数组。

在我们的代码里,我们将重载上面列出的前面具有“*”标记的属性或者方法,其它的属性方法只简单的抛出一个“没有执行”的异常

下面列出了部分代码

 

  1 using  System;
  2
  3 using  System.Data;
  4
  5 using  System.Data.SqlClient;
  6
  7 using  System.Configuration;
  8
  9 using  System.Web;
 10
 11 using  System.Web.Security;
 12
 13 using  System.Web.UI;
 14
 15 using  System.Web.UI.WebControls;
 16
 17 using  System.Web.UI.WebControls.WebParts;
 18
 19 using  System.Web.UI.HtmlControls;
 20
 21 using  BinaryIntellect.DataAccess;
 22
 23 using  System.Collections;
 24
 25 public   class  MyRolesProvider:RoleProvider
 26
 27 {
 28
 29    private DatabaseHelper db = null;
 30
 31    General#region General
 32
 33    public override void Initialize(string name, System.Collections.Specialized.NameValueCollection config)
 34
 35    {
 36
 37        string connstr = ConfigurationManager.ConnectionStrings[config["connectionStringName"]].ConnectionString;
 38
 39        db = new DatabaseHelper(connstr);
 40
 41    }

 42
 43    public override string Name
 44
 45    {
 46
 47        get
 48
 49        {
 50
 51            return "MyRolesProvider";
 52
 53        }

 54
 55    }

 56
 57    #endregion

 58
 59    Role Management#region Role Management
 60
 61    public override void CreateRole(string roleName)
 62
 63    {
 64
 65        db.AddParameter("@ROLE", roleName);
 66
 67        db.ExecuteNonQuery("INSERT INTO ROLES(ROLENAME) VALUES(@ROLE)");
 68
 69    }

 70
 71    public override bool DeleteRole(string roleName, bool throwOnPopulatedRole)
 72
 73    {
 74
 75        db.AddParameter("@ROLE", roleName);
 76
 77        int i = db.ExecuteNonQuery("DELETE FROM ROLES WHERE ROLENAME=@ROLE");
 78
 79        if (i > 0)
 80
 81            return true;
 82
 83        else
 84
 85            return false;
 86
 87    }

 88
 89    public override string[] GetAllRoles()
 90
 91    {
 92
 93        int reccount = (int)db.ExecuteScalar("SELECT COUNT(*) FROM ROLES");
 94
 95        SqlDataReader reader = (SqlDataReader)db.ExecuteReader("SELECT ROLENAME FROM ROLES");
 96
 97        string[] roles = new string[reccount];
 98
 99        int i = 0;
100
101        while (reader.Read())
102
103        {
104
105            roles[i] = reader.GetString(0);
106
107            i++;
108
109        }

110
111        reader.Close();
112
113        return roles;
114
115    }

116
117    public override bool RoleExists(string roleName)
118
119    {
120
121        db.AddParameter("@RID", roleName);
122
123        object obj = db.ExecuteScalar("SELECT ROLENAME FROM ROLES WHERE ROLENAME=@RID");
124
125        if (obj != null)
126
127        {
128
129            return true;
130
131        }

132
133        else
134
135        {
136
137            return false;
138
139        }

140
141    }

142
143    #endregion

144
145    Users and Roles#region Users and Roles
146
147    public override void AddUsersToRoles(string[] usernames, string[] roleNames)
148
149    {
150
151        foreach (string user in usernames)
152
153        {
154
155            foreach (string role in roleNames)
156
157            {
158
159                db.AddParameter("@UID", user);
160
161                db.AddParameter("@RID", role);
162
163                db.ExecuteNonQuery("INSERT INTO USERROLES(USERNAME,ROLENAME) VALUES(@UID,@RID)");
164
165            }

166
167        }

168
169    }

170
171    public override void RemoveUsersFromRoles(string[] usernames, string[] roleNames)
172
173    {
174
175        foreach (string user in usernames)
176
177        {
178
179            foreach (string role in roleNames)
180
181            {
182
183                db.AddParameter("@UID", user);
184
185                db.AddParameter("@RID", role);
186
187                db.ExecuteNonQuery("DELETE FROM USERROLES WHERE USERNAME=@UID AND ROLENAME=@RID");
188
189            }

190
191        }

192
193    }

194
195    public override string[] GetRolesForUser(string username)
196
197    {
198
199        db.AddParameter("@UID", username);
200
201        int reccount = (int)db.ExecuteScalar("SELECT COUNT(*) FROM USERROLES WHERE USERNAME=@UID");
202
203        string[] roles = new string[reccount];
204
205        db.AddParameter("@UID", username);
206
207        SqlDataReader reader = (SqlDataReader)db.ExecuteReader("SELECT ROLENAME FROM USERROLES WHERE USERNAME=@UID");
208
209        int i = 0;
210
211        while (reader.Read())
212
213        {
214
215            roles[i] = reader.GetString(0);
216
217            i++;
218
219        }

220
221        reader.Close();
222
223        return roles;
224
225    }

226
227    public override string[] GetUsersInRole(string roleName)
228
229    {
230
231        db.AddParameter("@RID", roleName);
232
233        int reccount = (int)db.ExecuteScalar("SELECT COUNT(*) FROM USERROLES WHERE ROLENAME=@RID");
234
235        string[] users = new string[reccount];
236
237        db.AddParameter("@RID", roleName);
238
239        SqlDataReader reader = (SqlDataReader)db.ExecuteReader("SELECT USERNAME FROM USERROLES WHERE ROLENAME=@RID");
240
241        int i = 0;
242
243        while (reader.Read())
244
245        {
246
247            users[i] = reader.GetString(0);
248
249            i++;
250
251        }

252
253        reader.Close();
254
255        return users;
256
257    }

258
259    public override bool IsUserInRole(string username, string roleName)
260
261    {
262
263        db.AddParameter("@UID", username);
264
265        db.AddParameter("@RID", roleName);
266
267        object obj = db.ExecuteScalar("SELECT ROLENAME FROM USERROLES WHERE USERNAME=@UID AND ROLENAME=@RID");
268
269        if (obj != null)
270
271        {
272
273            return true;
274
275        }

276
277        else
278
279        {
280
281            return false;
282
283        }

284
285    }

286
287

测试自定义Provider

   在你下载的页面里包含了四个Web窗体--default.aspxLogin.aspxRoleManager.aspxUserRoles.aspx。前面两个用于测试成员关系的Provider模型,后面两个用户测试角色的Provider模型。

我们使用了ASP.NET2.0提供的MembershipRoles的基本功能,这些类会使用我们自定义的Provider来完成相应的工作

总结

 在本文我们我们可以看到自定义MembershipRole是多么的简单。你可以扩展该功能来适用你的应用程序,你还可以扩展诸如加密解密等功能

转载于:https://www.cnblogs.com/nacarat/archive/2007/10/08/916651.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值