欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

.NET單點登陸的實現(xiàn)方法及思路

 更新時間:2013年07月26日 11:13:01   作者:  
這篇文章介紹了.NET單點登陸的實現(xiàn)方法及思路,有需要的朋友可以參考一下,希望對你有所幫助
系統(tǒng)的基本架構(gòu)
   我們假設(shè)一個系統(tǒng)System包含Service客戶服務(wù)中心、Shop網(wǎng)上購物中心和Office網(wǎng)上辦公中心三個獨立的網(wǎng)站。 Service管理客戶的資料,登錄和注銷過程。不論客戶訪問System的任何一個頁面,系統(tǒng)都會轉(zhuǎn)到登錄界面,在用戶登錄后,系統(tǒng)會自動轉(zhuǎn)會到客戶上 次請求的頁面。并且用戶此后可以在System中無縫切換。不需要再次進行登錄。即在System中實現(xiàn)單點登錄SSO(Single Sign-On)。
  我們知道,用戶的即時狀態(tài)通常是使用Application、Session、Cookie和存儲的。而這些都是不能在程序中跨站點訪問的。我們必需通過站點間相互通訊來確認(rèn)用戶的即時狀態(tài)。
 簡單的實現(xiàn)
   第一步,假設(shè)用戶訪問了Shop或Office的任何一個頁面Any。該頁面所在的網(wǎng)站將會檢查用戶的即時狀態(tài)。如果用戶已經(jīng)登錄了,則將 Any頁面的信息返回給用戶。如果用戶還沒有登錄,則自動轉(zhuǎn)到Service的Validate頁面,驗證用戶在Service狀態(tài)。即Shop或 Office向Service發(fā)出請求,要求Service返回用戶的即時狀態(tài)。
  第二步,Validate驗證用戶的即時狀態(tài),如果 用戶已經(jīng)登錄了,則Service將用戶的即時狀態(tài)返回給Shop或Office的同步頁面 Synchronous,通知Shop或Office同步用戶狀態(tài)。如果用戶沒有登錄,則自動轉(zhuǎn)向Customer頁面,提示用戶登錄。
  第三步,用戶完成登錄過程,當(dāng)用戶成功登錄后,自動轉(zhuǎn)回Validate頁面,通知Shop或Office的Synchronous進行用戶狀態(tài)的同步。
  第四步,在用戶狀態(tài)同步完成后,在本地站點,用戶狀態(tài)成為在線狀態(tài),即可訪問Any頁面。
  在上面的流程中。我們知道,不管用戶訪問哪個站點,用戶只需要一次登錄,就保證用戶在Service的即時狀態(tài)都是在線的,不會再需要進行第二次登錄的過程。
  現(xiàn)在我們的思路已經(jīng)清楚,具體的實現(xiàn)我們將在代碼分析中完成。
代碼分析
  從上面的流程中我們可以看出,系統(tǒng)中Shop和Office的代碼是完全類似的。只要Shop可以實現(xiàn),Office也可以同樣的克隆。所以我們的重點分析的對象是Shop和Service的代碼。
  1、Shop的Web.config和Project.cs
  在Shop的Web.config里,我們配置了Service站點和Shop站點,以方便我們在部署時方便修改。
復(fù)制代碼 代碼如下:

<appsettings>
<add key="Service" value="http://localhost:8001" />
<add key="WebSite" value="http://localhost:8002" />
</appsettings> 

 在Project類里進行引用。
復(fù)制代碼 代碼如下:

using System;
using System.Configuration;
namespace Amethysture.SSO.Shop
{
 public class Project
 {
  public static string Service = ConfigurationSettings.AppSettings["Service"];
  public static string WebSite = ConfigurationSettings.AppSettings["WebSite"];
 }
}

  2、Shop的Global.cs
   Shop的Global.cs定義了四個Session變量,UserID用來標(biāo)識用 戶身份。Pass標(biāo)識用戶即時狀態(tài),Security用于保存往來Service和Shop的通訊不是被仿冒的。Url保存了上次請求的頁面,以保證在用 戶登錄后能轉(zhuǎn)到用戶請求的頁面。
