在非SqlServer数据库上实现MemberShip和Role功能(自定义MemberShipProvider和RoleProvider)

时间:2022-04-23
本文章向大家介绍在非SqlServer数据库上实现MemberShip和Role功能(自定义MemberShipProvider和RoleProvider),主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

默认情况下,.Net网站上的MemberShip和Role功能只能用于SqlServer,如果要在其它数据库,比如Access,Oracle上使用该功能该怎么办呢?

其实MS早就为我们考虑到了,用户只要从MemberShipProvider和RoleProvider派生自己的Provider类,并实现相关的方法和属性就可以了,其实ASPX中的MemberShip功能就是这二个抽象类在SqlServer上的实现(有兴趣的朋友可以查阅一下System.Web.Security.SqlMembershipProvider)

这里只是给出一个MemberShip的演示,数据库结构如下:

用户表T_LoginUser

F_ID            用户ID

F_LoginName     登录名  

F_Password      登录密码

自定义一个MyMemberShipProvider类,这里只实现了三个方法(Initialize,ValidateUser,CreateUser)

using System;

using System.Data;

using System.Data.SqlClient;

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;



/// <summary>

/// MyMemberShipProvider 的摘要说明

/// </summary>

public class MyMemberShipProvider:System.Web.Security.MembershipProvider

{

    public MyMemberShipProvider()

    {

        //

        // TODO: 在此处添加构造函数逻辑

        //

    }





    private string connStr;

    private bool _requiresQuestionAndAnswer;

    private int _minRequiredPasswordLength;



    public override int MinRequiredPasswordLength

    {

        get { return _minRequiredPasswordLength; }

    }

    public override bool RequiresQuestionAndAnswer

    {

        get

        {

            return _requiresQuestionAndAnswer;

        }

    }



    /// <summary>

    /// 初始化

    /// </summary>

    /// <param name="name"></param>

    /// <param name="config"></param>

    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);

    }



    /// <summary>

    /// 验证用户

    /// </summary>

    /// <param name="username"></param>

    /// <param name="password"></param>

    /// <returns></returns>

    public override bool ValidateUser(string username, string password)

    {

        using(SqlConnection conn = new SqlConnection(connStr))

        {

            SqlCommand comm = new SqlCommand();

            comm.CommandText = "Select Top 1 * From T_LoginUser Where F_LoginName=@LoginName And F_PassWord=@Password";

            comm.Parameters.AddWithValue("@LoginName", username);

            comm.Parameters.AddWithValue("@Password", password);

            comm.Connection = conn;

            conn.Open();

            using (SqlDataReader dr = comm.ExecuteReader())

            {

                if (dr.HasRows)

                {                   

                   return true;                    

                }

                return false;

            }

        }        

    }



    /// <summary>

    /// 创建用户

    /// </summary>

    /// <param name="username"></param>

    /// <param name="password"></param>

    /// <param name="email"></param>

    /// <param name="passwordQuestion"></param>

    /// <param name="passwordAnswer"></param>

    /// <param name="isApproved"></param>

    /// <param name="providerUserKey"></param>

    /// <param name="status"></param>

    /// <returns></returns>

    public override MembershipUser CreateUser(string username, string password, string email, string passwordQuestion, string passwordAnswer, bool isApproved, object providerUserKey, out MembershipCreateStatus status)

    {



        using (SqlConnection conn = new SqlConnection(connStr))

        {

            SqlCommand comm = new SqlCommand();

            comm.CommandText = "Insert Into T_LoginUser(F_LoginName,F_Password) values(@LoginName,@Password)";

            comm.Parameters.AddWithValue("LoginName", username);

            comm.Parameters.AddWithValue("Password", password);

            comm.Connection = conn;

            conn.Open();

            try

            {

                comm.ExecuteNonQuery();

            }

            catch (Exception Ex)

            {

                throw new Exception("创建用户失败!原因:" + Ex.Message.ToString());

            }



            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;

        }

    }



    public override string ApplicationName

    {

        get

        {

            throw new Exception("暂未实现");

        }

        set

        {

            throw new Exception("暂未实现");

        }

    }



    public override bool ChangePassword(string username, string oldPassword, string newPassword)

    {

        throw new Exception("暂未实现");

    }



    public override bool ChangePasswordQuestionAndAnswer(string username, string password, string newPasswordQuestion, string newPasswordAnswer)

    {

        throw new Exception("暂未实现");

    }



   



    public override bool DeleteUser(string username, bool deleteAllRelatedData)

    {

        throw new Exception("暂未实现");

    }



    public override bool EnablePasswordReset

    {

        get { throw new Exception("暂未实现"); }

    }



    public override bool EnablePasswordRetrieval

    {

        get { throw new Exception("暂未实现"); }

    }



    public override MembershipUserCollection FindUsersByEmail(string emailToMatch, int pageIndex, int pageSize, out int totalRecords)

    {

        throw new Exception("暂未实现");

    }



    public override MembershipUserCollection FindUsersByName(string usernameToMatch, int pageIndex, int pageSize, out int totalRecords)

    {

        throw new Exception("暂未实现");

    }



    public override MembershipUserCollection GetAllUsers(int pageIndex, int pageSize, out int totalRecords)

    {

        throw new Exception("暂未实现");

    }



    public override int GetNumberOfUsersOnline()

    {

        throw new Exception("暂未实现");

    }



    public override string GetPassword(string username, string answer)

    {

        throw new Exception("暂未实现");

    }



    public override MembershipUser GetUser(string username, bool userIsOnline)

    {

        throw new Exception("暂未实现");

    }



    public override MembershipUser GetUser(object providerUserKey, bool userIsOnline)

    {

        throw new Exception("暂未实现");

    }



    public override string GetUserNameByEmail(string email)

    {

        throw new Exception("暂未实现");

    }



    public override int MaxInvalidPasswordAttempts

    {

        get { throw new Exception("暂未实现"); }

    }



    public override int MinRequiredNonAlphanumericCharacters

    {

        get { throw new Exception("暂未实现"); }

    }





    public override int PasswordAttemptWindow

    {

        get { throw new Exception("暂未实现"); }

    }



    public override MembershipPasswordFormat PasswordFormat

    {

        get { throw new Exception("暂未实现"); }

    }



    public override string PasswordStrengthRegularExpression

    {

        get { throw new Exception("暂未实现"); }

    }



    public override bool RequiresUniqueEmail

    {

        get { throw new Exception("暂未实现"); }

    }



    public override string ResetPassword(string username, string answer)

    {

        throw new Exception("暂未实现");

    }



    public override bool UnlockUser(string userName)

    {

        throw new Exception("暂未实现");

    }



    public override void UpdateUser(MembershipUser user)

    {

        throw new Exception("暂未实现");

    }

}

