Asp.net的membership提供了一种存储,验证和管理用户信息以及权限的统一的路径。membership所对应的验证方式是asp.net的Forms身份验证(注:asp.net的身份验证方式 有好几种包括windows身份验证 Forms身份验证 Passport身份认证当然还有就是没有验证)。在vs2005中 还给membership提供了一系列的控件(login控件),能方便的在asp.net实现membership。
具体来说membership能实现:
1. 创建用户
2. 可以保存membership信息在sql server,Active Directory以及其他的一些数据保存方法
3. 鉴别谁在访问你的网站。如果使用login控件,几乎可以在不写代码的情况下完成。
4. 管理密码。包括 创建 修改 重置
5. 创建一个唯一的值来标志每一个登陆用户,可以实现对用户的个性化以及角色管理。
6. 提供一个用户自定义的membership provider,从而实现一些自己网站特有的数据的保存和管理。
让membership能工作要做的一些工作:
1. 在web.config中填写一些membership的设置,在asp.net默认情况下membership是被允许使用的 而默认的数据保存是使用ms的sql server.你可以做些设置提供其他的数据保存方法 包括自定义的方法。这将在后面的文章中具体介绍
2. 设置你的网站使用Forms验证方式,
3. 为membership定义用户帐号。可以使用vs2005提供的web administrator tool进行设置,也可以自己制作create user页面进行,而自定义页面 只要调用membership.createuser就可以方便的创建用户。
Membership的管理和配置:
在web.config中配置管理membership最简单的方法就是使用Web Site Administration Tool(在vs2005的websits菜单里)。你可以指定membership的提供者sql server还是其他,密码的管理 包括是否要加密保存 以及是否要给用户提供根据事先设置的问题 恢复密码的机制。当然是用web site administration tool可以直接创建和管理用户及角色。
Membership的方便之处在于,当一个用户通过认证之后,他的信息的保存都是系统自动完成的 这样我以前最头痛的如何安全完整的在各个页面中传递登陆用户信息这点就迎刃而解了。
如果使用vs2005自带的login控件 要清楚一件事 就是login控件的功能实现都是调用了membership的类函数,我们完全可以自己写出所有的控件。
这里主要是把如何实现自定义的membership记录一下,便于以后查阅。
首先,我们需要一个数据表来存储用户的个人信息:UserName,Password,Email,PasswordQuestion,PasswordAnswer。
在vs中新建一个web网站或者web应用程序,新建一个login.aspx登录页面,在login.aspx中拖入一个login控件,在default.aspx页面上拖上两个login控件,首先拖上去一个CreateUserWizard控件,不用做什么修改,接着在CreateUserWizard控件下面放上一个LoginView控件,在LoginView的AnonymousTemplate 视图里拖上一个LoginStatus控件,并把LoginStatus控件的LogoutPageUrl设置为login.aspx。页面部分就这些。
然后在项目里新建一个类,命名为MyMembershipProvider.cs,类的名字 MyMembershipProvider.继承自MembershipProvider,vs2005会帮我们生成可以重载的函数(右键点击MembershipProvider选择实现虚函数),我们这里不会建立所有的新函数,,我们重载两个属性和两个函数
首先建几个私有变量
private string connStr;//保存数据库连接字符串
private bool _requiresQuestionAndAnswer;//是否需要问题和回答
private int _minRequiredPasswordLength;//最短密码长度
需要重载的属性为:
MinRequiredPasswordLength
RequiresQuestionAndAnswer
重载的函数
public override void Initialize(string name, System.Collections.Specialized.NameValueCollection config)//
该方法需要手动添加
public override bool ValidateUser(string username, string password)//验证用户
public override MembershipUser CreateUser(string username, string password, string email, string passwordQuestion, string passwordAnswer, bool isApproved, object providerUserKey, out MembershipCreateStatus status)//创建用户
下面是代码:
public override int MinRequiredPasswordLength
{
get { return _minRequiredPasswordLength; }
}
public override bool RequiresQuestionAndAnswer
{
get
{
return _requiresQuestionAndAnswer;
}
}
public override void Initialize(string name, System.Collections.Specialized.NameValueCollection config)
{
if (config["requiresQuestionAndAnswer"].ToLower() == "true")
{
_requiresQuestionAndAnswer = true;
}
else
{
_requiresQuestionAndAnswer = false;
}
int.TryParse (config["minRequiredPasswordLength"],out _minRequiredPasswordLength );
connStr = config["connectionString"];
base.Initialize(name, config);
}
public override MembershipUser CreateUser(string username, string password, string email, string passwordQuestion, string passwordAnswer, bool isApproved, object providerUserKey, out MembershipCreateStatus status)
{
//throw new NotImplementedException();
System.Data.SqlClient.SqlConnection conn = new System.Data.SqlClient.SqlConnection(connStr);
try
{
conn.Open();
string sql = "insert into UserInof(username,password,Email,passwordQuestion,passwordAnswer) values(@username,@password,@email,@pq,@pa)";
System.Data.SqlClient.SqlCommand command = new System.Data.SqlClient.SqlCommand(sql, conn);
command.Parameters.AddWithValue("@username", username);
command.Parameters.AddWithValue("@password", password);
command.Parameters.AddWithValue("@email", email);
command.Parameters.AddWithValue("@pq", passwordQuestion);
command.Parameters.AddWithValue("@pa", passwordAnswer);
command.ExecuteNonQuery();
MembershipUser user = new MembershipUser("MyMembershipProvider", username, providerUserKey, email, passwordQuestion, "", isApproved, true, DateTime.Now, DateTime.Now, DateTime.Now, DateTime.Now, DateTime.Now);
status = MembershipCreateStatus.Success;
return user;
}
catch
{
if (conn.State == System.Data.ConnectionState.Open)
conn.Close();
status = MembershipCreateStatus.ProviderError;
return null;
}
}
public override bool ValidateUser(string username, string password)
{
//throw new NotImplementedException();
System.Data.SqlClient.SqlConnection conn = new System.Data.SqlClient.SqlConnection(connStr);
try
{
conn.Open();
string sql = "select * from UserInfo where username=@username and password=@password";
System.Data.SqlClient.SqlCommand command = new System.Data.SqlClient.SqlCommand(sql, conn);
command.Parameters.AddWithValue("@username", username);
command.Parameters.AddWithValue("@password", password);
System.Data.SqlClient.SqlDataReader reader = command.ExecuteReader();
if (reader.HasRows)
{
conn.Close();
return true;
}
else
{
conn.Close();
return false;
}
}
catch
{
if (conn.State == System.Data.ConnectionState.Open)
conn.Close();
return false;
}
}
完成这些代码后 基本上就可以开始测试了,在测试之后我们要建立一个web.config文件在web site中,然后在 <system.web>中填入
<authentication mode="
Forms"/>
<membership defaultProvider="MyMembershipProvider">
<providers>
<add name="MyMembershipProvider" type="MyMembershipProvider" requiresQuestionAndAnswer="true" connectionString="Data Source = localhost;Initial Catalog=Merbership;User Id = sa;Password=123;"/>
</providers>
</membership>
将authentication 修改成 <authentication mode="Forms"/>
之后可以启动页面来进行测试了,login控件会根据web.config的配置使用Membership Provider 我们在web.config中defaultProvider中填入了MyMembershipProvider,它就会用我们自己编写的代码来执行了,你可以修改<add 中的requiresQuestionAndAnswer的值 看看CreateUserWizard控件的显示有什么变化。
参考:
http://www.cnblogs.com/dotLive/archive/2006/08/11/474622.html
BlogEngine.Net,他们自定义了MemberShip Provider,代码也写的很清晰,如果要学习,可以参考他们的代码,在源代码目录:(source)\BlogEngine.Core\Providers\里的DbMembershipProvider.cs和DbRoleProvider.cs