復(fù)制代碼 代碼如下:

protected void Session_Start(Object sender, EventArgs e)
{
 this.Session.Add("UserID", 0);
 this.Session.Add("Pass", false);
 this.Session.Add("Security", "");
 this.Session.Add("Url", "");
}

  3、Shop的Any.cs
  Shop的Any.cs并沒有包含代碼,因為Any類從Page繼承而來,為了代碼分析方便,我們將代碼集中到Page.cs中。
復(fù)制代碼 代碼如下:

using System;
using System.Web;
namespace Amethysture.SSO.Shop
{
 public class Any : Amethysture.SSO.Shop.Page
 {
 }
}

  4、Shop的Page.cs
  Page類有兩個方法,CustomerValidate和Initialize。CustomerValidate用戶檢查用戶的即時狀態(tài),而Initialize是頁面登錄后發(fā)送給用戶的信息。我們的重點是CustomerValidate。
   CustomerValidate是一個非常簡單的流程,用條件語句檢查Pass的狀態(tài),如果Pass為否,則表示用戶沒有登錄,頁面跳轉(zhuǎn)到 Service的Validate頁面中。我們要分析的是其中保存的Url和遞交的WebSite和Security幾個參數(shù)。Url的作用在前面已經(jīng)講 清楚了,只是為了保證用戶登錄后能回到原來的頁面。而WebSite是為了保證該站點是被Service所接受的,并且保證Service知道是哪個站點 請求了用戶即時狀態(tài)。因為這個例子是個簡單的例子,在后面的Validate里沒有驗證WebSite是否是接受的請求站點,但是在實際應(yīng)用中應(yīng)該驗證這 一點,因為Shop和Service等同于服務(wù)器和客戶端,服務(wù)器出于安全考慮必須要檢查客戶端是否是被允許的。Security是非常重要的一點。 Shop對Service發(fā)送的是請求,不需要保證該請求沒有被篡改,但是在Service應(yīng)答Shop請求時就必須要保證應(yīng)答的數(shù)據(jù)沒有被篡改了。 Security正是為了保證數(shù)據(jù)安全而設(shè)計的。
  在代碼中,Security是通過Hash一個隨機產(chǎn)生的數(shù)字生成的。具有不確定 性。和保密性。我們可以看到,Security同時保存在Session中和發(fā)送給Service。我們把這個Security當(dāng)作明文。在后面我們可以 看到,Security在Service經(jīng)過再一次Hash后作為密文發(fā)送回Shop。如果我們將Session保存的Security經(jīng)過同樣的 Hash方法處理后等到的字符串如果和Service返回的密文相同,我們就能夠在一定程度上保證Service應(yīng)答的數(shù)據(jù)是沒有經(jīng)過修改的。
復(fù)制代碼 代碼如下:

using System;
using System.Web;
using System.Security.Cryptography;
using System.Text;
namespace Amethysture.SSO.Shop
{
 public class Page : System.Web.UI.Page
 {
  private void CustomerValidate()
  {
   bool Pass = (bool) this.Session["Pass"];
   if (!Pass)
   {
    string Security = "";
    Random Seed = new Random();
    Security = Seed.Next(1, int.MaxValue).ToString();
    byte[] Value;
    UnicodeEncoding Code = new UnicodeEncoding();
    byte[] Message = Code.GetBytes(Security);
    SHA512Managed Arithmetic = new SHA512Managed();
    Value = Arithmetic.ComputeHash(Message);
    Security = "";
    foreach(byte o in Value)
    {
     Security += (int) o + "O";
    }
    this.Session["Security"] = Security;
    this.Session["Url"] = this.Request.RawUrl;
    this.Response.Redirect(Project.Service + "/Validate.aspx?WebSite=" + Project.WebSite + "&Security=" + Security);
   }
  }
  protected virtual void Initialize()
  {
   this.Response.Write("<html>");
   this.Response.Write("<head>"); 
   this.Response.Write("<title>Amethysture SSO Project</title>");
   this.Response.Write("<link rel=stylesheet type="text/css" href="" + project.website + "/Default.css">");
   this.Response.Write("</head>");
   this.Response.Write("<body>");
   this.Response.Write("<iframe width="0" height="0" src="" + project.service + "/Customer.aspx"></iframe>");
   this.Response.Write("<div align="center">");
   this.Response.Write("Amethysture SSO Shop Any Page");
   this.Response.Write("</div>");
   this.Response.Write("</body>");
   this.Response.Write("</html>");
  }
  protected override void OnInit(EventArgs e)
  {
   base.OnInit(e);
   this.CustomerValidate();
   this.Initialize();
   this.Response.End();
  }
 }
}