顺便也给个MyRoleProvider.cs,不过啥也没干,放了一个空架子,呵呵

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;



/// <summary>

/// MyRoleProvider 的摘要说明

/// </summary>

public class MyRoleProvider:System.Web.Security.RoleProvider

{

    public MyRoleProvider()

    {

        //

        // TODO: 在此处添加构造函数逻辑

        //

    }



    // 摘要:

    //     获取或设置要存储和检索其角色信息的应用程序的名称。

    //

    // 返回结果:

    //     要存储和检索其角色信息的应用程序的名称。

    public override string ApplicationName 

    {

        get { throw new Exception("暂未实现"); }

        set { throw new Exception("暂未实现"); }

    }



    // 摘要:

    //     将指定用户名添加到已配置的 applicationName 的指定角色名。

    //

    // 参数:

    //   roleNames:

    //     一个字符串数组,其中包含要将指定用户名添加到的角色的名称。

    //

    //   usernames:

    //     一个字符串数组,其中包含要添加到指定角色的用户名。

    public override void AddUsersToRoles(string[] usernames, string[] roleNames) 

    {

        throw new Exception("暂未实现");

    }



    //

    // 摘要:

    //     在数据源中为已配置的 applicationName 添加一个新角色。

    //

    // 参数:

    //   roleName:

    //     要创建的角色的名称。

    public override void CreateRole(string roleName) 

    {

        throw new Exception("暂未实现");

    }



    //

    // 摘要:

    //     从数据源中移除已配置的 applicationName 的角色。

    //

    // 参数:

    //   throwOnPopulatedRole:

    //     如果为 true,则在 roleName 具有一个或多个成员时引发异常,并且不删除 roleName。

    //

    //   roleName:

    //     要删除的角色的名称。

    //

    // 返回结果:

    //     如果成功删除角色,则为 true;否则为 false。

    public override bool DeleteRole(string roleName, bool throwOnPopulatedRole) 

