先列出编译通过的代码
1
using System;2
using System.Collections.Generic;3
using System.Text;4
using System.Web;5
using System.Web.Security;6
using System.Web.Configuration;7
using System.Data;8
using System.Data.OleDb;9
using System.Collections;10
using System.Configuration;11
using System.Configuration.Provider;12
using System.Security.Cryptography;13

14

/**//*表创建语句 (创建于:Oracle 8i)15
create table SHAREPOINTUSERS16
(17
PKID VARCHAR2(50),18
USERNAME VARCHAR2(255),19
APPLICATIONNAME VARCHAR2(255),20
EMAIL VARCHAR2(128),21
PASSWORD VARCHAR2(128),22
PASSWORDQUESTION VARCHAR2(255),23
PASSWORDANSWER VARCHAR2(255),24
ISAPPROVED NUMBER(1),25
LASTACTIVITYDATE DATE,26
LASTLOGINDATE DATE,27
LASTPASSWORDCHANGEDATE DATE,28
CREATIONDATE DATE,29
ISONLINE NUMBER(1),30
ISLOCKEDOUT NUMBER(1),31
LASTLOCKEDOUTDATE DATE,32
FAILEDPWDATTEMPTCOUNT NUMBER(5),33
FAILEDPWDATTEMPTWINSTART DATE,34
FAILEDPWDANSWERATTEMPTCOUNT NUMBER(5),35
FAILEDPWDANSWERATTEMPTWINSTART DATE,36
COMMENTS VARCHAR2(255)37
)38
*/39
namespace BoooLee40