5、Service的Global.cs
   現(xiàn)在我們頁面轉(zhuǎn)到了Service的Validate頁面,我們轉(zhuǎn)過來看 Service的代碼。在Global中我們同樣定義了四個Session變量,都和Shop的Session用處類似。WebSite是保存請求用戶即 時狀態(tài)的站點信息。以便能在登錄后返回正確的請求站點。
復(fù)制代碼 代碼如下:

protected void Session_Start(Object sender, EventArgs e)
{
 this.Session.Add("UserID", 0);
 this.Session.Add("Pass", false);
 this.Session.Add("WebSite", "");
 this.Session.Add("Security", "");
}

  6、Service的Validate.cs
  首先,將Shop傳遞過來的參數(shù)保存到Session中。如果用戶沒有登錄,則轉(zhuǎn)到Customer頁面進行登錄。如果用戶已經(jīng)登錄了。則將用戶即時狀態(tài)傳回給Shop站點。如上所述,這里將Security重新Hash了一次傳回給Shop,以保證數(shù)據(jù)不被纂改。
復(fù)制代碼 代碼如下:

private void CustomerValidate()
{
 bool Pass = (bool) this.Session["Pass"];
 if ((this.Request.QueryString["WebSite"] != null) && (this.Request.QueryString["WebSite"] != ""))
 {
  this.Session["WebSite"] = this.Request.QueryString["WebSite"];
 }
 if ((this.Request.QueryString["Security"] != null) && (this.Request.QueryString["Security"] != ""))
 {
  this.Session["Security"] = this.Request.QueryString["Security"];
 }
 if (Pass)
 {
  string UserID = this.Session["UserID"].ToString();
  string WebSite = this.Session["WebSite"].ToString();
  string Security = this.Session["Security"].ToString();
  byte[] Value;
  UnicodeEncoding Code = new UnicodeEncoding();
  byte[] Message = Code.GetBytes(Security);
  SHA512Managed Arithmetic = new SHA512Managed();
  Value = Arithmetic.ComputeHash(Message);
  Security = "";
  foreach(byte o in Value)
  {
   Security += (int) o + "O";
  }
  this.Response.Redirect(WebSite + "/Synchronous.aspx?UserID=" + UserID + "&Pass=True&Security=" + Security);
 }
 else
 {
  this.Response.Redirect("Customer.aspx");
 }
}

  7、Service的Customer.cs和Login.cs
   Customer主要的是一個用于登錄的表單,這里就不 貼出代碼了。這里分析一下Login的一段代碼,這段代碼是當(dāng)?shù)卿浭侵苯釉赟ervice完成的(WebSite為空值),則頁面不會轉(zhuǎn)到Shop或 Office站點。所以應(yīng)該暫停在Service站點。系統(tǒng)如果比較完美,這里應(yīng)該顯示一組字系統(tǒng)的轉(zhuǎn)向鏈接。下面我們看到,當(dāng)Pass為真時,頁面轉(zhuǎn)回 到Validate頁面,通過上面的分析,我們知道,頁面會轉(zhuǎn)向Shop的Synchronous頁面,進行用戶狀態(tài)的同步。
復(fù)制代碼 代碼如下:

