用好VS2005之擴充membership服務

來源:互聯網
上載者:User
  ASP.NET 2.0中新增的最佳功能之一是新的成員資格服務,它提供了用於建立和系統管理使用者帳戶的便於使用的API。ASP.NET 1.x大規模引入了表單身分識別驗證,但仍然要求您編寫相當數量的代碼來執行實際操作中的表單身分識別驗證。成員資格服務填補了ASP.NET 1.x表單驗證服務的不足,並且使實現表單身分識別驗證變得比以前簡單得多。

  成員資格API通過兩個新的類公開:Membership和MembershipUser。前者包含了用於建立使用者、驗證使用者以及完成其他工作的靜態方法。MembershipUser代表單個使用者,它包含了用於檢索和更改密碼、擷取上次登入日期以及完成類似工作的方法和屬性。通過這兩個新的類,我們可以不用寫一行代碼,方便得完成對使用者的管理。 但是在實際開發過程中,絕對不能滿足我們日常開發的需要。經過日常項目的開發和網路上資料的搜尋,現將其一一列出:

  一、預設的各類的資料庫是使用sql express的,而我們在實際開發中往往使用sql sever 2000或者sql server 2005,這時就需要我們修改資料庫的類型。

  微軟給我們提供了一個Aspnet_regsql的命令來修改預設資料庫。開啟 Visual Studio 2005 命令提示,輸入aspnet_regsql,按照提示一步一步進行即可。

  此時開啟資料庫,可以發現多處來了一系列"aspnet_"開頭的預存程序,這就是我們使用membership所必需的預存程序。

  此時開啟IIS,[屬性] →[ASP.NET] →[編輯配置]:

  [常規],串連參數LocalSqlServer按照普通的sql連接字串格式。

  [身分識別驗證],模式為Forms,管理提供者的minRequiredNonalphanumericCharacters為0,這時就可以去掉預設變態的必需需要輸入字母,數字等組合的密碼安全了。此步也可修改密碼最低長度和最大長度等等。

  經過此步驟,系統會自動在web.config中配置好了我們所需的規則。很方便,修改web.config以後都可以通過這種圖形化工具來了。

  二、由於內建的login控制項和membership類,只提供了簡單的使用者資訊錄入,不能滿足我們項目的需要。例如:我們要使用者註冊的時候同時輸入QQ號碼,電話號碼,家庭地址。那麼預設的是沒有辦法解決的。我這裡給出兩種解決方案。我分別用在了不同的項目中。優缺點大家自行判斷。

  1、使用profile。此類方法網上教程已經很多。不在出重複敘述,免去賺稿費的嫌疑:)。這裡只是給出網上沒有的部分說明。
由於membership只能列出來指定組的使用者名稱,而不能列出其他的詳細資料,我們實際使用中,往往需要對組中的其它資訊進行同時修改。我採用的是自行構造datatable的方法。見代碼:

public static DataTable listuser(string userRoles)//列出指定組的使用者資訊
{
 string[] users = Roles.GetUsersInRole(userRoles);
 //列出指定組下的使用者
 DataTable dt = new DataTable();
 dt.Columns.Add("username", System.Type.GetType("System.String"));
 dt.Columns.Add("QQ", System.Type.GetType("System.String"));
 dt.Columns.Add("phone", System.Type.GetType("System.String"));
 dt.Columns.Add("address", System.Type.GetType("System.String"));
 dt.Columns.Add("email", System.Type.GetType("System.String"));
 //以上構造一個資料表
 foreach (string i in users)
 {
  DataRow dr = dt.NewRow();
  MembershipUser mu = Membership.GetUser(i);
  得到使用者基本資料
  ProfileCommon p = Profile.GetProfile(i); //得到使用者的profile資訊
  dr[0] = mu. username;
  dr[1] = p. QQ;
  //profile是強型別,可以很方便的通過感知來添加。
  dr[2] = p. phone;
  dr[3] = p. address;
  dr[4] = mu. email;
  dt.Rows.Add(dr);
  dt.AcceptChanges();
 }
 return dt;
}
public static void deleteuser(string username)/刪除指定使用者
{
 Membership.DeleteUser(username);
 //系統會自動刪除profile下的指定使用者的資訊
}
public static void updateuser(string username)/更新指定使用者
{
 ProfileCommon p = Profile.GetProfile(i);
 //得到使用者的profile資訊
 p. phone="電話";
 p. address="地址;
 p. QQ="QQ號碼";
 p.Save();
 //儲存所作修改。
}
  2、自訂一個membershipinfo表格,同membership系統標關聯起來。自己編寫SQL語句來進行查詢,修改等功能。

