zoukankan      html  css  js  c++  java
  • Understanding ASP.NET Provider Model (Creating Custom Membership and Role Providers) Part 3

    Introduction

    In the Part 1 and Part 2 we learnt the concept and internal architecture of ASP.NET provider model. We know that the provider model is extensible and one can implement custom providers to suit his requirement. In this part we will develop two custom providers - one for membership and the other for roles.

    Why develop a custom membership and role provider?

    Well. There can be many reasons. Here are few:

    • You have custom data store (not SQL Server or Access) in which you want to store user data.
    • You are using some non-standard database for which there is no inbuilt membership or role providers.
    • You want to implement custom encryption mechanism for the data being saved and retrieved
    • You want to write database independent membership and role provider

    One more reason that I have not listed in the above list is - You may want to use your own table schema instead of using inbuilt one. At first glance it may look odd but it can be a great way to save your work while migrating applications.

    Requirements

    Let's decide the requirements for building our custom membership and role providers.

    • We want to use our application database for storing membership and role information. That also means that we do not have a central database for storing membership details of multiple applications
    • We want to store membership details in a table called Users
    • We want to store available roles in the system in a table called Roles
    • We want to store user-role mapping in a table called UserRoles
    • For the sake of simplicity we will not include any encryption-decryption logic
    • User can register by supplying user name, password and email. No security question is required
    • We do not need features such as password reset and accounting locking

    Database access

    We will be using BinaryIntellect DatabaseHelper open source component for all our database access.

    Creating the Web Site

    To begin, create a new web site and add two classes called MyMembershipProvider and MyRoleProvider to App_Code folder. For the sake of simplicity we will be creating all the necessary classes in the web site itself. In a more real world situations you may create a separate class library project to contain these classes.

    Configuring the web site to use our providers

    Open the web.config file and add the following markup:

    <membership defaultProvider="mymembershipprovider">
    <providers>
    <add name="mymembershipprovider" 
    type="MyMembershipProvider" 
    connectionStringName="connstr"/>
    </providers>
    </membership> 
    <roleManager enabled="true" defaultProvider="myrolesprovider"> 
    <providers> 
    <add name="myrolesprovider" 
    type="MyRolesProvider" 
    connectionStringName="connstr"/> 
    </providers>
    </roleManager>

    Here, we instruct ASP.NET to use MyMembershipProvider class as membership provider and MyRolesProvider class as roles provider.

    Creating custom membership provider

    Recollect from Part 2 that custom membership providers need to inherit from System.Web.Security.MembershipProvider class. The MembershipProvider class in turn inherits from ProviderBase class. The MembershipProvider class contains several abstract methods that you must implement in your class.

    If you are using VS.NET then your job is simple. Right click on the MembershipProvider class in the class definition line and choose "Implement Abstract Class". VS.NET will add dummy delimitations for all the required methods and properties from the MembershipProvider class. The following table lists all the properties and methods that you need to implement (methods are shown with parenthesis).

    Property/Method Name Description
    Initialize()* Receives the connection string name specified in the web.config file. You can use it to perform database operation in your class.
    Name* Represents name of our custom provider
    CreateUser()* Creates a user
    UpdateUser()* Saves modified information about an existing user
    DeleteUser()* Deletes a user
    GetUser()* Gets a user as MembershipUser instance
    GetAllUsers()* Gets all the users as MembershipUserCollection
    ChangePassword()* Changes password of a user
    GetPassword()* Retrieves password of a user. Used when implementing "Forgot Password" feature
    ValidateUser()* Authenticates the user
    EnablePasswordReset* Indicates whether the password can be reset by the user
    EnablePasswordRetrieval* Indicates whether the password can be retrieved by teh user
    RequiresQuestionAndAnswer* Indicates whether user should supply a security question and answer during registration
    RequiresUniqueEmail* Indicates whether the email supplied during registration should be unique
    ApplicationName Name of the web application. This name is used in case you are using a central database for storing membership data of multiple applications
    MaxInvalidPasswordAttempts Indicates the number of times user can try to login to the system
    MinRequiredNonAlphanumericCharacters Indicates minimum no. of non alpha numeric characters that the user must supply during registration and password change
    MinRequiredPasswordLength Indicates the minimum length required for the password when user registers or changes the password
    ChangePasswordQuestionAndAnswer() Allows to change user's security question and answer
    FindUsersByEmail() Searches user database on the basis of email
    FindUsersByName() Searches user database on the basis of user name
    GetNumberOfUsersOnline() Returns total no. of uses that are signed in
    GetUser() Returns MembershipUser instance representing a specific user
    GetUserNameByEmail() Returns the user name on the basis of email
    PasswordAttemptWindow Indicates the time span for multiple login attempts
    PasswordFormat Indicates the format of password e.g.clear, hashed etc.
    PasswordStrengthRegularExpression Indicates a regular expression to be used to check the strength of password
    ResetPassword() Resets the password
    UnlockUser() Unlocks the user account

    In our example we will code the methods and properties marked with * above. The remaining members will simply throw a "Not implemented" exception.

    The complete source code of our custom membership provider can be found in the download (MyMembershipProvider.cs). As an example CreateUser() method implementation is given below:

    public override MembershipUser CreateUser
    (string username, string password, 
    string email, string passwordQuestion, 
    string passwordAnswer, bool isApproved, 
    object providerUserKey, 
    out MembershipCreateStatus status)
    {
    MembershipUser user = new MembershipUser(Name, 
    username, providerUserKey, email, passwordQuestion,
     null, isApproved, false, DateTime.Now, DateTime.Now, 
    DateTime.Now, DateTime.Now, DateTime.Now);
    string sql = "INSERT INTO USERS(USERNAME,PASSWORD,
    EMAIL,ISACTIVE) VALUES(@UID,@PWD,@EMAIL,@ISACTIVE)";
    db.AddParameter("@UID", username);
    db.AddParameter("@PWD", password);
    db.AddParameter("@EMAIL", email);
    db.AddParameter("@ISACTIVE", 
    (isApproved == true ? "Y" : "N"));
    int i = db.ExecuteNonQuery(sql);
    if (i > 0)
    {
    status = MembershipCreateStatus.Success;
    return user;
    }
    else
    {
    status = MembershipCreateStatus.ProviderError;
    return null;
    }
    }

    Creating custom roles provider

    Creating custom roles provider involves creating a class that inherits from RoleProvider class. The following table lists all the properties and methods that you need to implement (methods are shown with parenthesis).

    Property/Method Name Description
    Initialize()* Receives the connection string name specified in the web.config file. You can use it to perform database operation in your class.
    Name* Represents name of our custom provider
    CreateRole* Create a new role
    DeleteRole* Deletes an existing role
    GetAllRoles* Returns all roles as string array
    RoleExists* Checks if role exists in the database
    AddUsersToRoles* Adds users to specified roles
    RemoveUsersFromRoles* Removes users from specified roles
    GetRolesForUser* Returns all the roles for a specific user
    GetUsersInRole* Returns all the users belonging to a specified role
    IsUserInRole* Checks if a user exists in a specified role
    ApplicationName Name of the web application. This name is used in case you are using a central database for storing membership data of multiple applications
    FindUsersInRole Searches for users belonging to a specified role

    In our example we will code the methods and properties marked with * above. The remaining members will simply throw a "Not implemented" exception.

    The complete source code of our custom membership provider can be found in the download (MyRolesProvider.cs). As an example CreateRole() method is given below:

    public override void CreateRole(string roleName) 
    { 
    db.AddParameter("@ROLE", roleName); 
    db.ExecuteNonQuery
    ("INSERT INTO ROLES(ROLENAME) VALUES(@ROLE)"); 
    }

    Testing our providers

    There are four test web forms provided along with the download - Default.aspx, Login.aspx, RoleManager.aspx and UserRoles.aspx. The first two test the membership provider and the later two test the roles provider. We use essentially the same Membership and Roles classes of ASP.NET. These classes in turn call our custom provides to get the job done.

    Summary

    In this article we saw how easy it is to develop your own providers for membership and role management. You can extend the application to suit your needs. You can also add more security features such as encryption and password strength.

  • 相关阅读:
    【Git】Git 学习笔记(一)
    【工程 Shell】Shell 学习(一)
    Vue 使用 Antd 简单实现左侧菜单栏和面包屑功能
    GoF的23种设计模式的功能
    ASP 对数据库的操作
    注册表修改USB状态(开与关)
    EXE文件关联修复
    CentOS8安装Docker
    GoogleEarth无法连接服务器解决方法
    【转】Qt 实现的拷贝 文件/文件夹 的函数
  • 原文地址:https://www.cnblogs.com/igtea/p/334586.html
Copyright © 2011-2022 走看看