if (Pass)
{
 if ((this.Session["WebSite"].ToString() != "") && (this.Session["Security"].ToString() != ""))
 {
  this.Response.Redirect("Validate.aspx");
 }
 else
 {
  this.Response.Write("");
  this.Response.Write(""); 
  this.Response.Write("");
  this.Response.Write("");
  this.Response.Write("");
  this.Response.Write("");
  this.Response.Write("");
  this.Response.Write("Pass");
  this.Response.Write("");
  this.Response.Write("");  
  this.Response.Write("");
 }
}
else
{
 this.Response.Redirect("Customer.aspx");
}

  8、Shop的Synchronous.cs
   好了,我們在Service中完成了登錄,并把用戶狀態(tài)傳遞回Shop站 點。我們接著看用戶狀態(tài)是怎么同步的。首先,如果Session里的Security是空字符串,則表示Shop站點沒有向Service發(fā)送過請求,而 Service向Shop發(fā)回了請求,這顯然是錯誤的。這次訪問是由客戶端偽造進行的訪問,于是訪問被拒絕了。同樣Security和 InSecurity不相同,則表示請求和應(yīng)答是不匹配的??赡軕?yīng)答被纂改過了,所以應(yīng)答同樣被拒絕了。當(dāng)檢驗Security通過后,我們保證 Serive完成了應(yīng)答,并且返回了確切的參數(shù),下面就是讀出參數(shù)同步Shop站點和Service站點的用戶即時狀態(tài)。
復(fù)制代碼 代碼如下:

string InUserID = this.Request.QueryString["UserID"];
string InPass = this.Request.QueryString["Pass"];
string InSecurity = this.Request.QueryString["Security"];
string Security = this.Session["Security"].ToString();
if (Security != "")
{
 byte[] Value;
 UnicodeEncoding Code = new UnicodeEncoding();
 byte[] Message = Code.GetBytes(Security);
 SHA512Managed Arithmetic = new SHA512Managed();
 Value = Arithmetic.ComputeHash(Message);
 Security = "";
 foreach(byte o in Value)
 {
  Security += (int) o + "O";
 }
 if (Security == InSecurity)
 {
  if (InPass == "True")
  {
   this.Session["UserID"] = int.Parse(InUserID);
   this.Session["Pass"] = true;
   this.Response.Redirect(this.Session["Url"].ToString());
  }
 }
 else
 {
  this.Response.Write("");
  this.Response.Write(""); 
  this.Response.Write("");
  this.Response.Write("");
  this.Response.Write("");
  this.Response.Write("");
  this.Response.Write("");
  this.Response.Write("數(shù)據(jù)錯誤");
  this.Response.Write("");
  this.Response.Write("");
  this.Response.Write("");
 }
}
else
{
 this.Response.Write("");
 this.Response.Write(""); 
 this.Response.Write("");
 this.Response.Write("");
 this.Response.Write("");
 this.Response.Write("");
 this.Response.Write("");
 this.Response.Write("訪問錯誤");
 this.Response.Write("");
 this.Response.Write("");
 this.Response.Write("");
}

 9、Shop的Page.cs
   我們知道,頁面在一段時間不刷新后,Session會超時失效,在我們一直訪問Shop的 時候怎么才能保證Service的Session不會失效呢?很簡單,我們返回來看Shop的Page.cs。通過在所有Shop的頁面內(nèi)都用 <iframe>嵌套Service的某個頁面,就能保證Service能和Shop的頁面同時刷新。需要注意的一點是Service的Session必 須保證不小于所有Shop和Office的Session超時時間。這個在Web.config里可以進行配置。
復(fù)制代碼 代碼如下:

this.Response.Write("<iframe width="0" height="0" src="" + project.service + "/Customer.aspx"></iframe>");