{41
public class OracleMembershipProvider : MembershipProvider42

{43

44

自定义私有字段#region 自定义私有字段45
//OracleTools46
private OracleTools OT = null; 47
//自定义属性48
private string _UsersTableName; 49
//Oracle数据库连接串50
private string _ConnectionString;51
//是否允许事件日志52
private bool _EnableEventLog;53
//MachineKey54
private MachineKeySection _MachineKey;55
#endregion56

57

用于MembershipProvider接口属性的私有字段,用于存放config.web中的MembershipProvider配置属性。#region 用于MembershipProvider接口属性的私有字段,用于存放config.web中的MembershipProvider配置属性。58
//使用自定义成员资格提供程序的应用程序的名称。59
private string _ApplicationName;60
//指示成员资格提供程序是否配置为允许用户重置其密码。61
private bool _EnablePasswordReset;62
//指示成员资格提供程序是否配置为允许用户检索其密码。63
private bool _EnablePasswordRetrieval;64
//获取锁定成员资格用户前允许的无效密码或无效密码提示问题答案尝试次数。65
private int _MaxInvalidPasswordAttempts;66
//获取有效密码中必须包含的最少特殊字符数。67
private int _MinRequireNonAlphanumericCharacters;68
//获取密码所要求的最小长度。69
private int _MinRequiredPasswordLength;70
//获取在锁定成员资格用户之前允许的最大无效密码或无效密码提示问题答案尝试次数的分钟数。71
private int _PasswordAttemptWindow;72
//获取一个值,该值指示在成员资格数据存储区中存储密码的格式。73
private MembershipPasswordFormat _PasswordFormat;74
//获取用于计算密码的正则表达式。75
private string _PasswordStrengthRegularExpression;76
//获取一个值,该值指示成员资格提供程序是否配置为要求用户在进行密码重置和检索时回答密码提示问题。77
private bool _RequiresQuestionAndAnswer;78
//获取一个值,指示成员资格提供程序是否配置为要求每个用户名具有唯一的电子邮件地址。79
private bool _RequiresUniqueEmail;80
#endregion81

82

MembershipProvider接口#region MembershipProvider接口83

/**//*84
摘要:85
初始化提供程序。86
87
参数:88
config: 名称/值对的集合,表示在配置中为该提供程序指定的、提供程序特定的属性。89
name: 该提供程序的友好名称。90
*/91
public override void Initialize(string name, System.Collections.Specialized.NameValueCollection config)92

{93
base.Initialize(name, config);94
95
//读取MembershipProvider接口属性配置96
_ApplicationName = GetConfigValue(config["ConnectionString"],System.Web.Hosting.HostingEnvironment.ApplicationVirtualPath);97
_EnablePasswordReset = Convert.ToBoolean(GetConfigValue(config["EnablePasswordReset"], "false"));98
_EnablePasswordRetrieval = Convert.ToBoolean(GetConfigValue(config["EnablePasswordRetrieval"], "false"));99
_MaxInvalidPasswordAttempts=Convert.ToInt32(GetConfigValue(config["MaxInvalidPasswordAttempts"],"5"));100
_MinRequireNonAlphanumericCharacters=Convert.ToInt32(GetConfigValue(config["MinRequiredNonAlphanumericCharacters"],"1"));101
_MinRequiredPasswordLength=Convert.ToInt32(GetConfigValue(config["MinRequiredPasswordLength"],"7"));102
_PasswordAttemptWindow=Convert.ToInt32(GetConfigValue(config["PasswordAttemptWindow"],"10"));103
switch (GetConfigValue(config["PasswordFormat"], MembershipPasswordFormat.Clear.ToString()))104

{105
case "Clear" :106
_PasswordFormat = MembershipPasswordFormat.Clear;107
break;108
case "Encrypted":109
_PasswordFormat = MembershipPasswordFormat.Encrypted;110
break;111
case "Hashed" :112
_PasswordFormat = MembershipPasswordFormat.Hashed;113
break;114
default:115
_PasswordFormat = MembershipPasswordFormat.Clear;116
break;117
}118
_PasswordStrengthRegularExpression=GetConfigValue(config["PasswordStrengthRegularExpression"],"");119
_RequiresQuestionAndAnswer=Convert.ToBoolean(GetConfigValue(config["RequiresQuestionAndAnswer"],"false"));120
_RequiresUniqueEmail=Convert.ToBoolean(GetConfigValue(config["RequiresUniqueEmail"],"true"));121
122
//读取自定义属性123
ConnectionStringSettings ConnectionStringSetting=ConfigurationManager.ConnectionStrings[config["ConnectionString"]];124
_ConnectionString=ConnectionStringSetting.ConnectionString;125
_UsersTableName=GetConfigValue(config["UsersTableName"],"SHAREPOINTUSERS");126
_EnableEventLog=Convert.ToBoolean(GetConfigValue(config["EnableEventLog"],"true"));127
Configuration cfg = WebConfigurationManager.OpenWebConfiguration(System.Web.Hosting.HostingEnvironment.ApplicationVirtualPath);128
_MachineKey = (MachineKeySection)cfg.GetSection("system.web/machineKey");129

130
//初始化OT131
OT = new OracleTools();132
OT.ConnectionString = _ConnectionString;133

134
//为OT分配日志记录器135
LogTools lt = new LogTools();136
lt.Log = "Application";137
lt.EventSource = "OracleMembershipProvider";138
OT.LogTool = lt;139
OT.EnableEventlog=_EnableEventLog;140
}141

142

/**//*143
摘要:144
使用自定义成员资格提供程序的应用程序的名称。145
146
返回值:147
使用自定义成员资格提供程序的应用程序的名称。148
*/149
public override string ApplicationName150

{151
get152

{153
return _ApplicationName;154
}155
set156

{157
;158
}159
}160

161

/**//*162
摘要:163
处理更新成员资格用户密码的请求。164

165
参数:166
newPassword: 指定的用户的新密码。167
oldPassword: 指定的用户的当前密码。168
username: 为其更新密码的用户。169

170
返回值:171
如果密码更新成功,则为 true;否则为 false。172
*/173
public override bool ChangePassword(string username, string oldPassword, string newPassword)174

{175
string SqlString = "";176

177
//更改用户密码178
if (ValidateUser(username,oldPassword))179

{180
SqlString = string.Format("update {0} set password={1} where username='{2}' and password='{3}' and applicationname='{4}'",_UsersTableName, newPassword, username, oldPassword,_ApplicationName);181
return OT.RunSqlNonQuery(SqlString);182
}183
184
return false;185
}186

187

/**//*188
摘要:189
处理更新成员资格用户的密码提示问题和答案的请求。190

191
参数:192
newPasswordQuestion: 指定的用户的新密码提示问题。193
newPasswordAnswer: 指定的用户的新密码提示问题答案。194
username: 要为其更改密码提示问题和答案的用户。195
password: 指定的用户的密码。196

197
返回值:198
如果成功更新密码提示问题和答案,则为 true;否则,为 false。199
*/200
public override bool ChangePasswordQuestionAndAnswer(string username, string password, string newPasswordQuestion, string newPasswordAnswer)201

{202
string SqlString = "";203

204
//更改用户密码问题和密码答案205
if (ValidateUser(username, password))206

{207
SqlString = string.Format("update {0} set question={1} , answer={2} where username='{3}' and password='{4}' and applicationname='{5}'", _UsersTableName,newPasswordQuestion, newPasswordAnswer, username, password,_ApplicationName);208
return OT.RunSqlNonQuery(SqlString);209
}210

211
return false;212
}213

214

/**//*215
摘要:216
将新的成员资格用户添加到数据源。217

218
参数:219
isApproved: 是否允许验证新用户。220
passwordAnswer: 新用户的密码提示问题答案。221
username: 新用户的用户名。222
providerUserKey: 成员资格数据源中该用户的唯一标识符。223
password: 新用户的密码。224
passwordQuestion: 新用户的密码提示问题。225
email: 新用户的电子邮件地址。226
status: 一个 System.Web.Security.MembershipCreateStatus 枚举值,指示是否已成功创建用户。227

228
返回值:229
一个用新创建的用户的信息填充的 System.Web.Security.MembershipUser 对象。230
*/231
public override MembershipUser CreateUser(string username, string password, string email, string passwordQuestion, string passwordAnswer, bool isApproved, object providerUserKey, out MembershipCreateStatus status)232

{233
//username无效234
if (string.IsNullOrEmpty(username))235

{236
status = MembershipCreateStatus.InvalidUserName;237
return null;238
}239

240
//username重复241
if (UserExist(username) > 0)242

{243
status = MembershipCreateStatus.DuplicateUserName;244
return null;245
}246

247
//email无效248
if (string.IsNullOrEmpty(email))249

{250
status = MembershipCreateStatus.InvalidEmail;251
return null;252
}253
254
//email重复255
if (UserExistByMail(email) > 0 && _RequiresUniqueEmail)256

{257
status = MembershipCreateStatus.DuplicateEmail;258
return null;259
}260

261
//passwordQuestion无效262
if (string.IsNullOrEmpty(passwordQuestion))263

{264
status = MembershipCreateStatus.InvalidQuestion;265
return null;266
}267

268
//passworAnswer无效269
if (string.IsNullOrEmpty(passwordAnswer))270

{271
status = MembershipCreateStatus.InvalidAnswer;272
return null;273
}274

275
//providerUserKey无效276
if (providerUserKey == null)277

{278
status = MembershipCreateStatus.InvalidProviderUserKey;279
return null;280
}281

282
//providerUserKey重复283
if (UserExistByPKID(providerUserKey.ToString()) > 0)284

{285
status = MembershipCreateStatus.DuplicateProviderUserKey;286
return null;287
}288

289
string SqlString = "insert into {0} " +290
"(PKID,USERNAME,APPLICATIONNAME,EMAIL,COMMENTS,PASSWORD,PASSWORDQUESTION," +291
"PASSWORDANSWER,ISAPPROVED,LASTACTIVITYDATE,LASTPASSWORDCHANGEDATE," +292
"CREATIONDATE,ISONLINE,ISLOCKEDOUT,LASTLOCKEDOUTDATE,FAILEDPWDATTEMPTCOUNT,FAILEDPWDATTEMPTWINSTART" +293
"FAILEDPWDANSWERATTEMPTCOUNT,FAILEDPWDANSWERATTEMPTWINSTART) " +294
"values('{1}','{2}','{3}','{4}','{5}','{6}','{7}','{8}',{9},{10},{11},{12},{13},{14},{15},{16},{17},{18},{19})";295

296
DateTime createDate=DateTime.Now;297
string screateDate = string.Format("to_date('yyyy-mm-dd hh:mi:ss',{0})", createDate.ToString("G"));298

299
int iisApproved=0;300
if(isApproved)301
iisApproved=1;302

303
SqlString=string.Format(SqlString,304
providerUserKey.ToString(),305
username,306
_ApplicationName,307
email,308
"",309
EncodePassword(password),310
passwordQuestion,311
EncodePassword(passwordAnswer),312
iisApproved,313
screateDate,314
screateDate,315
screateDate,316
"0",317
"0",318
screateDate,319
_MaxInvalidPasswordAttempts.ToString(), 320
screateDate,321
_MaxInvalidPasswordAttempts.ToString(),322
screateDate);323

324
if(OT.RunSqlNonQuery(SqlString))325

{326
SqlString=string.Format("select * from {0} where username={1} and applicationname='{2}'",_UsersTableName,username,_ApplicationName);327
DataTable dt=OT.RunSqlDataTable(SqlString);328
MembershipUser mu = ToMembershipUser(dt.Rows[0]);329
status = MembershipCreateStatus.Success;330
return mu;331
}332

333
status = MembershipCreateStatus.ProviderError;334
return null;335
}336

337

/**//*338
摘要:339
从成员资格数据源删除一个用户。340

341
参数:342
username: 要删除的用户的名称。343
deleteAllRelatedData: 如果为 true,则从数据库中删除与该用户相关的数据;如果为 false,则将与该用户相关的数据保留在数据库。344

345
返回值:346
如果用户被成功删除,则为 true;否则为 false。347
*/348
public override bool DeleteUser(string username, bool deleteAllRelatedData)349

{350
string SqlString = "";351

352
//删除用户353
if (UserExist(username)>0)354

{355
SqlString = string.Format("delete from {0} where username='{1}' and applicationname='{2}'",_UsersTableName, username,_ApplicationName);356
return OT.RunSqlNonQuery(SqlString);357
}358

359
return false;360
}361

362

/**//*363
摘要:364
指示成员资格提供程序是否配置为允许用户重置其密码。365

366
返回值:367
如果成员资格提供程序支持密码重置,则为 true;否则为 false。默认为 true。368
*/369
public override bool EnablePasswordReset370

{371
get 372

{373
return _EnablePasswordReset;374
}375
}376
377

/**//*378
摘要:379
指示成员资格提供程序是否配置为允许用户检索其密码。380

381
返回值:382
如果成员资格提供程序配置为支持密码检索,则为 true,否则为 false。默认为 false。383
*/384
public override bool EnablePasswordRetrieval385

{386
get 387

{388
return _EnablePasswordRetrieval; 389
}390
}391

392

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

396
参数:397
totalRecords: 匹配用户的总数。398
pageIndex: 要返回的结果页的索引。pageIndex 是从零开始的。399
emailToMatch: 要搜索的电子邮件地址。400
pageSize: 要返回的结果页的大小。401

402
返回值:403
包含一页 pageSizeSystem.Web.Security.MembershipUser 对象的 System.Web.Security.MembershipUserCollection 集合,这些对象从 pageIndex 指定的页开始。404
*/405
public override MembershipUserCollection FindUsersByEmail(string emailToMatch, int pageIndex, int pageSize, out int totalRecords)406

{407
string SqlString = "";408
MembershipUserCollection muc = null;409
totalRecords = UserExistByMail(emailToMatch);410
if (totalRecords>0)411

{412
SqlString = string.Format("select * from {0} where email='{1}' and applicationname='{2}'", _UsersTableName,emailToMatch,_ApplicationName);413
muc = ToMembershipUserCollection(OT.RunSqlDataTable(SqlString));414
}415
return muc;416
}417

418

/**//*419
摘要:420
获取一个成员资格用户的集合,这些用户的用户名包含要匹配的指定用户名。421

422
参数:423
totalRecords: 匹配用户的总数。424
pageIndex: 要返回的结果页的索引。pageIndex 是从零开始的。425
usernameToMatch: 要搜索的用户名。426
pageSize: 要返回的结果页的大小。427

428
返回值:429
包含一页 pageSizeSystem.Web.Security.MembershipUser 对象的 System.Web.Security.MembershipUserCollection 集合,这些对象从 pageIndex 指定的页开始。430
*/431
public override MembershipUserCollection FindUsersByName(string usernameToMatch, int pageIndex, int pageSize, out int totalRecords)432

{433
string SqlString = "";434
MembershipUserCollection muc = new MembershipUserCollection();435
totalRecords = UserExist(usernameToMatch);436
if (totalRecords > 0)437

{438
SqlString = string.Format("select * from {0} where username='{1}' and applicationname='{2}'", _UsersTableName,usernameToMatch,_ApplicationName);439
muc=ToMembershipUserCollection( OT.RunSqlDataTable(SqlString));440
}441
return muc;442
}443

444

/**//*445
摘要:446
获取数据源中的所有用户的集合,并显示在数据页中。447

448
参数:449
totalRecords: 匹配用户的总数。450
pageIndex: 要返回的结果页的索引。pageIndex 是从零开始的。451
pageSize: 要返回的结果页的大小。452

453
返回值:454
包含一页 pageSizeSystem.Web.Security.MembershipUser 对象的 System.Web.Security.MembershipUserCollection 集合,这些对象从 pageIndex 指定的页开始。455
*/456
public override MembershipUserCollection GetAllUsers(int pageIndex, int pageSize, out int totalRecords)457

{458
string SqlString = "";459
MembershipUserCollection muc = new MembershipUserCollection();460
totalRecords = UsersTotalRecords();461
if (totalRecords > 0)462

{463
SqlString =string.Format( "select * from {0} where applicationname='{1}'",_UsersTableName,_ApplicationName);464
muc = ToMembershipUserCollection(OT.RunSqlDataTable(SqlString));465
}466
return muc;467
}468

469

/**//*470
摘要:471
获取当前访问该应用程序的用户数。472

473
返回值:474
当前访问该应用程序的用户数。475
*/476
public override int GetNumberOfUsersOnline()477

{478
//TODO 获取在线人数(再斟酌)479
string SqlString = "";480
SqlString = string.Format("select count(*) from {0} where IsOnLine=1 and applicationname={1}", _UsersTableName,_ApplicationName);481
string numonline=OT.RunSqlScalar(SqlString);482
if (!string.IsNullOrEmpty(numonline))483
return Convert.ToInt32(numonline);484
return 0;485
}486

487

/**//*488
摘要:489
从数据源获取指定用户名所对应的密码。490

491
参数:492
username: 为其检索密码的用户。493
answer: 用户的密码提示问题答案。494

495
返回值:496
指定用户名所对应的密码。497
*/498
public override string GetPassword(string username, string answer)499

{500
string SqlString = "";501
string password=null;502
if (UserExist(username) > 0 && _EnablePasswordRetrieval)503

{504
SqlString = string.Format("select password from {0} where username='{1}' and answer='{2}' and applicationname='{3}'", _UsersTableName,username, answer,_ApplicationName);505
password = OT.RunSqlScalar(SqlString);506
}507
return password;508
}509

510

/**//*511
摘要:512
从数据源获取用户的信息。提供一个更新用户最近一次活动的日期/时间戳的选项。513

514
参数:515
username: 要获取其信息的用户名。516
userIsOnline: 如果为 true,则更新用户最近一次活动的日期/时间戳;如果为 false,则返回用户信息,但不更新用户最近一次活动的日期/时间戳。517

518
返回值:519
用数据源中指定用户的信息填充的 System.Web.Security.MembershipUser 对象。520
*/521
public override MembershipUser GetUser(string username, bool userIsOnline)522

{523
string SqlString = "";524
MembershipUser mu = null;525

526
if (UserExist(username) > 0)527

{528
SqlString = string.Format("select * from {0} where username='{1}' and applicationname='{2}'", _UsersTableName,username,_ApplicationName);529
if (userIsOnline)530
SqlString += " and isonline=1";531
mu=ToMembershipUser(OT.RunSqlDataTable(SqlString).Rows[0]);532
}533

534
return mu;535
}536

537

/**//*538
摘要:539
根据成员资格用户的唯一标识符从数据源获取该用户的信息。提供一个更新用户最近一次活动的日期/时间戳的选项。540

541
参数:542
providerUserKey: 要获取其信息的成员资格用户的唯一标识符。543
userIsOnline: 如果为 true,则更新用户最近一次活动的日期/时间戳;如果为 false,则返回用户信息,但不更新用户最近一次活动的日期/时间戳。544

545
返回值:546
用数据源中指定用户的信息填充的 System.Web.Security.MembershipUser 对象。547
*/548
public override MembershipUser GetUser(object providerUserKey, bool userIsOnline)549

{550
string SqlString = "";551
MembershipUser mu = null;552

553
if (UserExistByPKID(providerUserKey.ToString()) > 0)554

{555
SqlString = string.Format("select * from {0} where PKID='{1}' and APPLICATIONNAME={2}", _UsersTableName,providerUserKey.ToString(),_ApplicationName);556
if (userIsOnline)557
SqlString += "and isonline=1";558
mu = ToMembershipUser(OT.RunSqlDataTable(SqlString).Rows[0]);559
}560

561
return mu;562
}563

564

/**//*565
摘要:566
获取与指定的电子邮件地址关联的用户名。567

568
参数:569
email: 要搜索的电子邮件地址。570

571
返回值:572
与指定的电子邮件地址关联的用户名。如果未找到匹配项,则返回null。573
*/574
public override string GetUserNameByEmail(string email)575

{576
string SqlString = "";577
if (UserExist(email) > 0)578

{579
SqlString = string.Format("select username from {0} where email={1} and applicationname={2}", _UsersTableName, email,_ApplicationName);580
return OT.RunSqlScalar(SqlString);581
}582
return null;583
}584

585

/**//*586
摘要:587
获取锁定成员资格用户前允许的无效密码或无效密码提示问题答案尝试次数。588

589
返回值:590
锁定成员资格用户之前允许的无效密码或无效密码提示问题答案尝试次数。591
*/592
public override int MaxInvalidPasswordAttempts593

{594
get595

{596
return _MaxInvalidPasswordAttempts;597
}598
}599

600

/**//*601
摘要:602
获取有效密码中必须包含的最少特殊字符数。603

604
返回值:605
有效密码中必须包含的最少特殊字符数。606
*/607
public override int MinRequiredNonAlphanumericCharacters608

{609
get610

{611
return _MinRequireNonAlphanumericCharacters;612
}613

614
}615

616

/**//*617
摘要:618
获取密码所要求的最小长度。619

620
返回值:621
密码所要求的最小长度。622
*/623
public override int MinRequiredPasswordLength624

{625
get626

{627
return _MinRequiredPasswordLength;628
}629
}630

631

/**//*632
摘要:633
获取在锁定成员资格用户之前允许的最大无效密码或无效密码提示问题答案尝试次数的分钟数。634

635
返回值:636
在锁定成员资格用户之前允许的最大无效密码或无效密码提示问题答案尝试次数的分钟数。637
*/638
public override int PasswordAttemptWindow639

{640
get641

{642
return _PasswordAttemptWindow;643
}644
}645

646

/**//*647
摘要:648
获取一个值,该值指示在成员资格数据存储区中存储密码的格式。649

650
返回值:651
System.Web.Security.MembershipPasswordFormat 值之一,该值指示在数据存储区中存储密码的格式。652
*/653
public override MembershipPasswordFormat PasswordFormat654

{655
get656

{657
return _PasswordFormat;658
}659
}660

661

/**//*662
摘要:663
获取用于计算密码的正则表达式。664

665
返回值:666
用于计算密码的正则表达式。667
*/668
public override string PasswordStrengthRegularExpression669

{670
get671

{672
return PasswordStrengthRegularExpression;673
}674
}675

676

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

680
返回值:681
如果密码重置和检索需要提供密码提示问题答案,则为 true;否则为 false。默认为 true。682
*/683
public override bool RequiresQuestionAndAnswer684

{685
get686

{687
return RequiresQuestionAndAnswer;688
}689
}690

691

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

695
返回值:696
如果成员资格提供程序要求唯一的电子邮件地址,则返回 true;否则返回 false。默认为 true。697
*/698
public override bool RequiresUniqueEmail699

{700
get701

{702
return RequiresUniqueEmail;703
}704
}705

706

/**//*707
摘要:708
将用户密码重置为一个自动生成的新密码。709

710
参数:711
username: 为其重置密码的用户。712
answer: 指定的用户的密码提示问题答案。713

714
返回值:715
指定的用户的新密码。716
*/717
public override string ResetPassword(string username, string answer)718

{719
string SqlString = "";720
string newPassword = null;721

722
if (EnablePasswordReset)723

{724
SqlString = "select count(*) from {0} where username='{1}' and answer={2} and applicationname='{3}'";725
int count = Convert.ToInt32(OT.RunSqlScalar(SqlString));726
if (count > 0)727

{728
Random rd=new Random();729
string Password = "npwd" + Convert.ToString(rd.Next(1000)) + "oss" + Convert.ToString(rd.Next(10000));730
SqlString = string.Format("update {0} set password={1} where username='{2}' and applicationname='{3}'", _UsersTableName, Password, username, _ApplicationName);731
if (OT.RunSqlNonQuery(SqlString))732
newPassword = Password;733
}734
}735
return newPassword;736
}737

738

/**//*739
摘要:740
清除锁定,以便可以验证该成员资格用户。741

742
参数:743
userName: 要清除其锁定状态的成员资格用户。744

745
返回值:746
如果成功取消成员资格用户的锁定,则为 true;否则为 false。747
*/748
public override bool UnlockUser(string userName)749

{750
//TODO UnlockUser751
string SqlString = "";752
string sdate=string.Format("to_date('{0}','yyyy-mm-dd hh:mi:ss')", DateTime.Now.ToString("G"));753
SqlString = string.Format("update {0} set ISLOCKEDOUT=1,LASTLOCKEDOUTDATE={1} where USERNAME={2} and APPLICATIONNAME={3}", _UsersTableName, sdate,userName,_ApplicationName);754
return OT.RunSqlNonQuery(SqlString);755
}756

757

/**//*758
摘要:759
更新数据源中有关用户的信息。760

761
参数:762
user: 一个 System.Web.Security.MembershipUser 对象,表示要更新的用户及其更新信息。763
*/764
public override void UpdateUser(MembershipUser user)765

{766
//TODO UpdateUser767
string SqlString = "";768
string IsApproved = "0";769

770
if (user.IsApproved)771
IsApproved = "1";772

773
SqlString = string.Format(774
"update {0} set EMAIL='{1}',COMMENTS='{2}',ISAPPROVED={3} where USERNAME='{4}' and APPLICATIONNAME='{5}'",775
_UsersTableName,776
user.Email,777
user.Comment,778
IsApproved,779
user.UserName,780
_ApplicationName);781

782
OT.RunSqlNonQuery(SqlString);783
}784

785

/**//*786
摘要:787
验证数据源中是否存在指定的用户名和密码。788

789
参数:790
username: 要验证的用户的名称。791
password: 指定的用户的密码。792

793
返回值:794
如果指定的用户名和密码有效,则为 true;否则为 false。795
*/796
public override bool ValidateUser(string username, string password)797

{798
if (UserExist(username, password) > 0)799
return true;800
else801
return false;802
}803
#endregion804

805

非MembershipProvider成员#region 非MembershipProvider成员806

807

/**//*808
摘要:809
判断用户是否存在810

811
参数:812
username:用户名 813

814
返回值:815
找到用户返回true,没有找到用户false816
*/817
private int UserExist(string username)818

{819
string SqlString = "";820
string r = "";821
int Count = 0;822

823
SqlString = string.Format("select count(*) from {0} where username='{1}' and applicationname='{2}'", _UsersTableName,username,_ApplicationName);824
r = OT.RunSqlScalar(SqlString);825
try826

{827
Count = int.Parse(r);828
}829
catch (Exception)830

{831
Count = 0;832
}833

834
return Count;835
}836

837

/**//*838
摘要:839
判断用户是否存在840

841
参数:842
username:用户名843
password:用户密码844

845
返回值:846
找到用户的用户数。847
*/848
private int UserExist(string username, string password)849

{850
string SqlString = "";851
string r = "";852
int Count = 0;853

854
SqlString = string.Format("select count(*) from {0} where username='{1}' and password='{2}' and applicationname='{3}'",_UsersTableName, username,password,_ApplicationName);855
r = OT.RunSqlScalar(SqlString);856
try857

{858
Count = int.Parse(r);859
}860
catch (Exception)861

{862
Count = 0;863
}864

865
return Count;866
}867

868

/**//*869
摘要:870
判断用户是否存在871

872
参数:873
email:用户名 874

875
返回值:876
找到用户的用户数。877
*/878
private int UserExistByMail(string email)879

{880
string SqlString = "";881
string r = "";882
int Count = 0;883

884
SqlString = string.Format("select count(*) from {0} where email='{1}' and applicationname='{2}'", _UsersTableName,email,_ApplicationName);885
r = OT.RunSqlScalar(SqlString);886
try887

{888
Count = int.Parse(r);889
}890
catch (Exception)891

{892
Count = 0;893
}894

895
return Count;896
}897

898

/**//*899
摘要:900
判断用户是否存在901

902
参数:903
pkid:PKID904

905
返回值:906
找到用户的用户数。907
*/908
private int UserExistByPKID(string pkid)909

{910
string SqlString = "";911
string r = "";912
int Count = 0;913

914
SqlString = string.Format("select count(*) from {0} where PKID='{1}' and APPLICATIONNAME={2}", _UsersTableName, pkid,_ApplicationName);915
r = OT.RunSqlScalar(SqlString);916
try917

{918
Count = int.Parse(r);919
}920
catch (Exception)921

{922
Count = 0;923
}924

925
return Count;926
}927

/**//*928
摘要:929
转换用户数据表为MembershipUserCollection930

931
参数:932
userstable:用户表933

934
返回值:935
返回包含用户数据的MembershipUserCollection。936
*/937
private MembershipUserCollection ToMembershipUserCollection(DataTable userstable)938

{939
MembershipUserCollection muc = new MembershipUserCollection();940

941
foreach (DataRow dr in userstable.Rows)942

{943
muc.Add(ToMembershipUser(dr));944
}945

946
return muc;947
}948

949

/**//*950
摘要:951
获得用户总数952

953
返回值:954
返回用户数。955
*/956
private int UsersTotalRecords()957

{958
string SqlString = "";959
string r = "";960
int Count = 0;961

962
SqlString = string.Format("select count(*) from {0} where applicationname='{1}'",_UsersTableName,_ApplicationName);963
r = OT.RunSqlScalar(SqlString);964
try965

{966
Count = int.Parse(r);967
}968
catch (Exception)969

{970
Count = 0;971
}972

973
return Count;974
}975

976

/**//*977
摘要:978
转换用户数据表为MembershipUserCollection979

980
参数:981
usersrecord:用户记录982

983
返回值:984
返回包含用户数据的MembershipUser。985
*/986
private MembershipUser ToMembershipUser(DataRow usersrecord)987

{988
MembershipUser mu = null;989
try990

{991
bool IsApproved=false;992
if(Convert.ToInt32(usersrecord["ISAPPROVED"].ToString())>0)993
IsApproved=true;994

995
bool IsLockedOut=false;996
if(Convert.ToInt32(usersrecord["ISLOCKEDOUT"].ToString())>0)997
IsLockedOut=true;998

999
DateTime creationDate = Convert.ToDateTime(usersrecord["CREATIONDATE"]);1000
DateTime lastLoginDate=Convert.ToDateTime(usersrecord["LASTLOGINDATE"]);1001
DateTime lastActivityDate=Convert.ToDateTime(usersrecord["LASTACTIVITYDATE"]);1002
DateTime lastPasswordChangedDate=Convert.ToDateTime(usersrecord["LASTPASSWORDCHANGEDDATE"]);1003
DateTime lastLockOutDate=Convert.ToDateTime(usersrecord["LASTLOCKOUTDATE"]);1004

1005
mu=new MembershipUser(1006
this.Name,1007
usersrecord["USERNAME"].ToString(),1008
usersrecord["PKID"].ToString(),1009
usersrecord["EMAIL"].ToString(),1010
usersrecord["PASSWORDQUESTION"].ToString(),1011
usersrecord["COMMENTS"].ToString(),1012
IsApproved,1013
IsLockedOut,1014
creationDate,1015
lastLoginDate,1016
lastActivityDate,1017
lastPasswordChangedDate,1018
lastLockOutDate); 1019
}1020
catch (Exception)1021

{1022
}1023
return mu;1024
}1025

1026

/**//*1027
摘要:1028
获取配置文件1029

1030
参数:1031
ConfigValue:配置文件中的参数设置1032
DefaultValue:缺省值1033
1034
返回值:1035
如果ConfigValue值有效则返回ConfigValue,否则返回DefaultValue。1036
*/1037
private string GetConfigValue(string ConfigValue, string DefaultValue)1038

{1039
if (string.IsNullOrEmpty(ConfigValue))1040
return DefaultValue;1041
return ConfigValue;1042
}1043

1044

/**//*1045
摘要:1046
密码处理1047

1048
参数:1049
password:密码1050
1051
返回值:1052
返回处理后的密码。1053
*/1054
private string EncodePassword(string password)1055

{1056
string encodedPassword = password;1057

1058
switch (PasswordFormat)1059

{1060
case MembershipPasswordFormat.Clear:1061
break;1062
case MembershipPasswordFormat.Encrypted:1063
encodedPassword =1064
Convert.ToBase64String(EncryptPassword(Encoding.Unicode.GetBytes(password)));1065
break;1066
case MembershipPasswordFormat.Hashed:1067
HMACSHA1 hash = new HMACSHA1();1068
hash.Key = HexToByte(_MachineKey.ValidationKey);1069
encodedPassword =1070
Convert.ToBase64String(hash.ComputeHash(Encoding.Unicode.GetBytes(password)));1071
break;1072
default:1073
throw new ProviderException("不支持的密码格式.");1074
}1075

1076
return encodedPassword;1077
}1078

1079
private byte[] HexToByte(string hexString)1080

{1081
byte[] returnBytes = new byte[hexString.Length / 2];1082
for (int i = 0; i < returnBytes.Length; i++)1083
returnBytes[i] = Convert.ToByte(hexString.Substring(i * 2, 2), 16);1084
return returnBytes;1085
}1086

1087
1088
#endregion1089
1090
}1091
}1092

