Hopes

          Start Here..

           

          用戶Session過期

           思路(一)

            放在一個包含文件里,然后在每個文件的頭部包含他。 

          判斷1:

          String flag = (String)session.getAttribute( "Username/StrConnection "); 
          if(flag==null

          // 彈出提示 
          }

          判斷2:

          if   len(session( "username "))=0   then 
             Response.write 
          "session已過期 " 
             Response.write 
          " <a   href=login.asp> 重新登陸 </a>" 
             REsposne.end 
           end   
          if 
           
          //放在一個包含文件里,然后在每個文件的頭部包含他

           判斷3

          //通過BasrPage或IHtttpMoudle實現
          public class BasePage : System.Web.UI.Page
              {
                
          public  BasePage()
                {

           

                }

                
          protected override void OnInit(EventArgs O)
                {
                    
          if (base.Session["UserId"== null || base.Session["UserId"].ToString().Equals(""))
                    {
                        Response.Redirect(
          "~/Error.aspx");
                    }
                }
              }

            

           思路(二)

            Web.config里面1

          <customErrors mode="RemoteOnly" defaultRedirect="Error.aspx">
          </customErrors> 

          Web.config里面2(forms身份驗證 當session過期后 再點他就會自動跳到登陸頁面)

          <authentication mode="Forms">
          <forms name=".ASPXUSERDEMO" loginUrl="Login.aspx" protection="All" timeout="30" defaultUrl="Default.aspx" path="/"/>
          </authentication>


            思路(三) 

          使用cookie+session驗證,cookie保存登陸信息,每一次在驗證session失效后,首先判斷cookie中是否存在字段,如果沒有,退出頁面,如果有,就在后臺登陸。前臺感覺不到!這樣即使服務器總是session失效,也不會動不動就跳回登陸界面!
              session("bsz_login_name")=Request.Cookies("username")
              session("bsz_login_password")=Request.Cookies("password")
          追問:session失效了,只能停在登錄頁面,session都不存值的?
          回答:登陸的時候保存兩個值:一個session,一個cookie,在驗證登陸狀態的頁面做如下驗證:

          if session="" then
          if cookie="" then
          [返回登陸界面]
          else
          session
          =cookie
          end 
          if
          end 
          if






          如何運用 Form 表單認證

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

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

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

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

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

          一、 新建一個測試項目

          為了更好說明,有必要新建一個測試項目(暫且為“FormTest”吧),包含三張頁面足矣(Default.aspx、Login.aspx、UserInfo.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 設置的作用范圍,記住以下兩點:

          1、 Web.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),審核權限一般都在管理員或主管手里,并不想讓其他人瀏覽此頁面(真理往往掌握在少數人的手里,這也是沒法子的事),怎么辦?“辦法是人想出來滴”呵呵……新建一個管理員的目錄 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

          之前我曾強調,要注意,第一個參數很重要,重要到什么程度?說到這,恐怕地球人都知道了——它就是allow與deny的依據。假如此處用戶填寫的是“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記入ticket的userdata
          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也很簡單,FormsIdentity的Ticket屬性就提供了對當前票據的訪問,獲得票據后就可以用UserData屬性訪問保存的信息,當然是經過解密的。
          ((System.Web.Security.FormsIdentity)this.Context.User.Identity).Ticket.UserData


          下面是一個具體的應用。

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

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

          但是如果不能使用SSL呢?我們可以判斷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空的GenericIdentity和roles使票據失效,這樣將強迫用戶重新登錄。為了測試這個方法,可以先把條件改為相等,看效果如何 :)

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

          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!,注意是兩個。現在的安全作用范圍是整個類。

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

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

          下面是msdn給的示例

          示例

          下面的示例說明可以如何以聲明方式使用 PrincipalPermission 要求當前用戶是 Bob 并且屬于 Supervisor 角色。
          [PrincipalPermissionAttribute(SecurityAction.Demand, Name="Bob",
          Role="Supervisor")]下面的示例說明如何要求當前用戶的身份是 Bob,與角色成員條件無關。
          [PrincipalPermissionAttribute(SecurityAction.Demand, Name="Bob")]
          下面的示例說明如何僅要求對用戶進行身份驗證。
          [PrincipalPermissionAttribute(SecurityAction.Demand, Authenticated=true)]

          再要說一下的是,這里面的User和Role是可以和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");









          posted on 2012-09-08 18:57 ** 閱讀(1533) 評論(0)  編輯  收藏


          只有注冊用戶登錄后才能發表評論。


          網站導航:
           

          導航

          統計

          公告

          你好!

          常用鏈接

          留言簿(2)

          隨筆檔案

          文章分類

          文章檔案

          新聞檔案

          相冊

          收藏夾

          C#學習

          友情鏈接

          搜索

          最新評論

          閱讀排行榜

          評論排行榜

          主站蜘蛛池模板: 大英县| 隆子县| 林州市| 开远市| 台山市| 蒙山县| 黄山市| 甘洛县| 淮南市| 资中县| 苏州市| 遂川县| 土默特左旗| 建德市| 广元市| 灌云县| 上高县| 闵行区| 怀化市| 宜州市| 芦溪县| 徐州市| 稷山县| 苏尼特左旗| 博野县| 包头市| 博客| 鄂尔多斯市| 吐鲁番市| 闽清县| 墨竹工卡县| 锡林浩特市| 高邑县| 南丰县| 区。| 东阳市| 商丘市| 乐清市| 临沭县| 广元市| 北京市|