国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > .NET > 正文

ASP.NET 2.0 Membership

2024-07-10 13:09:45
字體:
來源:轉載
供稿:網友

摘要:asp.net 2.0的membership組件提供了一組非常簡單易用的接口供開發者進行用戶管理,用戶驗證。本文將它對它的實現原理進行簡單的分析,介紹如何正確的使用,以及如何對它進擴展。

一、membershipprovider抽象類

在很多情況下,在使用membership的時候我們并不會直接使用到這個類。在membershipprovider類定義的都是一些抽象方法和抽象屬性,就是這些方法和屬性構成了membership接口的基本規范,而且在.net 框架內部使用membership的功能都是通過這個類型調用的。繼承類通過實現這些接口來提供不用環境下的用戶管理功能,并且對membership框架本身并沒有影響,下面來看看membershipprovider原形定義:


public abstract class membershipprovider : providerbase

...{

      // events

      public event membershipvalidatepasswordeventhandler validatingpassword;

 

      // methods

      protected membershipprovider();

      public abstract bool changepassword(string username, string oldpassword, string newpassword);

      public abstract bool changepasswordquestionandanswer(string username, string password, string newpasswordquestion, string newpasswordanswer);

      public abstract membershipuser createuser(string username, string password, string email, string passwordquestion, string passwordanswer, bool isapproved, object provideruserkey, out membershipcreatestatus status);

      protected virtual byte[] decryptpassword(byte[] encodedpassword);

      public abstract bool deleteuser(string username, bool deleteallrelateddata);

      internal string encodepassword(string pass, int passwordformat, string salt);

      protected virtual byte[] encryptpassword(byte[] password);

      public abstract membershipusercollection findusersbyemail(string emailtomatch, int pageindex, int pagesize, out int totalrecords);

      public abstract membershipusercollection findusersbyname(string usernametomatch, int pageindex, int pagesize, out int totalrecords);

      internal string generatesalt();

      public abstract membershipusercollection getallusers(int pageindex, int pagesize, out int totalrecords);

      public abstract int getnumberofusersonline();

      public abstract string getpassword(string username, string answer);

      public abstract membershipuser getuser(object provideruserkey, bool userisonline);

      public abstract membershipuser getuser(string username, bool userisonline);

      internal membershipuser getuser(string username, bool userisonline, bool throwonerror);

      public abstract string getusernamebyemail(string email);

      protected virtual void onvalidatingpassword(validatepasswordeventargs e);

      public abstract string resetpassword(string username, string answer);

      internal string unencodepassword(string pass, int passwordformat);

      public abstract bool unlockuser(string username);

      public abstract void updateuser(membershipuser user);

      public abstract bool validateuser(string username, string password);

 

      // properties

      public abstract string applicationname ...{ get; set; }

      public abstract bool enablepasswordreset ...{ get; }

      public abstract bool enablepasswordretrieval ...{ get; }

      public abstract int maxinvalidpasswordattempts ...{ get; }

      public abstract int minrequirednonalphanumericcharacters ...{ get; }

      public abstract int minrequiredpasswordlength ...{ get; }

      public abstract int passwordattemptwindow ...{ get; }

      public abstract membershippasswordformat passwordformat ...{ get; }

      public abstract string passwordstrengthregularexpression ...{ get; }

      public abstract bool requiresquestionandanswer ...{ get; }

      public abstract bool requiresuniqueemail ...{ get; }

 

      // fields

      private membershipvalidatepasswordeventhandler _eventhandler;

      private const int salt_size_in_bytes = 0x10;

}

 


其中修飾符為internal是幾個方法是密碼的輔助方法,用于加密,解密和驗證密碼。但這邊的設計似乎有一些問題,將這些方法定義為internal范圍好像有點不妥,將這些方法定義在基類中,就是為了能夠被復用,但是從效果上來看,不是這樣的,因為internal的成員只允許在本程序集內被使用(正常情況下,不包括反射等其它方法),這就是說我們自己擴展的membershipprovider是無法使用到這些方法的。而且從目前應用范圍來看,目前這些方法也只有在sqlmembershipprovider中被使用到,所以我認為應該將這些方法修飾符修改為protected。