1
using System;2
using System.Collections.Generic;3
using System.Text;4
using System.Data;5
using System.Data.OleDb;6

7
namespace BoooLee8


{9
class OracleTools10

{11

/**//// <summary>12
/// 私有变量13
/// </summary>14
private string _ConnectionString = ""; //数据库连接串15

16

/**//// <summary>17
/// 日志记录器18
/// </summary>19
private LogTools _LogTools = null;20

21

/**//// <summary>22
/// 是否允许记录日志23
/// </summary>24
private bool _EnableEventLog = false;25

26

/**//// <summary>27
/// 是否允许记录日志28
/// </summary>29
public bool EnableEventlog30

{31
get32

{33
return _EnableEventLog;34
}35

36
set37

{38
_EnableEventLog = value;39
}40
}41

42

/**//// <summary>43
/// 日志记录器44
/// </summary>45
public LogTools LogTool46

{47
get48

{49
return _LogTools;50
}51

52
set53

{54
_LogTools = value;55
}56
}57

/**//// <summary>58
/// 数据库连接串59
/// </summary>60
public string ConnectionString61

{62
get63

{64
return _ConnectionString;65
}66

67
set68

{69
_ConnectionString=value;70
}71
}72

73

/**//// <summary>74
/// 运行无返回值的Sql语句。75
/// </summary>76
/// <param name="SqlString">指定要运行的Sql语句。</param>77
/// <param name="Conn">指定数据库连接。</param>78
/// <returns>成功返回true,失败返回false。</returns>79
public bool RunSqlNonQuery(string SqlString)80

{81
OleDbConnection Conn=null;82

83
try84

{85
using (OleDbCommand Command = new OleDbCommand())86

{87
Command.CommandText = SqlString;88
Conn = GetConnection();89
Conn.Open();90
Command.Connection = Conn; 91
Command.ExecuteNonQuery();92
}93
return true;94
}95
catch (Exception ex)96

{97
if (_LogTools != null && _EnableEventLog)98

_LogTools.WriteToEventLog(ex, string.Format("RunSqlNonQuery(\"
{0}\")", SqlString));99
return false;100
}101
finally 102

{103
//关闭数据库连接104
if (Conn != null && Conn.State==ConnectionState.Open)105
Conn.Close();106
}107
}108

109

/**//// <summary>110
/// 运行返回一个值的Select语句。111
/// </summary>112
/// <param name="SqlString">指定要运行的Sql语句。</param>113
/// <param name="Conn">指定数据库连接。</param>114
/// <returns>成功返回Select语句结果,失败返回null。</returns>115
public string RunSqlScalar(string SqlString)116

{117
OleDbConnection Conn = null;118

119
try120

{121
Conn = GetConnection();122
Conn.Open();123

124
using (OleDbCommand Command = new OleDbCommand())125

{126
Command.CommandText = SqlString;127
Command.Connection = Conn;128
return Command.ExecuteScalar().ToString();129
}130
}131
catch (Exception ex)132

{133
if (_LogTools != null && _EnableEventLog)134

_LogTools.WriteToEventLog(ex, string.Format("RunSqlScalar(\"
{0}\")",SqlString));135
return null;136
}137
finally138

{139
if (Conn != null && Conn.State == ConnectionState.Open)140
Conn.Close();141
}142
}143

144

/**//// <summary>145
/// 运行返回DataTable的Sql语句。146
/// </summary>147
/// <param name="SqlString">指定要运行的Sql语句。</param>148
/// <param name="Conn">指定数据库连接。</param>149
/// <returns>成功返回Select语句结果DataTable。失败返回null</returns>150
public DataTable RunSqlDataTable(string SqlString)151

{152
OleDbConnection Conn = null;153

154
try155

{156
using (OleDbDataAdapter DataAdapter = new OleDbDataAdapter())157

{158
Conn = GetConnection();159
Conn.Open();160
OleDbCommand SC = new OleDbCommand();161
SC.CommandText = SqlString;162
SC.Connection = Conn;163
DataAdapter.SelectCommand = SC;164
DataTable dt = new DataTable();165
DataAdapter.Fill(dt);166
return dt;167
}168
}169
catch (Exception ex)170

{171
if (_LogTools != null && _EnableEventLog)172

_LogTools.WriteToEventLog(ex, string.Format("RunSqlDataTable(\"
{0}\")", SqlString));173
return null;174
}175
finally176

{177
if (Conn != null && Conn.State == ConnectionState.Open)178
Conn.Close();179
}180
}181

182

/**//// <summary>183
/// 返回一个OleDbConnection对象。184
/// </summary>185
/// <returns>成功返回的OleDbConnection对象,失败返回null。</returns>186
public OleDbConnection GetConnection()187

{188
try189

{190
OleDbConnection result = new OleDbConnection();191
result.ConnectionString = _ConnectionString;192
return result;193
}194
catch (Exception ex)195

{196
if (_LogTools != null && _EnableEventLog)197
_LogTools.WriteToEventLog(ex, "GetConnection()");198
return null;199
}200
}201
}202
}203