列出指定組的使用者
select * from aspnet_membership inner join aspnet_users on
aspnet_membership.userid=aspnet_users.userid left join memberinfo on aspnet_membership.userid=memberinfo.userid
where aspnet_membership.userid=(select userid from aspnet_usersinroles inner join
aspnet_roles on aspnet_usersinroles.roleid=aspnet_roles.roleid where rolename='admin')

  
  刪除、修改等功能比較簡單,這裡就不作敘述。可以採用membership的createuser方法建立,然後再用sql語句寫入memberinfo表。

  對於建立使用者,我們可以採取擴充CreateUserWizard控制項,或者自行寫登陸介面。

  1、採取擴充CreateUserWizard控制項,我們可以使用它的模版列,此時需要注意的是:使用者名稱,密碼,提示問題,提示問題答案,Email,他們的ID一定要分別是username,Password,Question,Answer,Email否則會出錯,而且此時驗證控制項均不能使用。懷疑是IDE的一個Bug。

  如下所示,我們定義好的樣式應當是:

<WizardSteps>
<asp:CreateUserWizardStep runat="server"> 自訂代碼部分<ContentTemplate>
</ContentTemplate>
</asp:CreateUserWizardStep>
</WizardSteps>
代碼部分:
protected void CreateUserWizard1_CreatedUser(object sender, EventArgs e)
{
 //由於系統會自動給們建立基本的資訊表,所以我們只需要對profile或者membershipinfo標進行修改即可。   
 Roles.AddUserToRole(CreateUserWizard1.UserName, "shop"); 
 //添加使用者到相應的組
 ProfileCommon p = (ProfileCommon)ProfileCommon.Create(CreateUserWizard1.UserName, true);
 p. QQ = ((TextBox)CreateUserWizard1.CreateUserStep.ContentTemplateContainer.FindControl("QQ")).Text.Trim();
 p.address= ((TextBox)CreateUserWizard1.CreateUserStep.ContentTemplateContainer.FindControl("address")).Text.Trim();   
 p.phone = ((TextBox)CreateUserWizard1.CreateUserStep.ContentTemplateContainer.FindControl("phone")).Text.Trim(); p.Save();//儲存所作修改
}
  2、採取自己寫UI,個人推薦使用這種方法。靈活性比較大,而且可以使用2005強大的驗證控制項。

  頁面部分比較簡單略過不再陳述。下面詳細介紹一下代碼部分。

  此時我們需要使用membership的CreateUser()方法。文法我們就不再介紹。他會根據建立使用者的結果返回成一個MembershipCreateStatus枚舉類,它詳細的包含了所有建立使用者不成功的錯誤資訊。我們只需要根據他的值,就可以返回給介面相應的提示,如:使用者名稱已經存在,電子郵件已經存在等等。

  對於自訂使用者資訊部分我們仍然可以採取profile或者自訂membershipinfo表的方法。

  列出profile建立使用者的方法。SQL語句比較簡單,略過不寫。

protected void Button1_Click(object sender, EventArgs e)
{
 MembershipCreateStatus status;
 MembershipUser newUser = Membership.CreateUser(username.Text.Trim(), Password.Text.Trim(),  Email.Text.Trim(), Question.Text.Trim(), Answer.Text.Trim(), true, out status);
 //使用membership建立使用者,並把建立結果返回給MembershipCreateStatus

  if (newUser == null)//沒有新使用者,則意味著出錯。
  {
  GetErrorMessage(status);
  //調用GetErrorMessage函數,返回詳細錯誤資訊
  } else {
   Roles.AddUserToRole(newUser.UserName, "jiancai");
   //添加使用者到相應組 ProfileCommon
   p = (ProfileCommon)ProfileCommon.Create(newUser.UserName, true);
   p.QQ = QQ.Text.Trim();
   p.address= address.Text.Trim();
   p.phone= phone.Text.Trim();
   p.Save();
  }
 }