二、membership 靜態類

上面提到過,一般情況下我們都不會直接去使用到membershipprovider抽象,因為這涉及到如何去實例化真正的membership服務類的問題,涉及到配置和實例化對象的問題一般都是比較棘手的問題,對初學者來說,想要掌握也不是那么容易。那在.net框架中就是通過membership(static class)這個靜態類來屏蔽掉這一層的復雜關系。membership(static class)除了使用者屏蔽讀配置文件,初始對象等一些基本工作外,還有一個重要的作用就是重載所有的membershipprovider所以有api,甚至為了讓用戶更加方便的使用,將這些方法重載為靜態方法,并且提供了membershipprovider基本api基礎上更加豐富的重載實現供使用者調用。這就直接支持了不管是在ui層,還是其它的各個工程,只需要引用system.web.security命名空間,就可以不用關心任何細節的享受到membership給我們提供的各種便利。下面來看看membership(static class)的原型定義:(利用lutz roder’s .net reflector可以查看它的所有實現。)

public static class membership

...{

      // events

      public static  event membershipvalidatepasswordeventhandler validatingpassword;

 

      // methods

      static membership();

      public static membershipuser createuser(string username, string password);

      public static membershipuser createuser(string username, string password, string email);

      public static membershipuser createuser(string username, string password, string email, string passwordquestion, string passwordanswer, bool isapproved, out membershipcreatestatus status);

      public static membershipuser createuser(string username, string password, string email, string passwordquestion, string passwordanswer, bool isapproved, object provideruserkey, out membershipcreatestatus status);

      public static bool deleteuser(string username);

      public static bool deleteuser(string username, bool deleteallrelateddata);

      public static membershipusercollection findusersbyemail(string emailtomatch);

      public static membershipusercollection findusersbyemail(string emailtomatch, int pageindex, int pagesize, out int totalrecords);

      public static membershipusercollection findusersbyname(string usernametomatch);

      public static membershipusercollection findusersbyname(string usernametomatch, int pageindex, int pagesize, out int totalrecords);

      public static string generatepassword(int length, int numberofnonalphanumericcharacters);

      public static membershipusercollection getallusers();

      public static membershipusercollection getallusers(int pageindex, int pagesize, out int totalrecords);

      private static string getcurrentusername();

      public static int getnumberofusersonline();

      public static membershipuser getuser();

      public static membershipuser getuser(bool userisonline);

      public static membershipuser getuser(object provideruserkey);

      public static membershipuser getuser(string username);

      public static membershipuser getuser(object provideruserkey, bool userisonline);

      public static membershipuser getuser(string username, bool userisonline);

      public static string getusernamebyemail(string emailtomatch);

      private static void initialize();

      public static void updateuser(membershipuser user);

      public static bool validateuser(string username, string password);

 

      // properties

      public static string applicationname ...{ get; set; }

      public static bool enablepasswordreset ...{ get; }

      public static bool enablepasswordretrieval ...{ get; }

      public static string hashalgorithmtype ...{ get; }

      internal static bool ishashalgorithmfrommembershipconfig ...{ get; }

      public static int maxinvalidpasswordattempts ...{ get; }

      public static int minrequirednonalphanumericcharacters ...{ get; }

      public static int minrequiredpasswordlength ...{ get; }

      public static int passwordattemptwindow ...{ get; }

      public static string passwordstrengthregularexpression ...{ get; }

      public static membershipprovider provider ...{ get; }

      public static membershipprovidercollection providers ...{ get; }

      public static bool requiresquestionandanswer ...{ get; }

      public static int userisonlinetimewindow ...{ get; }

 

      // fields

      private static char[] punctuations;

      private static bool s_hashalgorithmfromconfig;

      private static string s_hashalgorithmtype;

      private static bool s_initialized;

      private static exception s_initializeexception;

      private static object s_lock;

      private static membershipprovider s_provider;

      private static membershipprovidercollection s_providers;

      private static int s_userisonlinetimewindow;

}

 