1
using System;2
using System.Collections.Generic;3
using System.Text;4
using System.Diagnostics;5

6
namespace BoooLee7


{8
class LogTools9

{10
private string _eventSource = "";11
private string _eventLog = "";12

13

14

/**//// <summary>15
/// 事件发生源16
/// </summary>17
public string EventSource18

{19
get20

{21
return _eventSource;22
}23

24
set25

{26
_eventSource = value;27
}28
}29

30

/**//// <summary>31
/// 日志名32
/// </summary>33
public string Log34

{35
get36

{37
return _eventLog;38
}39

40
set41

{42
_eventLog = value;43
}44
}45

46
public void WriteToEventLog(Exception e, string action)47

{48
EventLog log = new EventLog();49
log.Source = _eventSource;50
log.Log = _eventLog;51

52
string message = "数据源发生异常.\n\n";53
message += "操作: " + action + "\n\n";54
message += "异常: " + e.ToString();55

56
log.WriteEntry(message);57
}58
}59
}60

强签名后发布到gac,程序集信息如下:
BoooLee.OracleMembershipProvider, BoooLee.OracleMembershipProvider, Version=1.0.0.0, Culture=neutral, PublicKeyToken=4b2945803a587d6b
vs2005中创建一个新的网站,web.config配置如下:
1
<?xml version="1.0" encoding="utf-8"?>2
<!-- 3
注意: 除了手动编辑此文件以外,您还可以使用 4
Web 管理工具来配置应用程序的设置。可以使用 Visual Studio 中的5
“网站”->“Asp.Net 配置”选项。6
设置和注释的完整列表在 7
machine.config.comments 中,该文件通常位于 8
\Windows\Microsoft.Net\Framework\v2.x\Config 中9
-->10
<configuration>11
<appSettings>12
<add key="EnableCaching" value="true" />13
</appSettings>14
<connectionStrings>15
<add name="ORACLEDB" connectionString="Provider=MSDAORA.1;Password=jgf;User ID=antuuser;Data Source=op;Persist Security Info=True" />16
</connectionStrings>17
<system.web>18
<!--19
通过 <authentication> 节可以配置 ASP.NET 使用的 20
安全身份验证模式,21
以标识传入的用户。 22
-->23
<authentication mode="Windows" />24
<!--25
如果在执行请求的过程中出现未处理的错误,26
则通过 <customErrors> 节可以配置相应的处理步骤。具体说来,27
开发人员通过该节可以配置28
要显示的 html 错误页29
以代替错误堆栈跟踪。30

