自定义RoleProvider和MembershipProvider

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.lemongtree.com/download/MemberShip.rar

7 Responses

  1. 幻想曲 November 28 2006 , 00:57
    幻想曲
    说明一下:
    admin.aspx只允许角色为admin的进入
    guest.aspx只允许角色为guest的进入
    admin用户有admin和guest二种角色
    而guest用户只有guest角色,所以guest是进不了admin.aspx页面的
    #1
  2. 非目 November 28 2006 , 13:52
    非目
    谢谢 长知识
    #2
  3. popmao December 9 2006 , 04:52
    popmao
    好东西 我想请教你几个问题,希望能得到你的帮助:)

    引用你的一段话:
    在这个Demo中,MembershipProvider中要重写的方法有:ValidateUser
    因为我只是为了验证用户,要实现创建、编辑,就要实现UpdateUser方法、CreateUser方法了。


    1.要实现创建、编辑,需要重写UpdateUser方法、CreateUser方法吗? 如果需要,是否跟ValidateUser方法的重写相似?

    2.我怎么看完了代码也每看见在什么地方使用了MyMemberShip.cs中的ValidateUser方法的重写呢? 我应该从那里了解它的运行机制?

    3.使用自带的Login控件有那些优势? 如果不用的话,应该用什么方法?

    说一下我的看法,望指正:) 我原来用asp做过一些程序,现在才刚转到asp.net,觉得最大的改变是asp.net是面向对象的,现在我觉得asp.net学起来吃力,就因为不懂面向对象编程,例如重写…… 原来在asp中的登录验证系统我是这样做的:

    在添加用户的时候设置他的权限标签,然后存入数据库中“role”字段,然后通过查询是否含有权限标签来验证用户。

    例如:
    用户admin的权限为:可以访问a.asp(对应权限标签为 a)和b.asp(对应权限标签为b )这两个页面,
    因此admin的数据库记录中的 “role”字段值为" a,b ".
    当用户要访问a.asp页面的时候,就先查询该用户数据库记录中的 role 字段值是否含有 “a” ,有的话则继续访问,没有的话则离开。

    看完你的这个demo,发现与我原来用asp的方式非常相似啊,只是那些验证在web.config中。

    下面说回原话题,如果不用自带的Login控件,是否也是使用asp的方式(如我上面说的)?似乎也很简单啊

    突然觉得我能回答第一个问题:不需要。不指导正确否? 创建、编辑用户不是只要更新数据库嘛,和一般的数据库操作一样。这是我的理解。

    说了这么一大堆,希望你能多指点一下:) 谢谢了
    #3
  4. yoyo December 19 2006 , 09:55
    yoyo
    你好,我最近也一直在研究membership等功能,但是我始终有个地方不是太明白.MS的提供的数据库对于用户信息的表示太简单了.如果想添加用户信息就要通过Profile来实现.信息少还可以全部多放在profile里面.但是如果有很多的自定义用户信息应该怎么处理呢...期待回复.MSN:yearning_N@hotmail.com
    #4
  5. zahota March 22 2007 , 04:26
    zahota
    提供程序的connectionStringName是存放在web.config中连接字符串的名字的
    作者直接使用connectionString不知道会不会报错,我觉得使用connectionStringName还是好一点,然后多个提供程序都用一个就可以了,
    #5
  6. 幻想曲 March 22 2007 , 08:52
    幻想曲
    这个Demo当然有些不足,但重点在于演示MembershipProvider与RoleProvider[em1]
    #6
  7. xzr2004 August 7 2007 , 11:52
    xzr2004
    我用了CreateUserWizard的ContentTemplate來實現自定義用戶注冊,重寫了
    MyRole,MyMemberShip,分別派生於RoleProvider,MembershipProvider,
    DATABASE 為自己新建的,有個Users table,我點畿CreateUserWizard里的注冊,出錯Could not find stored procedure'dbo.aspnet_CheckSchemaVersion'.不知怎么解決,我web.config如下:



    requiresUniqueEmail="true" passwordFormat="Hashed" maxInvalidPasswordAttempts="5" minRequiredPasswordLength="7" minRequiredNonalphanumericCharacters="0"
    passwordAttemptWindow="10" passwordStrengthRegularExpression="" name="AspNetSqlServer2005Provider" type="System.Web.Security.SqlMembershipProvider, System.Web, Version=2.0.0.0, Culture=neutral,PublicKeyToken=b03f5f7f11d50a3a"/>





    #7

Write a comment:



(Will show your Gravatar icon)  



[b][/b] - [i][/i] - [u][/u]- [quote][/quote]

:-/ ^_^ :d :o :kiss: :) :p :se: [yeah] :( :love: :han: :up: :cry: :zzz: o_o

申请链接请看这里