asp.net form 驗證方式的使用(轉載)

来源:http://www.cnblogs.com/qinge/archive/2016/06/27/5620171.html
-Advertisement-
Play Games

如何運用 Form 表單認證 ASP.NET 的安全認證,共有“Windows”“Form”“Passport”“None”四種驗證模式。“Windows”與“None”沒有起到保護的作用,不推薦使用;“Passport”我又沒用過,唉……所以我只好講講“Form”認證了。我打算分三部分: 第一部分 ...


 

  如何運用 Form 表單認證

  ASP.NET 的安全認證,共有“Windows”“Form”“Passport”“None”四種驗證模式。“Windows”與“None”沒有起到保護的作用,不推薦使用;“Passport”我又沒用過,唉……所以我只好講講“Form”認證了。我打算分三部分:

  第一部分 —— 怎樣實現From 認證;

  第二部分 —— Form 認證的實戰運用;

  第三部分 —— 實現單點登錄(Single Sign On

  第一部分 如何運用 Form 表單認證

  一、     新建一個測試項目

  為了更好說明,有必要新建一個測試項目(暫且為“FormTest”吧),包含三張頁面足矣(Default.aspxLogin.aspxUserInfo.aspx)。啥?有人不會新建項目,不會新增頁面?你問我咋辦?我看這麼辦好了:拖出去,打回原藉,從幼兒園學起……

  二、     修改 Web.config

  1、 雙擊項目中的Web.config(不會的、找不到的打 PP

  2、 找到下列文字 <authentication mode="Windows" /> 把它改成:

  <authentication mode="Forms">

  <forms loginUrl="Login.aspx" name=".ASPXAUTH"></forms>

  </authentication>

  3、 找到<authorization> <allow users="*" /></authorization>換成

  <authorization><deny users="?"></deny></authorization>

  這裡沒什麼好說的,只要拷貝過去就行。雖說如此,但還是有人會弄錯,如下:

  <authentication mode="Forms">

  <forms loginUrl="Login.aspx" name=".APSX"></forms>

  <deny users="?"></deny>

  </authentication>

  若要問是誰把 <deny users="?"></deny> 放入 <authentication> 中的,我會很榮幸地告訴你,那是 N 年前的我:<authentication> <authorization> 都是以 auth 字母開頭又都是以 ation 結尾,何其相似;英文單詞背不下來的我以為他們是一伙的……

  三、     編寫 .cs 代碼——登錄與退出

  1、 登錄代碼:

  a、 書本上介紹的

  private void Btn_Login_Click(object sender, System.EventArgs e)

  {

  if(this.Txt_UserName.Text=="Admin" && this.Txt_Password.Text=="123456")

  {

  System.Web.Security.FormsAuthentication.RedirectFromLoginPage(this.Txt_UserName.Text,false);

  }

  }

  b、 偶找了 N 久才找到的

  private void Btn_Login_Click(object sender, System.EventArgs e)

  {

  if(this.Txt_UserName.Text=="Admin" && this.Txt_Password.Text=="123456")

  {

  System.Web.Security.FormsAuthentication.SetAuthCookie(this.Txt_UserName.Text,false);

  Response.Redirect("Default.aspx");

  }

  }

  以上兩種都可發放驗證後的 Cookie ,即通過驗證,區別:

  方法 a) 指驗證後返回請求頁面,俗稱“從哪來就打哪去”。比如:用戶沒登錄前直接在 IE 地址欄輸入 http://localhost/FormTest/UserInfo.aspx ,那麼該用戶將看到的是 Login.aspx?ReturnUrl=UserInfo.aspx ,輸入用戶名與密碼登錄成功後,系統將根據“ReturnUrl”的值,返回相應的頁面

  方法 b) 則是分兩步走:通過驗證後就直接發放 Cookie ,跳轉頁面將由程式員自行指定,此方法多用於 Default.aspx 使用框架結構的系統。

  2、 退出代碼:

  private void Btn_LogOut_Click(object sender, System.EventArgs e)

  {

  System.Web.Security.FormsAuthentication.SignOut();

  }

  四、     如何判斷驗證與否及獲取驗證後的用戶信息

  有的時候,在同一張頁面需要判斷用戶是否已經登錄,然後再呈現不同的佈局。有人喜歡用 Session 來判斷,我不反對此類做法,在此我只是想告訴大家還有一種方法,且看下麵代碼:

  if(User.Identity.IsAuthenticated)

  {

  //你已通過驗證,知道該怎麼做了吧?

  }

  User.Identity 還有兩個屬性AuthenticationType(驗證類型)與 Name(用戶名稱) ,大家要註意的是 Name 屬性,此處的User.Identity.Name將得到,驗證通過(RedirectFromLoginPage SetAuthCookie)時,我們帶入的第一個參數 this.Txt_UserName.Text 。這個參數很重要,關係到種種……種種的情況,何出此言,且聽下回分解……

  靈活運用 Form 表單認證中的 deny allow 及保護 .htm 等文件

  第二部分 Form 認證的實戰運用

  Web.config 的作用範圍

  新建項目時, VS.Net 會在項目根目錄建立一個內容固定的 Web.config。除了在項目根目錄,你還可以在任一目錄下建立 Web.config ,條件就是應用程式級別的節點只能在根目錄的 Web.config 中出現。至於哪些是應用程式級別節點呢,這個問題嘛,其實我也不太清楚,呵呵。電腦不是我發明的,微軟不是我創建的,C# 更不是我說了算的,神仙也有不知道的,所以我不曉得是正常的。話雖如此,只要它不報錯,那就是對的。

  關於 Web.config 設置的作用範圍,記住以下兩點:

  1Web.config 的設置將作用於所在目錄的所有文件及其子目錄下的所有東東(繼承:子隨父姓)

  2、 子目錄下的 Web.config 設置將覆蓋由父目錄繼承下來的設置(覆蓋:縣官不如現管)

  給大家提個問題:有沒有比根目錄Web.config 的作用範圍還大的配置文件呢?看完第三部分便知分曉。

  六、     學會拒絕與巧用允許

  回到我們在第一回合新建的測試項目“FormTest” ,既然要進行驗證,按國際慣例,就得有用戶名與密碼。那,這些用戶是管理員自己在資料庫建好呢,還是用戶註冊、管理員審核好呢。只要不是一般的笨蛋,都知道選擇後者。你們還別說,我公司還真有個別項目是管理員連到資料庫去建帳號的,屬於比較特殊的笨蛋,咱們不學他也罷,還是老老實實添加兩個頁面吧——註冊頁面(Register.aspx)與審核頁面(Auditing.aspx)。

  問題終於就要浮出水面啦,當你做好 Register.aspx 時,想訪問它的時候突然覺得不對勁,怎麼又回到了登錄頁面?你仔細瞧瞧網址,是不是成了:Login.aspx?ReturnUrl=Register.aspx 。怎麼辦,用戶就是因為沒有帳號才去訪問註冊頁面的呀?(這句純屬廢話,有帳號誰還跑去註冊。)我時常對我的同事說:“辦法是人想出來滴!!”

  1、 新建一個目錄 Public ,用於存放一些公用的文件,如萬年曆、腳本呀……

  2、 在“解決方案資源管理器”中右擊點擊目錄 Public ,新增一個 Web.config

  3、 把上述 Web.config 的內容統統刪除,僅留以下即可:

  <?xml version="1.0" encoding="utf-8"?>

  <configuration>

  <system.web>

  <authorization><allow users="*"/></authorization>

  </system.web>

  </configuration>

  終於切入正題了,不容易呀。根據“覆蓋”原則,我們知道上述 Web.config 將替代根目錄 Web.config 中的 <authorization> 節點設置,即:

  <allow users="*"/> 替換 <deny users="?"></deny>

  註解:“allow”允許的意思;“*”表示所有用戶;

  “deny” 拒絕的意思;“?”表示匿名用戶;

  因此,處於 Public 目錄下的文件,允許所有人瀏覽,包括未驗證的用戶。把 Register.aspx 拖進來吧,再也不會有人阻止你瀏覽啦。

  除了註冊頁面,我們還提到一個審核頁面(Auditing.aspx),審核許可權一般都在管理員或主管手裡,008km.org 並不想讓其他人瀏覽此頁面(真理往往掌握在少數人的手裡,這也是沒法子的事),怎麼辦?“辦法是人想出來滴”呵呵……新建一個管理員的目錄 ManageSys ,在此目錄下再新增一個 Web.config。內容如下:

  <?xml version="1.0" encoding="utf-8"?>

  <configuration>

  <system.web>

  <authorization>

  <allow users="Admin"/>

  <deny users="*"/>

  </authorization>

  </system.web>

  </configuration>

  System.Web.Security.FormsAuthentication.SetAuthCookie(this.Txt_UserName.Text,false); //通過驗證,發放 Cookie

  之前我曾強調,要註意,第一個參數很重要,重要到什麼程度?說到這,恐怕地球人都知道了——它就是allowdeny的依據。假如此處用戶填寫的是“Admin”即 this.Txt_UserName.Text = "Admin"; 那麼進入系統後,他就能訪問 ManageSys 目錄下的網頁了,其它閑雜人等一律拒之門外。

  以上 from

  1: web.config中,加入form認證;

  <authentication mode="Forms">

  <forms name="auth" loginUrl="index.aspx" timeout="30"></forms>

  </authentication>

  <authorization>

  <deny users="?" />

  </authorization>

  2: 如果有註冊頁面時還應該允許匿名用戶調用註冊頁面進行註冊;

  以下代碼應該在<configuration><system.web>之間,而不應該包含到<system.web>..</system.web>之間;

  ----------------表示允許 匿名用戶對 userReg.aspx頁面進行訪問.

  <location path="userReg.aspx">

  <system.web>

  <authorization>

  <allow users="?" />

  </authorization>

  </system.web>

  </location>

  3 在登錄成功後要 創建身份驗證票, 表明已經通過認證的合法用戶;

  if(登陸成功)

  System.Web.Security.FormsAuthentication.SetAuthCookie(用戶名稱, false);

  1.使用Forms驗證存儲用戶自定義信息

  Forms驗證在內部的機製為把用戶數據加密後保存在一個基於cookie的票據FormsAuthenticationTicket中,因為是經過特殊加密的,所以應該來說是比較安全的。而.net除了用這個票據存放自己的信息外,還留了一個地給用戶自由支配,這就是現在要說的UserData

  UserData可以用來存儲string類型的信息,並且也享受Forms驗證提供的加密保護,當我們需要這些信息時,也可以通過簡單的get方法得到,兼顧了安全性和易用性,用來保存一些必須的敏感信息還是很有用的。

  下麵來看怎麼使用UserData,然後會給出一個實際使用的例子。

  //創建一個新的票據,將客戶ip記入ticketuserdata

  FormsAuthenticationTicket ticket=new FormsAuthenticationTicket(

  1,userName.Text,DateTime.Now,DateTime.Now.AddMinutes(30),

  false,Request.UserHostAddress);

  //將票據加密

  string authTicket=FormsAuthentication.Encrypt(ticket);

  //將加密後的票據保存為cookie

  HttpCookie coo=new HttpCookie(FormsAuthentication.FormsCookieName,authTicket);

  //使用加入了userdata的新cookie

  Response.Cookies.Add(coo);

  下麵是FormsAuthenticationTicket構造函數的重載之一的方法簽名

  public FormsAuthenticationTicket(

  int version,

  string name,

  DateTime issueDate,

  DateTime expiration,

  bool isPersistent,

  string userData

  );

  參數

  version

  版本號。

  name

  與身份驗證票關聯的用戶名。

  issueDate

  Cookie 的發出時間。

  expiration

  Cookie 的到期日期。

  isPersistent

  如果 Cookie 是持久的,為 true;否則為 false

  userData

  將存儲在 Cookie 中的用戶定義數據

  使用userdata也很簡單,FormsIdentityTicket屬性就提供了對當前票據的訪問,獲得票據後就可以用UserData屬性訪問保存的信息,當然是經過解密的。

  ((System.Web.Security.FormsIdentity)this.Context.User.Identity).Ticket.UserData

  下麵是一個具體的應用。

  由於Forms驗證是通過cookie來進行的,它需要傳遞一個票據來進行工作。雖然票據是加密的,裡面的內容不可見,但這並不能阻止別人用一個假冒的身份使用票據(就像我們可以拿別人的鑰匙去開別人的鎖),比較常見的就是不同ip的用戶在不安全通道截獲了這個票據,然後使用它進行一些安全範圍外的活動。

  解決這個問題的辦法之一就是使用SSL來傳遞信息。

  但是如果不能使用SSL呢?澳門新濠天地官網66bb.org 我們可以判斷ip和票據是否匹配,如果發出請求的ip是初次產生票據的ip,則沒有問題,否則就銷毀這個票據。

  為此,我們需要在一開始處理登錄時將用戶的ip保存起來,這樣就可以在以後的請求中隨時驗證後繼請求的ip是否和初始ip相同。保存這個敏感ip的最佳場所當然是UserData啦,而驗證的時機則是在AuthenticateRequest事件發生時,即Global.aspx.cs中定義的處理此事件的Application_AuthenticateRequest方法中。

  上面的示例實際上已經是把用戶ip保存到了UserData中,下麵是驗證的過程。

  if(this.Request.IsAuthenticated)

  {

  if(((System.Web.Security.FormsIdentity)this.Context.User.Identity).Ticket.UserData !=this.Request.UserHostAddress)

  {

  System.Security.Principal.GenericIdentity gi=new System.Security.Principal.GenericIdentity("","");

  string[] rolesi={};

  System.Security.Principal.GenericPrincipal gpi=new System.Security.Principal.GenericPrincipal(gi,rolesi);

  this.Context.User=gpi;

  }

  }

  通過給GenericPrincipal空的GenericIdentityroles使票據失效,這樣將強迫用戶重新登錄。為了測試這個方法,可以先把條件改為相等,看效果如何 :)

  這個方法也有不足之處,具體為:

  1.使用同一代理的用戶將擁有同一個ip,這樣就不能防範此類假冒攻擊了

  2.如果用戶使用動態ip,則可能造成正常用戶被我們強行銷毀票據。不過總的來說,這個辦法還是比較可行的。

  2.使用安全特性配合Forms驗證進行安全操作。

  PrincipalPermissionAttribute可以配合Forms驗證進行基於角色或用戶的安全驗證,該特性不能用於程式集級別。它的作用範圍可以是類或具體的方法。來看一個簡單的示例。

  [PrincipalPermission(SecurityAction.Demand,User="Notus")]

  public class Test : BasePage

  {

  private void Page_Load(object sender, System.EventArgs e)

  {

  try

  {

  this.sayHello();

  this.sayHello2();

  }

  catch(Exception ex)

  {

  Response.Write(ex.ToString());

  }

  }

  private void sayHello()

  {

  Response.Write("hello world!");

  }

  private void sayHello2()

  {

  Response.Write("hello PrincipalPermissionAttribute!");

  }

  #region Web 窗體設計器生成的代碼

  override protected void OnInit(EventArgs e)

  {

  //

  // CODEGEN: 該調用是 ASP.NET Web 窗體設計器所必需的。

  //

  InitializeComponent();

  base.OnInit(e);

  }

  /// <summary>

  /// 設計器支持所需的方法 - 不要使用代碼編輯器修改

  /// 此方法的內容。

  /// </summary>

  private void InitializeComponent()

  {

  this.Load += new System.EventHandler(this.Page_Load);

  }

  #endregion

  }

  註意這個例子一開始是作用於整個類的,生成後執行,如果當前用戶不是Notus,就會發生異常System.Security.SecurityException,提示對主體許可權的請求失敗。反之,則可以順利訪問,並輸出兩個hello world!,註意是兩個。現在的安全作用範圍是整個類。

  接下來我們改一下特性的作用範圍。b31.org 將特性聲明移到sayHello2方法上面,重新編譯後運行,就會發現程式在運行到sayHello2方法後拋出了System.Security.SecurityException。這說明現在安全作用範圍縮小到了方法級別。

  該特性可以通過設置UserRole來進行基於用戶和角色的安全保護。另外其使用的第一個參數是SecurityAction枚舉,該枚舉設置了具體的保護級別或措施。像我們現在使用的這個Demand,是要求調用堆棧中的所有高級調用方都已被授予了當前許可權對象所指定的許可權。

  下麵是msdn給的示例

  示例

  下麵的示例說明可以如何以聲明方式使用 PrincipalPermission 要求當前用戶是 Bob 並且屬於 Supervisor 角色。

  [PrincipalPermissionAttribute(SecurityAction.Demand, Name="Bob",

  Role="Supervisor")]下麵的示例說明如何要求當前用戶的身份是 Bob,與角色成員條件無關。

  [PrincipalPermissionAttribute(SecurityAction.Demand, Name="Bob")]

  下麵的示例說明如何僅要求對用戶進行身份驗證。

  [PrincipalPermissionAttribute(SecurityAction.Demand, Authenticated=true)]

  再要說一下的是,這裡面的UserRole是可以和Forms驗證集成的,據此,我們可以在一些重要的類或方法中使用PrincipalPermissionAttribute,以將自己的程式武裝到家。

  而實際上,該特性的作用遠不止這些,更詳細的信息可以查閱msdn

  或者:

  1.配置Web.Config文件

  設置為Form認證:

  <authentication mode="Forms">

  <forms name="oursnet" loginUrl="login.aspx" timeout="10" />

  </authentication>

  其中:

  name:        決定驗證用戶時所使用的Cookie名稱

  loginurl:     在用戶沒有登錄是,被重定向的頁面

  timeout:     超時時間,單位為分鐘

  不允許匿名登錄

  <authorization>

  <!-- 允許所有用戶 -->

  <deny users="?" />

  <!-- <allow     users="[逗號分隔的用戶列表]"

  roles="[逗號分隔的角色列表]"/>

  <deny      users="[逗號分隔的用戶列表]"

  roles="[逗號分隔的角色列表]"/>

  -->

  </authorization>

  其中:

  users:    表示禁止訪問資源的用戶列表,使用通配符“?“拒絕匿名用戶訪問,使用"*",則表示拒絕所有的用戶訪問.

  2.添加登錄成功的代碼:

  Session.Contents["UserName"]=txtUser.Text;

  FormsAuthentication.RedirectFromLoginPage(txtUser.Text,false);

  Response.Redirect("index.aspx");

  3.添加退出時的代碼

  System.Web.Security.FormsAuthentication.SignOut();

  Response.Redirect("login.aspx");


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • Nop中定義了ICacheManger介面,它有幾個實現,其中MemoryCacheManager是記憶體緩存的一個實現。 MemoryCacheManager: 緩存的添加,在需要的地方構建cache key然後調用ICacheManger介面存儲起來: 這個ICacheManger的Get方法其實 ...
  • 前言 如果你還不知道ZKEACMS,不妨先瞭解一下。 ASP.NET MVC 開源建站系統 ZKEACMS 推薦,從此網站“拼”起來 官方地址:http://www.zkea.net/zkeacms 下載地址:https://github.com/SeriaWei/ASP.NET-MVC-CMS/r ...
  • 命令模式:將一個請求封裝為一個對象,從而是你可用不同的請求對客戶進行參數化;對請求排隊或記錄請求日誌,以及支持可撤銷的操作。 命令模式有如下優點:1.它能較容易地設計一個命令隊列;2.在需要的情況下,可以較容易地將命令記入日誌;3.允許接收請求的一方決定是否要否決請求;4.可以容易地實現請求的撤銷和 ...
  • MXS&Vincene ─╄OvЁ &0000025─╄OvЁ MXS&Vincene MXS&Vincene ─╄OvЁ:今天很殘酷,明天更殘酷,後天很美好,但是絕大部分人是死在明天晚上,只有那些真正的英雄才能見到後天的太陽。 MXS&Vincene ─╄OvЁ:We're here to put ...
  • .net 分散式集群監控平臺,用於集群的性能監控,應用耗時監控管理,統一日誌管理等多維度的性能監控分析。 ...
  • .net 動態腳本引擎, 用於解決.net環境windows系統下類似java中Grovvy的功能和方向。 在互聯網項目可以用來做一些功能,如動態營銷活動(營銷業務解耦和剝離),規則引擎,流程引擎,windows運維腳本,源碼式插件開發。 ...
  • 之前兩篇文章簡析.NET Core 以及與 .NET Framework的關係和.NET Core的構成體系從總體上介紹.NET Core,接下來計劃用一個系列對ASP.NET Core的運行原理進行剖析 ...
  • 在C#編程中,我們經常需要處理這些情況。 1. 某種條件為真時,程式這樣處理;當某種條件為假時,程式那樣處理。 2. 當某種條件為真時,程式一直這樣處理; 這裡的條件,在C#中就是邏輯運算。接下來我就和大家聊聊C#中關於邏輯運算的一些基本概念。 比較運算符 比較運算符,顧名思議就是用來作比較,比較運 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...