說到這里,就不得不多羅嗦兩句。在看membership(static class)實現代碼的過程中,可以發現,每一個membersip api重載都最后都是調用屬性provider的方法,這個屬性的類型就是membershipprovider類型,只有看到這里,你也許才會理解membershipprovider的重要作用了吧。還有一個providers屬性,這個屬性就是獲得web.config中配置的所有的membership提供服務類。它們都是靜態屬性,但是它們怎么去實例化的呢?就是通過調用membership. initialize()這個方法,在每次調用這兩個屬性的時候,都會調用這個方法去判斷是否已初始化了membership提供服務類了,如果沒有則去調用配置服務類,讀取配置內容,從而進行初始化。到此你可能也就不難理解了,為什么我們使用那么簡單了!

三、sqlmembershipprovider介紹和使用配置

ok,通過上面的介紹應該基本可以了解membership的整體結構了吧?(如何還沒有,可能是你沒有打開lutz roder’s .net reflector去分析它的實現代碼,或者是對抽象類的作用還沒弄明白)。不管怎么樣,我們最終的目的就是要學會如何去使用。

在這之前,我先要介紹一下,在.net 框架中提供的兩個membershipprovider實現類:activedirectorymembershipprovider和sqlmembershipprovider(如何知道這兩個類的?在membershipprovider的derived types就可以看到所有的繼承類了。)前者是提供基本活動目錄下的用戶管理(我也沒有實踐過),后者就是我們最經常使用到的基于sqlserver的用戶管理實現。

到了介紹如何使用了,其實園子里已經有了這方面的文章((翻譯)怎么在asp.net 2.0中使用membership),我也不多費口舌了。但這邊要告訴大家一個最直接的學習和參考使用的辦法。在系統盤找到并打開machine.config,找到aspnetsqlmembershipprovider節點,看到沒有,其實這個就是一個最基本的membership配置了,只不過是還少了一個defaultprovider屬性的指定,指定了這個屬性后,你再使用login控件,進行用戶登錄驗證就無需使用任何代碼了。不信你可以試試。(關于forms驗證,就不在這里多做介紹,可以參考相關資料。關于sqlmembershipprovider的更多屬性的介紹可以參看msdn)。

四、如何自定義membershipprovider,現有其它的membershipprovider資源

那么,我們如何去自定義一個membershipprovider呢?其實如果你已經了解了membership的結構后我相信對你來說已經不是一件很難的事了,但是考慮到要完整的寫一個membershipprovider還是有一定的工作量和難度的。對于我們來說,更多的地方可能是對現有的provider進行擴展,如sqlmembershipprovider。那其實這是非常簡單的,我們只需要繼承自sqlmembershipprovider,(悄悄告訴你,在initialize方法config參數中保存的就是provider對應配置節的屬性名和值)然后擴展和重寫所需的方法就可以了。使用的時候,在provider配置節中,將type的值改為你的類名就ok了。

最后,在市面上已經有好多不同環境的membershipprovider了,如mysql,oracle等。這里給出mysql 的實現:http://www.codeproject.com/aspnet/mysqlmembershipprovider.asp ,更多不同的實現,相信你從google上找到更多的幫助。

好了,說多了,說了這么多希望能對不辭辛苦看完本篇blog的您有所幫助,謝謝 ^_*

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 陇川县| 大英县| 朔州市| 绥棱县| 海淀区| 海兴县| 青铜峡市| 东乡| 印江| 十堰市| 扶余县| 扎囊县| 道孚县| 和政县| 定襄县| 明水县| 沙雅县| 开远市| 渭源县| 略阳县| 茶陵县| 五寨县| 桐梓县| 轮台县| 蒙阴县| 乌拉特中旗| 乐至县| 灌云县| 静宁县| 武汉市| 临高县| 元氏县| 江永县| 德钦县| 留坝县| 阜康市| 沈丘县| 农安县| 新营市| 万盛区| 乐安县|