public void GetErrorMessage(MembershipCreateStatus status)
{
 switch (status)
  {
   case MembershipCreateStatus.DuplicateUserName: DisplayAlert("目前使用者已經存在,請重新選擇");
    break;
    //其餘各種錯誤資訊,請查看MSDN的MembershipCreateStatus枚舉類。
   default: DisplayAlert("註冊00000000使用者失敗,請檢查您的使用者名稱,密碼等資訊");
    break;
  }
}
  個人見解:採取profile的方法,比較方便,由於profile 是強型別,可以通過智能感知功能減少代碼的輸入量。採取自訂資料表的方法,需要輸入大量的sql語句,但是查詢速度比較快,效能比較強,由於Roles.GetUsersInRole()方法無法分頁讀取資料,只能一次性讀出來所有資料,而自寫SQL 陳述式可以很方便的根分頁結合起來。隨著使用者量的增多,故不推薦profile方法。

  三、密碼問題。

  個人覺得密碼是一個比較頭疼的問題。我們在實際開發中總是需要admin組有對使用者進行密碼修改的許可權。Membership提供的修改密碼方法只能在已經知道密碼提示答案的時候才能修改。而admin組根本不可能知道使用者的密碼提示答案的。這裡有點好笑。難道是中西方文化差異?

  列出個人對membership密碼研究的一些心得。

  大家都知道machine.config和web.config,如果兩者發生衝突,那麼以web.config優先。

  預設狀態下,membership是採用SHA1的方法進行加密,然後採取一種機制,與passwordsalt進行再次加密,最後形成資料庫中顯示的密碼。可見隨著MD5加密的破解,微軟對密碼的安全也煞費苦心。

  有的朋友不喜歡預設的SHA1加密形式,我們只需要在web.config中設定以下代碼來覆蓋machine.config中對密碼的設定就好了:

<machineKey
validationKey="AutoGenerate,IsolateApps"
decryptionKey="AutoGenerate,IsolateApps"
decryption="Auto"
validation="MD5/SHA1/Clear" />
  其中:

  Clear - 密碼以明文形式儲存。使用者密碼可與此值直接比較,而不需要進行進一步的轉換。

  MD5 -使用訊息摘要 5 (MD5) 雜湊摘要儲存密碼。為了驗證憑據,將使用 MD5 演算法對使用者密碼進行雜湊運算並將計算出來的值與儲存的值進行比較。使用此值時,從不儲存或比較純文字密碼。此演算法的效能比 SHA1 好。

  SHA1 -使用 SHA1 雜湊摘要儲存密碼。為了驗證憑據,將使用 SHA1 演算法對使用者密碼進行雜湊運算並將計算出來的值與儲存的值進行比較。從不儲存純文字密碼。使用該演算法可以獲得比 MD5 演算法高的安全性。

  然而雖然MembershipUser提供了GetPassword 方法,但是這是後只有在加密形式設定成Clear,即密碼在資料庫中以明碼的形式存在,才能得到密碼。而ChangePassword必須要提供舊密碼或者密碼提示答案才可以修改。對使用者管理造成了很大的不便。找了許多資料無解。順便提帶一下:微軟的membership機制起源於csblog,並進行了一定的修改。

  Csblog對密碼的策略:首先對使用者輸入的密碼進行加密(SHA1或者MD5),然後根據系統自動產生的密匙再次對加密後的密碼進行DES加密。不過我按照csblog 的方法進行加密的時候,形式相同,密碼卻不同,目前正在演就中。也歡迎大家共同討論。

  如果passwordsalt和password固定,那麼使用者密碼肯定一定。所以目前我採取的一個方法就是給使用者重新設定成固定密碼的功能。

  首先取得已知使用者密碼的passwordsalt和password,然後替換相應使用者的passwordsalt和password欄位。這時,使用者的密碼就已經恢複成已知的密碼了。

  不可否認,membership給我們開發中創造了很大的便利,其方便的Roles功能,對於我們進行許可權管理的時候提供了很好的解決方案。2005許多功能均進化自csblog這優秀的開源項目,有興趣者可以研究csblog,以進一步的瞭解membership的運作機制。限於篇幅,MSDN上邊有做介紹的我就不再重複敘述。只介紹MSDN上沒有列出的技巧跟我在項目開發中的一些心得。 ASP.NET 2.0為使用表單身分識別驗證的Web網站提供了重要的安全性優勢。通過提供使用者設定檔儲備庫以及對角色的支援,表單身分識別驗證將走出ASP.NET內行的視野,而得以更廣泛地實現。

相關文章

Cloud Intelligence Leading the Digital Future

Alibaba Cloud ACtivate Online Conference, Nov. 20th & 21st, 2019 (UTC+08)

Register Now >

Starter Package

SSD Cloud server and data transfer for only $2.50 a month

Get Started >

Alibaba Cloud Free Trial

Learn and experience the power of Alibaba Cloud with a free trial worth $300-1200 USD

Learn more >

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。