    {

        throw new Exception("暂未实现");

    }

    //

    // 摘要:

    //     获取属于某个角色且与指定的用户名相匹配的用户名的数组。

    //

    // 参数:

    //   usernameToMatch:

    //     要搜索的用户名。

    //

    //   roleName:

    //     作为搜索范围的角色。

    //

    // 返回结果:

    //     一个字符串数组,包含用户名与 usernameToMatch 匹配且用户是指定角色的成员的所有用户的名称。

    public override string[] FindUsersInRole(string roleName, string usernameToMatch) 

    {

        throw new Exception("暂未实现");

    }

    //

    // 摘要:

    //     获取已配置的 applicationName 的所有角色的列表。

    //

    // 返回结果:

    //     一个字符串数组,包含在数据源中存储的已配置的 applicationName 的所有角色的名称。

    public override string[] GetAllRoles() 

    {

        throw new Exception("暂未实现");

    }

    //

    // 摘要:

    //     获取指定用户对于已配置的 applicationName 所属于的角色的列表。

    //

    // 参数:

    //   username:

    //     要为其返回角色列表的用户。

    //

    // 返回结果:

    //     一个字符串数组,其中包含指定用户对于已配置的 applicationName 所属于的所有角色的名称。

    public override string[] GetRolesForUser(string username) 

    {

        throw new Exception("暂未实现");

    }

    //

    // 摘要:

    //     获取属于已配置的 applicationName 的指定角色的用户的列表。

    //

    // 参数:

    //   roleName:

    //     一个角色名称,将获取该角色的用户列表。

    //

    // 返回结果:

    //     一个字符串数组,其中包含属于已配置的 applicationName 的指定角色的成员的所有用户名。

    public override string[] GetUsersInRole(string roleName) 

    {

        throw new Exception("暂未实现");

    }

    //

    // 摘要:

    //     获取一个值,指示指定用户是否属于已配置的 applicationName 的指定角色。

    //

    // 参数:

    //   username:

    //     要搜索的用户名。

    //

    //   roleName:

    //     作为搜索范围的角色。

    //

    // 返回结果:

    //     如果指定用户属于已配置的 applicationName 的指定角色,则为 true;否则为 false。

    public override bool IsUserInRole(string username, string roleName) 

    {

        throw new Exception("暂未实现");

    }



    //

    // 摘要:

    //     移除已配置的 applicationName 的指定角色中的指定用户名。

    //

    // 参数:

    //   roleNames:

    //     一个字符串数组,其中包含要将指定用户名从中移除的角色的名称。

    //

    //   usernames:

    //     一个字符串数组,其中包含要从指定角色中移除的用户名。

    public override void RemoveUsersFromRoles(string[] usernames, string[] roleNames) 

    {

        throw new Exception("暂未实现");

    }



    //

    // 摘要:

    //     获取一个值,该值指示指定角色名是否已存在于已配置的 applicationName 的角色数据源中。

    //

    // 参数:

    //   roleName:

    //     要在数据源中搜索的角色的名称。

    //

    // 返回结果:

    //     如果角色名已存在于已配置的 applicationName 的数据源中,则为 true;否则为 false。

    public override bool RoleExists(string roleName) 

    {

        throw new Exception("暂未实现");

    }

}

下面是关键的Web。config配置

<?xml version="1.0"?>



<configuration>

    <appSettings/>

    <connectionStrings>

        <add name="connStr" connectionString="Data Source=.SQLEXPRESS;AttachDbFilename=|DataDirectory|demo.mdf;Integrated Security=True;User Instance=True" providerName="System.Data.SqlClient"/>

    </connectionStrings>

    <system.web>

        

        <compilation debug="true"/>

        

    <authentication mode="Forms">

      <forms defaultUrl="~/Default.aspx" name="MemberShipProviderDemo" cookieless="UseCookies"></forms>

    </authentication>

    

    

    

        <membership defaultProvider="MyMemberShipProvider">

            <providers>

                <add type="MyMemberShipProvider" name="MyMemberShipProvider" requiresQuestionAndAnswer="false" connectionString="Data Source=.SQLEXPRESS;AttachDbFilename=|DataDirectory|demo.mdf;Integrated Security=True;User Instance=True"/>

            </providers>

        </membership>   

    

    

    </system.web>

</configuration>

好了,随便建一个Default.aspx,放一个Login控件和CreateUserWizard控件就可以测试了