自定义RoleProvider和MembershipProvider

2006年11月28日 1:40 上午  |  分类:Develop

csdn上有朋友问到这,随写了该文。

为什么要自定义呢?
首先,自定义有更大的灵活性,不必过份依赖于aspnetdb数据库,有利于自己的扩展;其次,自定义以后仍然可以用.Net 2.0中自带的Login控件。
当然,自定义不是随便自定义,而要是实现二个抽象类:
MembershipProvider和RoleProvider
这二个抽象类的说明请参见SDK 2.0或MSDN,这里不多说了。
在这个Demo中,MembershipProvider中要重写的方法有:ValidateUser
因为我只是为了验证用户,要实现创建、编辑,就要实现UpdateUser方法、CreateUser方法了。
看ValidateUser方法的重写:[MyMemberShip.cs]

 public override bool ValidateUser(string username, string password)
    {
        using (OleDbConnection conn = new OleDbConnection(connectionstring))
        {
            OleDbCommand comm = new OleDbCommand();
            comm.CommandText = “select count(0) from users where u_name=@name and u_pwd=@pwd”;
            comm.Parameters.AddWithValue(“@name”, username);
            comm.Parameters.AddWithValue(“@pwd”, password);
            comm.Connection = conn;
            conn.Open();
            return ((int)comm.ExecuteScalar()) > 0 ? true : false;
        }
    }

这里的变量connectionstring我写在.cs里了,这只是为了演示,应该写在web.config中的。这个方法不用多说,相信大家能看明白。
这就实现了用户的验证。
下面实现角色的验证[MyRole.cs]
要实现的方法有:
 bool IsUserInRole(string username, string roleName)
用于验证用户是否属于指定的角色

public override bool IsUserInRole(string username, string roleName)
    {
        using (OleDbConnection conn = new OleDbConnection(connectionstring))
        {
            OleDbCommand comm = new OleDbCommand();
            comm.CommandText = “select top 1 * from users where u_name=@name and u_role=@role”;
            comm.Parameters.AddWithValue(“@name”, username);
            comm.Parameters.AddWithValue(“@role”, roleName);
            comm.Connection = conn;
            conn.Open();
            using (OleDbDataReader dr = comm.ExecuteReader())
            {
                if (dr.HasRows)
                {
                   
                        return true;
                    
                }
                return false;
            }
        }
    }

代码简单,也不多说了
第二个要实现的方法:
string[] GetRolesForUser(string username),取得当前用户的所有角色列表

public override string[] GetRolesForUser(string username)
    {
        string[] tmp = new string[] { };
        using (OleDbConnection conn = new OleDbConnection(connectionstring))
        {
            OleDbCommand comm = new OleDbCommand();
            comm.CommandText = “select top 1 * from users where u_name=@name”;
            comm.Parameters.AddWithValue(“@name”, username);
           
            comm.Connection = conn;
            conn.Open();
            using (OleDbDataReader dr = comm.ExecuteReader())
            {
                if (dr.Read())
                {

                    tmp = dr["U_role"].ToString().Split(‘,’);

                }

            }
        }
        return tmp;
    }

下面就是更改web.config了
首先,需要对相关页作forms验证
<authentication mode=”Forms”>
            <forms defaultUrl=”default.aspx” loginUrl=”userlogin.aspx” path=”/” name=”Demo”/>
        </authentication>
注意下面的配置,重中之重

<membership defaultProvider=“MyMemberShip”>
            <providers>
                <add name=“MyMemberShip” type=“MyMemberShip” requiresQuestionAndAnswer=“true” connectionString=“Provider=Microsoft.Jet.OLEDB.4.0;Data Source=H:\Documents and Settings\Administrator\桌面\Demo\demo.mdb;Persist Security Info=False”/>
            </providers>
        </membership>
        <roleManager defaultProvider=“MyRole” enabled=“true”>
            <providers>
                <add name=“MyRole” type=“MyRole”/>
            </providers>
        </roleManager>

注意roleManager中的enabled一定要为true,否则会失效。

<location path=“admin.aspx”>
        <system.web>
            <authorization>
                <allow roles=“admin”/>
                <deny users=“*”/>
            </authorization>
        </system.web>
    </location>
    <location path=“guest.aspx”>
        <system.web>
            <authorization>
                <allow roles=“guest”/>
                <deny users=“*”/>
            </authorization>
        </system.web>
    </location>

对admin.aspx与guest.aspx做不同的角色控制
累了,直接看demo吧
用户名   密码
admin    admin   
guest    guest

http://demo.lemongtree.com/default.aspx

下载:
http://www.yibin001.com/download/MemberShip.rar

重写MembershipProvider实现自己的身份验证

2006年10月13日 12:46 下午  |  分类:Develop

