Membership学习记录
---自定义成员资格用户类型及相关提供程序
一.Web.config文件配制
因Membership是基于Forms验证,所以首先得在<system.web>节点下添加Forms验证节点:
<authentication mode="Forms">
<forms name="WPFORMAUTH" loginUrl="~/Login.aspx" timeout="90"/>
</authentication>
此节点的相关属性说明这里就没必要说了,相信大家一看就明白。
接下来依然在<system.web>下添加membership节点:
<membership defaultProvider="MyMembershipProvider">
<providers>
<add name="MyMembershipProvider" type="MyMembershipProvider" requiresQuestionAndAnswer="false" connectionString="DatabaseConnectionString"/>
</providers>
</membership>
再就是添加 rolemanager节点
<roleManager cacheRolesInCookie="true" defaultProvider="MyRoleProvider" enabled="true">
<providers>
<clear/>
<add connectionStringName="DatabaseConnectionString" applicationName="simple" name="MyRoleProvider" type="MyRoleProvider"/>
</providers>
</roleManager>
最后就是添加授权节点
<authorization>
<allow roles="admin,guest"/>
<deny users="*"/>
</authorization>
二.创建自定义成员资格用户
可以创建一个自定义成员资格用户,方法是创建一个继承 MembershipUser 类的类,然后包括公开其他用户值的属性。此外,还可以向 MembershipUser 类添加方法和事件。调用 Membership 类以创建自定义 MembershipUser 的实例时,将只调用由 MembershipUser 类定义的构造函数。如果 MembershipUser 实现包括其他构造函数重载,则这些构造函数只能由为调用自定义构造函数而专门编写的应用程序代码调用。
代码示例演示一个继承 MembershipUser 类的简单自定义成员资格用户
public class MyMembershipUser:MembershipUser
{
public MyMembershipUser(string providername,
string username,
object providerUserKey,
string email,
string passwordQuestion,
string comment,
bool isApproved,
bool isLockedOut,
DateTime creationDate,
DateTime lastLoginDate,
DateTime lastActivityDate,
DateTime lastPasswordChangedDate,
DateTime lastLockedOutDate,
string qq) : base(providername,
username,
providerUserKey,
email,
passwordQuestion,
comment,
isApproved,
isLockedOut,
creationDate,
lastLoginDate,
lastActivityDate,
lastPasswordChangedDate,
lastLockedOutDate)
{
this._qq = qq;
}
private string _qq;
public string QQ
{
get { return _qq; }
set { _qq = value; }
}
}
三.自定义提供程序
1. 创建自定义成员资格提供程序
创建一个自定义成员资格提供程序,该提供程序支持自定义成员资格用户类型和自定义成员资格数据存储区。可以编写自定义成员资格提供程序的 GetUser 和 CreateUser 方法,以返回自定义成员资格用户类型的对象。可以编写自定义成员资格提供程序的 UpdateUser 方法,以采用自定义成员资格用户类型的对象作为输入。
using System;
using System.Web;
using System.Web.Security;
using System.Data;
using System.Data.SqlClient;
/// <summary>
///MyMembershipProvider 的摘要说明
/// </summary>
public class MyMembershipProvider:MembershipProvider
{
private string _connectionString;
public override void Initialize(string name, System.Collections.Specialized.NameValueCollection config)
{
string connStringName = config["connectionString"];//这里去得到那个在web.config节点中配置的数据库连接字符串
this._connectionString = System.Web.Configuration.WebConfigurationManager.ConnectionStrings[connStringName].ConnectionString;
base.Initialize(name, config);
}
public override string ApplicationName
{
get
{
return null;
}
set
{
//throw new Exception("The method or operation is not implemented.");
}
}
public override bool ChangePassword(string username, string oldPassword, string newPassword)
{
System.Data.SqlClient.SqlConnection conn = new System.Data.SqlClient.SqlConnection(this._connectionString);
try
{
conn.Open();
string sql = "UPDATE Users SET Password=@newPassword WHERE UserName=@username AND Password=@oldPassword";
System.Data.SqlClient.SqlCommand comm = new System.Data.SqlClient.SqlCommand(sql, conn);
comm.Parameters.AddWithValue("@username", username);
comm.Parameters.AddWithValue("@oldPassword", oldPassword);
comm.Parameters.AddWithValue("@newPassword", newPassword);
int result = comm.ExecuteNonQuery();
if (result > 0)
return true;
else
return false;
}
catch
{
return false;
}
finally
{
if (conn.State != ConnectionState.Closed)
conn.Close();
conn.Dispose();
}
}
public override bool ChangePasswordQuestionAndAnswer(string username, string password, string newPasswordQuestion, string newPasswordAnswer)
{
return false;
}
public override MembershipUser CreateUser(string username, string password, string email, string passwordQuestion, string passwordAnswer, bool isApproved, object providerUserKey, out MembershipCreateStatus status)
{
return this.CreateUser(username,password,email,"",out status);
}
public MembershipUser CreateUser(string username, string password, string email, string qq, out MembershipCreateStatus status)
{
System.Data.SqlClient.SqlConnection conn = new System.Data.SqlClient.SqlConnection(this._connectionString);
try
{
conn.Open();
string sql = "INSERT INTO Users VALUES (@username, @password, @email,@qq)";
System.Data.SqlClient.SqlCommand comm = new System.Data.SqlClient.SqlCommand(sql, conn);
comm.Parameters.AddWithValue("@username", username);
comm.Parameters.AddWithValue("@password", password);
comm.Parameters.AddWithValue("@email", email);
comm.Parameters.AddWithValue("@qq", qq);
comm.ExecuteNonQuery();
conn.Close();
status = MembershipCreateStatus.Success;
return (MyMembershipUser)GetUser(username, false);
}
catch (Exception ex)
{
status = MembershipCreateStatus.UserRejected;
return null;
}
}
public override bool DeleteUser(string username, bool deleteAllRelatedData)
{
return false;
}
public override bool EnablePasswordReset
{
get
{
return false;
}
}
public override bool EnablePasswordRetrieval
{
get
{
return false;
}
}
public override MembershipUserCollection FindUsersByEmail(string emailToMatch, int pageIndex, int pageSize, out int totalRecords)
{
totalRecords = 0;
return null;
}
public override MembershipUserCollection FindUsersByName(string usernameToMatch, int pageIndex, int pageSize, out int totalRecords)
{
totalRecords = 0;
return null;
}
public override MembershipUserCollection GetAllUsers(int pageIndex, int pageSize, out int totalRecords)
{
totalRecords = 0;
return null;
}
public override int GetNumberOfUsersOnline()
{
return 0;
}
public override string GetPassword(string username, string answer)
{
System.Data.SqlClient.SqlConnection conn = new System.Data.SqlClient.SqlConnection(this._connectionString);
try
{
conn.Open();
string sql = "SELECT password FROM Users WHERE username=@username";
System.Data.SqlClient.SqlCommand comm = new System.Data.SqlClient.SqlCommand(sql, conn);
comm.Parameters.AddWithValue("@username", username);
System.Data.SqlClient.SqlDataReader reader = comm.ExecuteReader();
if (reader.HasRows)
{
reader.Read();
return reader.GetString(0);
}
else
return null;
}
catch (Exception ex)
{
return null;
}
finally
{
if (conn.State != ConnectionState.Closed)
conn.Close();
conn.Dispose();
}
}
public override MembershipUser GetUser(object providerUserKey, bool userIsOnline)
{
return null;
}
public override MembershipUser GetUser(string username, bool userIsOnline)
{
System.Data.SqlClient.SqlConnection conn = new System.Data.SqlClient.SqlConnection(this._connectionString);
try
{
conn.Open();
string sql = "SELECT username,password,qq FROM Users WHERE username=@username";
System.Data.SqlClient.SqlCommand comm = new System.Data.SqlClient.SqlCommand(sql, conn);
comm.Parameters.AddWithValue("@username", username);
System.Data.SqlClient.SqlDataReader reader = comm.ExecuteReader();
if (reader.HasRows)
{
reader.Read();
MembershipUser user = GetUserFromReader(reader);
return user;
}
else
return null;
}
catch (Exception ex)
{
return null;
}
finally
{
if (conn.State != ConnectionState.Closed)
conn.Close();
conn.Dispose();
}
}
private MyMembershipUser GetUserFromReader(SqlDataReader reader)
{
string username = reader.GetString(0);
string email = reader.GetString(1);
string qq = String.Empty;
if (reader.GetValue(2) != DBNull.Value)
qq = reader.GetString(2);
MyMembershipUser u = new MyMembershipUser(this.Name,
username,
string.Empty,
email,
string.Empty,
string.Empty, false, false, DateTime.Now, DateTime.Now, DateTime.Now, DateTime.Now, DateTime.Now, qq);
return u;
}
public override string GetUserNameByEmail(string email)
{
return null;
}
public override int MaxInvalidPasswordAttempts
{
get
{
return 0;
}
}
public override int MinRequiredNonAlphanumericCharacters
{
get
{
return 0;
}
}
public override int PasswordAttemptWindow
{
get
{
return 0;
}
}
public override int MinRequiredPasswordLength
{
get
{
return 0;
}
}
public override MembershipPasswordFormat PasswordFormat
{
get
{
return MembershipPasswordFormat.Clear;
}
}
public override string PasswordStrengthRegularExpression
{
get
{
return null;
}
}
public override bool RequiresQuestionAndAnswer
{
get
{
return false;
}
}
public override bool RequiresUniqueEmail
{
get
{
return false;
}
}
public override string ResetPassword(string username, string answer)
{
return null;
}
public override bool UnlockUser(string userName)
{
return false;
}
public override void UpdateUser(MembershipUser user)
{
}
public override bool ValidateUser(string username, string password)
{
System.Data.SqlClient.SqlConnection conn = new System.Data.SqlClient.SqlConnection(this._connectionString);
try
{
conn.Open();
string sql = "SELECT * FROM Users WHERE UserName=@username AND Password=@password";
System.Data.SqlClient.SqlCommand comm = new System.Data.SqlClient.SqlCommand(sql, conn);
comm.Parameters.AddWithValue("@username", username);
comm.Parameters.AddWithValue("@password", password);
System.Data.SqlClient.SqlDataReader reader = comm.ExecuteReader();
if (reader.HasRows)
{
return true;
}
else
{
return false;
}
}
catch (Exception ex)
{
return false;
}
finally
{
if (conn.State != ConnectionState.Closed)
conn.Close();
conn.Dispose();
}
}
}
2. 自定义角色提供程序
创建一个继承 System.Web.Security 命名空间中 RoleProvider 抽象类的类。RoleProvider 抽象类继承 System.Configuration.Provider 命名空间的 ProviderBase 抽象类。因此,也必须实现 ProviderBase 类所需的成员。
using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Configuration.Provider;
using System.Data.SqlClient;
/**//// <summary>
/// MyRole 的摘要说明
/// </summary>
public class MyRoleProvider : RoleProvider
{
public MyRoleProvider()
{
//
// TODO: 在此处添加构造函数逻辑
//
}
string connectionstring = ConfigurationManager.ConnectionStrings["DatabaseConnectionString"].ConnectionString.ToString();
public override void AddUsersToRoles(string[] usernames, string[] rolenames)
{
foreach (string rolename in rolenames)
{
if (!RoleExists(rolename))
{
throw new ProviderException("Role name not found.");
}
}
foreach (string username in usernames)
{
if (username.Contains(","))
{
throw new ArgumentException("User names cannot contain commas.");
}
foreach (string rolename in rolenames)
{
if (IsUserInRole(username, rolename))
{
throw new ProviderException("User is already in role.");
}
}
}
SqlConnection conn = new SqlConnection(connectionstring);
SqlCommand cmd = new SqlCommand("INSERT INTO UsersInRoles (Username,Rolename) Values(@Username, @Rolename)", conn);
SqlParameter userParm = cmd.Parameters.Add("@Username",SqlDbType.VarChar, 255);
SqlParameter roleParm = cmd.Parameters.Add("@Rolename", SqlDbType.VarChar, 255);
SqlTransaction tran = null;
try
{
conn.Open();
tran = conn.BeginTransaction();
cmd.Transaction = tran;
foreach (string username in usernames)
{
foreach (string rolename in rolenames)
{
userParm.Value = username;
roleParm.Value = rolename;
cmd.ExecuteNonQuery();
}
}
tran.Commit();
}
catch (SqlException e)
{
try
{
tran.Rollback();
}
catch {
throw e;
}
}
finally
{
conn.Close();
}
}
public override string ApplicationName
{
get
{
throw new Exception("The method or operation is not implemented.");
}
set
{
throw new Exception("The method or operation is not implemented.");
}
}
public override void CreateRole(string rolename)
{
if (rolename.Contains(","))
{
throw new ArgumentException("Role names cannot contain commas.");
}
if (RoleExists(rolename))
{
throw new ProviderException("Role name already exists.");
}
SqlConnection conn = new SqlConnection(connectionstring);
SqlCommand cmd = new SqlCommand("INSERT INTO Roles " +
" (Rolename) " +
" Values(@Rolename)", conn);
cmd.Parameters.Add("@Rolename",SqlDbType.VarChar, 255).Value = rolename;
try
{
conn.Open();
cmd.ExecuteNonQuery();
}
catch (SqlException e)
{
throw e;
}
finally
{
conn.Close();
}
}
public override bool DeleteRole(string rolename, bool throwOnPopulatedRole)
{
if (!RoleExists(rolename))
{
throw new ProviderException("Role does not exist.");
}
if (throwOnPopulatedRole && GetUsersInRole(rolename).Length > 0)
{
throw new ProviderException("Cannot delete a populated role.");
}
SqlConnection conn = new SqlConnection(connectionstring);
SqlCommand cmd = new SqlCommand("DELETE FROM Roles " +
" WHERE Rolename =@Rolename ", conn);
cmd.Parameters.Add("@Rolename", SqlDbType.VarChar, 255).Value = rolename;
SqlCommand cmd2 = new SqlCommand("DELETE FROM UsersInRoles " +
" WHERE Rolename = @Rolename ", conn);
cmd2.Parameters.Add("@Rolename", SqlDbType.VarChar, 255).Value = rolename;
SqlTransaction tran = null;
try
{
conn.Open();
tran = conn.BeginTransaction();
cmd.Transaction = tran;
cmd2.Transaction = tran;
cmd2.ExecuteNonQuery();
cmd.ExecuteNonQuery();
tran.Commit();
}
catch (SqlException e)
{
try
{
tran.Rollback();
}
catch {
throw e;
}
}
finally
{
conn.Close();
}
return true;
}
public override string[] FindUsersInRole(string rolename, string usernameToMatch)
{
SqlConnection conn = new SqlConnection(connectionstring);
SqlCommand cmd = new SqlCommand("SELECT Username FROM UsersInRoles " +
"WHERE Username LIKE @UsernameSearch AND RoleName =@RoleName", conn);
cmd.Parameters.Add("@UsernameSearch", SqlDbType.VarChar, 255).Value = usernameToMatch;
cmd.Parameters.Add("@RoleName", SqlDbType.VarChar, 255).Value = rolename;
string tmpUserNames = "";
SqlDataReader reader = null;
try
{
conn.Open();
reader = cmd.ExecuteReader();
while (reader.Read())
{
tmpUserNames += reader.GetString(0) + ",";
}
}
catch (SqlException e)
{
throw e;
}
finally
{
if (reader != null) { reader.Close(); }
conn.Close();
}
if (tmpUserNames.Length > 0)
{
// Remove trailing comma.
tmpUserNames = tmpUserNames.Substring(0, tmpUserNames.Length - 1);
return tmpUserNames.Split(',');
}
return new string[0];
}
public override string[] GetAllRoles()
{
string tmpRoleNames = "";
SqlConnection conn = new SqlConnection(connectionstring);
SqlCommand cmd = new SqlCommand("SELECT Rolename FROM Roles ", conn);
SqlDataReader reader = null;
try
{
conn.Open();
reader = cmd.ExecuteReader();
while (reader.Read())
{
tmpRoleNames += reader.GetString(0) + ",";
}
}
catch (SqlException e)
{
throw e;
}
finally
{
if (reader != null) { reader.Close(); }
conn.Close();
}
if (tmpRoleNames.Length > 0)
{
// Remove trailing comma.
tmpRoleNames = tmpRoleNames.Substring(0, tmpRoleNames.Length - 1);
return tmpRoleNames.Split(',');
}
return new string[0];
}
public override string[] GetRolesForUser(string username)
{
string tmpRoleNames = "";
SqlConnection conn = new SqlConnection(connectionstring);
SqlCommand cmd = new SqlCommand("SELECT Rolename FROM UsersInRoles " +
" WHERE Username = @Username", conn);
cmd.Parameters.Add("@Username", SqlDbType.VarChar, 255).Value = username;
SqlDataReader reader = null;
try
{
conn.Open();
reader = cmd.ExecuteReader();
while (reader.Read())
{
tmpRoleNames += reader.GetString(0) + ",";
}
}
catch (SqlException e)
{
throw e;
}
finally
{
if (reader != null) { reader.Close(); }
conn.Close();
}
if (tmpRoleNames.Length > 0)
{
// Remove trailing comma.
tmpRoleNames = tmpRoleNames.Substring(0, tmpRoleNames.Length - 1);
return tmpRoleNames.Split(',');
}
return new string[0];
}
public override string[] GetUsersInRole(string rolename)
{
string tmpUserNames = "";
SqlConnection conn = new SqlConnection(connectionstring);
SqlCommand cmd = new SqlCommand("SELECT Username FROM UsersInRoles " +
" WHERE Rolename = @Rolename ", conn);
cmd.Parameters.Add("@Rolename", SqlDbType.VarChar, 255).Value = rolename;
SqlDataReader reader = null;
try
{
conn.Open();
reader = cmd.ExecuteReader();
while (reader.Read())
{
tmpUserNames += reader.GetString(0) + ",";
}
}
catch (SqlException e)
{
throw e;
}
finally
{
if (reader != null) { reader.Close(); }
conn.Close();
}
if (tmpUserNames.Length > 0)
{
// Remove trailing comma.
tmpUserNames = tmpUserNames.Substring(0, tmpUserNames.Length - 1);
return tmpUserNames.Split(',');
}
return new string[0];
}
public override bool IsUserInRole(string username, string rolename)
{
bool userIsInRole = false;
SqlConnection conn = new SqlConnection(connectionstring);
SqlCommand cmd = new SqlCommand("SELECT COUNT(*) FROM UsersInRoles " +
" WHERE Username = @Username AND Rolename = @Rolename", conn);
cmd.Parameters.Add("@Username", SqlDbType.VarChar, 255).Value = username;
cmd.Parameters.Add("@Rolename", SqlDbType.VarChar, 255).Value = rolename;
try
{
conn.Open();
int numRecs = (int)cmd.ExecuteScalar();
if (numRecs > 0)
{
userIsInRole = true;
}
}
catch (SqlException e)
{
throw e;
}
finally
{
conn.Close();
}
return userIsInRole;
}
public override void RemoveUsersFromRoles(string[] usernames, string[] roleNames)
{
throw new Exception("The method or operation is not implemented.");
}
public override bool RoleExists(string rolename)
{
bool exists = false;
SqlConnection conn = new SqlConnection(connectionstring);
SqlCommand cmd = new SqlCommand("SELECT COUNT(*) FROM Roles " +
" WHERE Rolename = @Rolename ", conn);
cmd.Parameters.Add("@Rolename", SqlDbType.VarChar, 255).Value = rolename;
try
{
conn.Open();
int numRecs = (int)cmd.ExecuteScalar();
if (numRecs > 0)
{
exists = true;
}
}
catch (SqlException e)
{
throw e;
}
finally
{
conn.Close();
}
return exists;
}
}
四.使用方法
1. 验证登录
protected void Button1_Click(object sender, EventArgs e)
{
string username = TextBox2.Text;
string pwd = TextBox1.Text;
if (Membership.ValidateUser(username, pwd))
FormsAuthentication.RedirectFromLoginPage(username, true);
else
Label1.Text = "login error";
}
2. 注册
protected void Button1_Click(object sender, EventArgs e)
{
string username = TextBox1.Text;
string password = TextBox2.Text;
string email = TextBox3.Text;
string qq = TextBox4.Text;
MembershipCreateStatus status;
((MyMembershipProvider) Membership.Provider).CreateUser(username,password,email,qq,out status);
}
3. 权限验证
User.IsInRole("admin"))
Response.Write("i'm admin");
4. 角色增加
protected void Button1_Click(object sender, EventArgs e)
{
string rolename = TextBox1.Text;
Roles.CreateRole(rolename);
}
5. 角色用户增加
protected void Button2_Click(object sender, EventArgs e)
{
string rolename = DropDownList1.SelectedValue;
string username = TextBox2.Text;
Roles.AddUsersToRoles(new string[] { username }, new string[] { rolename });
}
五.附加
用户表:
CREATE TABLE [dbo].[Users] (
[UserId] [int] IDENTITY (1, 1) NOT NULL ,
[UserName] [char] (20) COLLATE Chinese_PRC_CI_AS NULL ,
[Password] [char] (20) COLLATE Chinese_PRC_CI_AS NULL ,
[Email] [char] (30) COLLATE Chinese_PRC_CI_AS NULL ,
[QQ] [char] (10) COLLATE Chinese_PRC_CI_AS NULL
) ON [PRIMARY]
角色表:
CREATE TABLE [dbo].[Roles] (
[RoleId] [int] IDENTITY (1, 1) NOT NULL ,
[Rolename] [nvarchar] (50) COLLATE Chinese_PRC_CI_AS NULL
) ON [PRIMARY]
用户角色表:
CREATE TABLE [dbo].[UsersInRoles] (
[RoleName] [nvarchar] (50) COLLATE Chinese_PRC_CI_AS NOT NULL ,
[UserName] [nvarchar] (50) COLLATE Chinese_PRC_CI_AS NOT NULL
) ON [PRIMARY]