總結(jié)
   一次完整的登錄完成了。我們接著假設(shè)一下現(xiàn)在要跳到Office的Any頁面,系統(tǒng)會進行怎樣的操作 呢?Any(用戶沒有登錄)->Validate(用戶已經(jīng)登錄)->Synchronous(同步)->Any。也就是說這次,用戶沒有進行登錄的過 程。我們通過一次登錄,使得Service的用戶狀態(tài)為登錄,并且不管有多少個網(wǎng)站應(yīng)用,只要這些網(wǎng)站都保證符合Shop的特性,這些網(wǎng)站就都能保持 Service的用戶狀態(tài),同時能通過Service獲得用戶的狀態(tài)。也就是說我們實現(xiàn)了SSO

相關(guān)文章

  • C#中Linq查詢基本操作使用實例

    C#中Linq查詢基本操作使用實例

    這篇文章主要介紹了C#中Linq查詢基本操作使用實例,有需要的朋友可以參考一下
    2013-12-12
  • C#實現(xiàn)定時任務(wù)Task Scheduler的示例代碼

    C#實現(xiàn)定時任務(wù)Task Scheduler的示例代碼

    這篇文章主要為大家詳細(xì)介紹了C#實現(xiàn)定時任務(wù)Task Scheduler的相關(guān)知識,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2024-02-02
  • C#實現(xiàn)冒泡排序算法的代碼示例

    C#實現(xiàn)冒泡排序算法的代碼示例

    冒泡排序即是對數(shù)組每次輪循出最大數(shù)或最小數(shù)放在隊尾,這里我們來看一下C#實現(xiàn)冒泡排序算法的代碼示例,需要的朋友可以參考下
    2016-07-07
  • 如何使用Dapper處理多個結(jié)果集與多重映射實例教程

    如何使用Dapper處理多個結(jié)果集與多重映射實例教程

    Dapper類是一個開源的數(shù)據(jù)庫操作類,下面這篇文章主要給大家介紹了關(guān)于如何使用Dapper處理多個結(jié)果集與多重映射的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),需要的朋友可以參考借鑒,下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2018-09-09
  • 詳解C#如何實現(xiàn)窗體換膚

    詳解C#如何實現(xiàn)窗體換膚

    這篇文章主要為大家詳細(xì)介紹了如何利用C#實現(xiàn)窗體換膚,文中的示例代碼講解詳細(xì),對我們學(xué)習(xí)C#有一定的幫助,感興趣的小伙伴可以跟隨小編一起了解一下
    2022-12-12
  • C#使用DLLImport調(diào)用外部DLL的方法

    C#使用DLLImport調(diào)用外部DLL的方法

    這篇文章介紹了C#使用DLLImport調(diào)用外部DLL的方法,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-04-04
  • C#實現(xiàn)把彩色圖片灰度化代碼分享

    C#實現(xiàn)把彩色圖片灰度化代碼分享

    這篇文章主要介紹了C#實現(xiàn)把彩色圖片灰度化代碼分享,用在一些特殊場合中,需要的朋友可以參考下
    2014-08-08
  • C#實現(xiàn)網(wǎng)絡(luò)小程序的步驟詳解

    C#實現(xiàn)網(wǎng)絡(luò)小程序的步驟詳解

    經(jīng)常要檢測某些IP地址范圍段的計算機是否在線。有很多的方法,比如進入到網(wǎng)關(guān)的交換機上去查詢、使用現(xiàn)成的工具或者編寫一個簡單的DOS腳本等等,這些都比較容易實現(xiàn)。本文將用C#來實現(xiàn),感興趣的可以了解一下
    2022-12-12
  • 詳解c# 強制轉(zhuǎn)換和類型轉(zhuǎn)換

    詳解c# 強制轉(zhuǎn)換和類型轉(zhuǎn)換

    這篇文章主要介紹了c# 強制轉(zhuǎn)換和類型轉(zhuǎn)換的相關(guān)資料,幫助大家更好的理解和學(xué)習(xí)c#,感興趣的朋友可以了解下
    2020-10-10
  • C#實現(xiàn)串口調(diào)試工具

    C#實現(xiàn)串口調(diào)試工具

    這篇文章介紹了C#實現(xiàn)串口調(diào)試工具的方法,文中通過示例代碼介紹的非常詳細(xì)。對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-01-01

最新評論