31
<customErrors mode="RemoteOnly" defaultRedirect="GenericErrorPage.htm">32
<error statusCode="403" redirect="NoAccess.htm" />33
<error statusCode="404" redirect="FileNotFound.htm" />34
</customErrors>35
-->36
<!-- 37
设置 compilation debug="true" 将调试符号插入38
已编译的页面中。但由于这会 39
影响性能,因此只在开发过程中将此值 40
设置为 true。41
-->42
<compilation debug="true" batch="false" batchTimeout="15" defaultLanguage="vb" explicit="true" maxBatchSize="1000" maxBatchGeneratedFileSize="3000" numRecompilesBeforeAppRestart="15" strict="false" tempDirectory="" />43
<membership defaultProvider="OracleMembershipProvider">44
<providers>45
<add name="OracleMembershipProvider" 46
type="BoooLee.OracleMembershipProvider, BoooLee.OracleMembershipProvider, Version=1.0.0.0, Culture=neutral, PublicKeyToken=4b2945803a587d6b" 47
ConnectionStringName="ORACLEDB" 48
enablePasswordRetrieval="false" 49
enablePasswordReset="true" 50
requiresQuestionAndAnswer="true" 51
applicationName="/" 52
requiresUniqueEmail="false" 53
passwordFormat="Hashed" 54
maxInvalidPasswordAttempts="5" 55
minRequiredPasswordLength="7" 56
minRequiredNonalphanumericCharacters="1" 57
passwordAttemptWindow="10" 58
passwordStrengthRegularExpression="" 59
description="OracleMembershipProvider认证提供程序"60
usersTableName="SHAREPOINTUSERS"61
enableEventLog="true" 62
/> 63
</providers>64
</membership>65
</system.web>66
</configuration>现在已经可以用vs2005来调试了,非常方便,但程序有一些bug,周末了,不想这个了,等下周再来debug。