众所周知 .Net 2.0推出来以后一些新的控件给我们的开发带来极大的便利在Form验证上更是如此内置的Login控件可以让我们不写一行代码实现基本的Form验证
这样的验证默认是基于AspNetSqlProvider验证的利用的数据库是aspnet_db库但有时我们需要用自己的用户库,又想用login控件那该怎么办呢?
我们可以重写MembershipProvider类该类是一个抽象类,我们可以通过重写来实现我们所需要的结果具体关于该类的属性和方法可参阅MSDN文档,这里就不浪费口水了先看我写的这个

using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Data.SqlClient;
/// /// SqlMembershipProvider 的摘要说明 ///
public class SqlMembershipProvider : MembershipProvider
{
private string connStr = ConfigurationManager.ConnectionStrings["DefaultConnectionstrings"].ConnectionString;
private bool _requiresQuestionAndAnswer;
private int _minRequiredPasswordLength;
public SqlMembershipProvider()
{
// // TODO: 在此处添加构造函数逻辑 //
}
public override void Initialize(string name, System.Collections.Specialized.NameValueCollection config)
{
if (config["requiresQuestionAndAnswer"].ToLower() == "true")
_requiresQuestionAndAnswer = true;
else
_requiresQuestionAndAnswer = false;
int.TryParse(config["minPasswordLength"], out _minRequiredPasswordLength);
base.Initialize(name, config);
}
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 bool ChangePassword(string username, string oldPassword, string newPassword) { throw new Exception("The method or operation is not implemented."); }
public override bool ChangePasswordQuestionAndAnswer(string username, string password, string newPasswordQuestion, string newPasswordAnswer) { throw new Exception("The method or operation is not implemented."); }
public override MembershipUser CreateUser(string username, string password, string email, string passwordQuestion, string passwordAnswer, bool isApproved, object providerUserKey, out MembershipCreateStatus status) { throw new Exception("The method or operation is not implemented."); }
public override bool DeleteUser(string username, bool deleteAllRelatedData) { throw new Exception("The method or operation is not implemented."); }
public override bool EnablePasswordReset { get { throw new Exception("The method or operation is not implemented."); } }
public override bool EnablePasswordRetrieval { get { throw new Exception("The method or operation is not implemented."); } }
public override MembershipUserCollection FindUsersByEmail(string emailToMatch, int pageIndex, int pageSize, out int totalRecords) { throw new Exception("The method or operation is not implemented."); }
public override MembershipUserCollection FindUsersByName(string usernameToMatch, int pageIndex, int pageSize, out int totalRecords) { throw new Exception("The method or operation is not implemented."); }
public override MembershipUserCollection GetAllUsers(int pageIndex, int pageSize, out int totalRecords) { throw new Exception("The method or operation is not implemented."); }
public override int GetNumberOfUsersOnline() { throw new Exception("The method or operation is not implemented."); }
public override string GetPassword(string username, string answer) { throw new Exception("The method or operation is not implemented."); }
public override MembershipUser GetUser(string username, bool userIsOnline) { throw new Exception("The method or operation is not implemented."); }
public override MembershipUser GetUser(object providerUserKey, bool userIsOnline) { throw new Exception("The method or operation is not implemented."); }
public override string GetUserNameByEmail(string email) { throw new Exception("The method or operation is not implemented."); }
public override int MaxInvalidPasswordAttempts { get { throw new Exception("The method or operation is not implemented."); } }
public override int MinRequiredNonAlphanumericCharacters { get { throw new Exception("The method or operation is not implemented."); } }
public override int MinRequiredPasswordLength { get { return _minRequiredPasswordLength; } }
public override int PasswordAttemptWindow { get { throw new Exception("The method or operation is not implemented."); } }
public override MembershipPasswordFormat PasswordFormat { get { throw new Exception("The method or operation is not implemented."); } }
public override string PasswordStrengthRegularExpression { get { throw new Exception("The method or operation is not implemented."); } }
public override bool RequiresQuestionAndAnswer { get { return _requiresQuestionAndAnswer; } }
public override bool RequiresUniqueEmail { get { throw new Exception("The method or operation is not implemented."); } }
public override string ResetPassword(string username, string answer) { throw new Exception("The method or operation is not implemented."); }
public override bool UnlockUser(string userName) { throw new Exception("The method or operation is not implemented."); }
public override void UpdateUser(MembershipUser user) { throw new Exception("The method or operation is not implemented."); }
//验证用户
public override bool ValidateUser(string username, string password)
{
using (SqlConnection conn = new SqlConnection(connStr))
{
SqlCommand comm = new SqlCommand();
comm.CommandText = "select * from registers where name=@name and pwd=@pwd";
comm.Parameters.Add("@name", SqlDbType.NVarChar, 50).Value = username;
comm.Parameters.Add("@pwd", SqlDbType.VarChar, 100).Value = password;
comm.Connection = conn;
conn.Open();
SqlDataReader dr = comm.ExecuteReader(CommandBehavior.CloseConnection);
if (dr.HasRows) return true; return false;
}
}
}

还有一些方法大家就参阅文档了,最后要做的就是修改你的web.config文件,这样就可以用Login控件来实现自己的身份验证了,同样你也可以重写RoleProvider类来实现自己的基于角色的身份验证