程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> C#入門知識 >> asp.net 真正實現完全跨域單點登錄

asp.net 真正實現完全跨域單點登錄

編輯:C#入門知識

單點登錄(Single Sign On),簡稱為 SSO,是目前比較流行的企業業務整合的解決方案之一。SSO的定義是在多個應用系統中,用戶只需要登錄一次就可以訪問所有相互信任的應用系統。

asp.net跨域單點登錄分為:

1、跨子域單點登錄。如 blog.a.com 和 info.a.com 這2個站點同屬一個主域.a.com,實現跨子域單點登錄很簡單,可以利用cookie,設置Domain為”.a.com'即可,這裡就不再贅敘。

2、完成跨域單點登錄。如 www.a.com www.b.com 這2個站點之間實現共享一個身份驗證系統,只需在一處地方登錄,下面主要談下這種方式的實現方法。

 

asp.net 跨域單點登錄實現原理:

當用戶第一次訪問web應用系統1的時候,因為還沒有登錄,會被引導到認證中心進行登錄;根據用戶提供的登錄信息,認證系統進行身份效驗,如果通過效驗,返回給用戶一個認證的憑據;用戶再訪問別的web應用的時候就會將這個Token帶上,作為自己認證的憑據,應用系統接受到請求之後會把Token送到認證中心進行效驗,檢查Token的合法性。如果通過效驗,用戶就可以在不用再次登錄的情況下訪問應用系統2和應用系統3了。所有應用系統共享一個身份認證系統。認證系統的主要功能是將用戶的登錄信息和用戶信息庫相比較,對用戶進行登錄認證;認證成功後,認證系統應該生成統一的認證標志,返還給用戶。另外,認證系統還應該對Token進行效驗,判斷其有效性。 所有應用系統能夠識別和提取Token信息要實現SSO的功能,讓用戶只登錄一次,就必須讓應用系統能夠識別已經登錄過的用戶。應用系統應該能對Token進行識別和提取,通過與認證系統的通訊,能自動判斷當前用戶是否登錄過,從而完成單點登錄的功能。

比如說,我現在有3個分站點和1個認證中心(總站)。當用戶訪問分站點的時候,分站點會發Token到驗證中心進行驗證。驗證中心判斷用戶是否已經登錄。如果未登錄,則返回到驗證中心登錄入口進行登錄,否之則返回Token驗證到分站點,直接進入分站點。

 

如圖所示:

 

上面是實現單點登錄的原理圖,下面介紹下如何用asp.net實現跨域單點登錄:

一、新建網站 MasterSite,作為總站認證中心。配置web.config,采用form登錄驗證。
配置如下:

<authentication mode=”Forms”> 
<forms name=”.AspxFormAuth” loginUrl=”Default.aspx” defaultUrl=”center.html” protection=”All” path=”/” timeout=”120”> 
</forms> 
</authentication> 
<authorization> 
<!--拒絕所有匿名用戶--> 
<deny users=”?”/> 
</authorization> 
<authentication mode=”Forms”>
<forms name=”.AspxFormAuth” loginUrl=”Default.aspx” defaultUrl=”center.html” protection=”All” path=”/” timeout=”120”>
</forms>
</authentication>
<authorization>
<!--拒絕所有匿名用戶-->
<deny users=”?”/>
</authorization>

 

添加Default.aspx頁面,用來進行登錄。代碼如下:

HTML Code:

<%@ Page Language=”C#” AutoEventWireup=”true” CodeFile=”Default.aspx.cs” Inherits=”_Default” %> 

<!DOCTYPE html PUBLIC ”-//W3C//DTD XHTML 1.0 Transitional//EN” ”http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd”> 

<html xmlns=”http://www.w3.org/1999/xhtml” > 
<head runat=”server”> 
<title>總站登錄</title> 
</head> 
<body> 
<form id=”form1” runat=”server”> 
<div> 
<asp:Login ID=”Login1” runat=”server” OnAuthenticate=”Login1_Authenticate” UserName=”test”> 
</asp:Login> 
</div> 
</form> 
</body> 
</html> 
<%@ Page Language=”C#” AutoEventWireup=”true” CodeFile=”Default.aspx.cs” Inherits=”_Default” %>

<!DOCTYPE html PUBLIC ”-//W3C//DTD XHTML 1.0 Transitional//EN” ”http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd”>

<html xmlns=”http://www.w3.org/1999/xhtml” >
<head runat=”server”>
<title>總站登錄</title>
</head>
<body>
<form id=”form1” runat=”server”>
<div>
<asp:Login ID=”Login1” runat=”server” OnAuthenticate=”Login1_Authenticate” UserName=”test”>
</asp:Login>
</div>
</form>
</body>
</html>


Default.cs Code:


using System; 
using System.Data; 
using System.Configuration; 
using System.Web; 
using System.Web.Security; 
using System.Web.UI; 
using System.Web.UI.WebControls; 
using System.Web.UI.WebControls.WebParts; 
using System.Web.UI.HtmlControls; 
using System.Text; 

public partial class _Default : System.Web.UI.Page 

protected void Page_Load(object sender, EventArgs e) 

if (!IsPostBack) 

SSORequest ssoRequest = new SSORequest(); 


#region 驗證 Post 過來的參數 
//-------------------------------- 
// 請求注銷 
if (!string.IsNullOrEmpty(Request[”Logout”])) 

Authentication.Logout(); 
return; 

//-------------------------------- 
// 各獨立站點標識 
if (string.IsNullOrEmpty(Request[”IASID”])) 

return; 

else 

ssoRequest.IASID = Request[”IASID”]; 


//-------------------------------- 
// 時間戳 
if (string.IsNullOrEmpty(Request[”TimeStamp”])) 

return; 

else 

ssoRequest.TimeStamp = Request[”TimeStamp”]; 


//-------------------------------- 
// 各獨立站點的訪問地址 
if (string.IsNullOrEmpty(Request[”AppUrl”])) 

return; 

else 

ssoRequest.AppUrl = Request[”AppUrl”]; 


//-------------------------------- 
// 各獨立站點的 Token 
if (string.IsNullOrEmpty(Request[”Authenticator”])) 

return; 

else 

ssoRequest.Authenticator = Request[”Authenticator”]; 


ViewState[”SSORequest”] = ssoRequest; 

#endregion 


//驗證從分站發過來的Token 
if (Authentication.ValidateAppToken(ssoRequest)) 

string userAccount = null; 

// 驗證用戶之前是否登錄過 
//驗證 EAC 認證中心的 Cookie,驗證通過時獲取用戶登錄賬號 
if (Authentication.ValidateEACCookie(out userAccount)) 

ssoRequest.UserAccount = userAccount; 

//創建認證中心發往各分站的 Token 
if (Authentication.CreateEACToken(ssoRequest)) 

Post(ssoRequest); 


else 

return; 


else 

return; 





//post請求 
void Post(SSORequest ssoRequest) 

PostService ps = new PostService(); 

ps.Url = ssoRequest.AppUrl; 

ps.Add(”UserAccount”, ssoRequest.UserAccount); 
ps.Add(”IASID”, ssoRequest.IASID); 
ps.Add(”TimeStamp”, ssoRequest.TimeStamp); 
ps.Add(”AppUrl”, ssoRequest.AppUrl); 
ps.Add(”Authenticator”, ssoRequest.Authenticator); 

ps.Post(); 


/// <summary> 
/// 驗證登錄賬號和密碼是否正確 
/// </summary> 
/// <param name=”userName”>登錄賬號</param> 
/// <param name=”userPwd”>登錄密碼</param> 
/// <returns></returns> 
private bool ValidateUserInfo(string userName, string userPwd) 

//從數據庫中讀取,驗證登錄賬號和密碼 
//略... 
return true; 


protected void Login1_Authenticate(object sender, AuthenticateEventArgs e) 

if (string.IsNullOrEmpty(Login1.UserName) || string.IsNullOrEmpty(Login1.Password)) 

Page.RegisterClientScriptBlock(”Add”, ”<mce:script lanuage=\”javascript\”><!-- 
alert('用戶名密碼不能為空!'); 
// --></mce:script>”); 
return; 

else if (ValidateUserInfo(Login1.UserName, Login1.Password) == false) 

Page.RegisterClientScriptBlock(”Add”, ”<mce:script lanuage=\”javascript\”><!-- 
alert('用戶名密碼錯誤!'); 
// --></mce:script>”); 
return; 

else 

Session[”CurrUserName”] = Login1.UserName; 
Session.Timeout = 120; 

SSORequest ssoRequest = ViewState[”SSORequest”] as SSORequest; 

// 如果不是從各分站 Post 過來的請求,則默認登錄主站 
if (ssoRequest == null) 

FormsAuthentication.SetAuthCookie(Login1.UserName, false); 

ssoRequest = new SSORequest(); 
//主站標識ID 
ssoRequest.IASID = ”00”; 
ssoRequest.AppUrl = ”SiteList.aspx”; 
ssoRequest.TimeStamp = DateTime.Now.ToString(”yyyy-MM-dd HH:mm”); 
ssoRequest.Authenticator = string.Empty; 

Response.Redirect(”SiteList.aspx”); 

ssoRequest.UserAccount = Login1.UserName; 

//創建Token 
if (Authentication.CreateEACToken(ssoRequest)) 

string expireTime = DateTime.Now.AddHours(3).ToString(”yyyy-MM-dd HH:mm”); 

Authentication.CreatEACCookie(ssoRequest.UserAccount, ssoRequest.TimeStamp, expireTime); 

Post(ssoRequest); 







using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Text;

public partial class _Default : System.Web.UI.Page 
{
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
SSORequest ssoRequest = new SSORequest();


#region 驗證 Post 過來的參數
//--------------------------------
// 請求注銷
if (!string.IsNullOrEmpty(Request[”Logout”]))
{
Authentication.Logout();
return;
}
//--------------------------------
// 各獨立站點標識
if (string.IsNullOrEmpty(Request[”IASID”]))
{
return;
}
else
{
ssoRequest.IASID = Request[”IASID”];
}

//--------------------------------
// 時間戳
if (string.IsNullOrEmpty(Request[”TimeStamp”]))
{
return;
}
else
{
ssoRequest.TimeStamp = Request[”TimeStamp”];
}

//--------------------------------
// 各獨立站點的訪問地址
if (string.IsNullOrEmpty(Request[”AppUrl”]))
{
return;
}
else
{
ssoRequest.AppUrl = Request[”AppUrl”];
}

//--------------------------------
// 各獨立站點的 Token
if (string.IsNullOrEmpty(Request[”Authenticator”]))
{
return;
}
else
{
ssoRequest.Authenticator = Request[”Authenticator”];
}

ViewState[”SSORequest”] = ssoRequest;

#endregion


//驗證從分站發過來的Token
if (Authentication.ValidateAppToken(ssoRequest))
{
string userAccount = null;

// 驗證用戶之前是否登錄過
//驗證 EAC 認證中心的 Cookie,驗證通過時獲取用戶登錄賬號
if (Authentication.ValidateEACCookie(out userAccount))
{
ssoRequest.UserAccount = userAccount;

//創建認證中心發往各分站的 Token
if (Authentication.CreateEACToken(ssoRequest))
{
Post(ssoRequest);
}
}
else
{
return;
}
}
else
{
return;
}
}
}


//post請求
void Post(SSORequest ssoRequest)
{
PostService ps = new PostService();

ps.Url = ssoRequest.AppUrl;

ps.Add(”UserAccount”, ssoRequest.UserAccount);
ps.Add(”IASID”, ssoRequest.IASID);
ps.Add(”TimeStamp”, ssoRequest.TimeStamp);
ps.Add(”AppUrl”, ssoRequest.AppUrl);
ps.Add(”Authenticator”, ssoRequest.Authenticator);

ps.Post();
}

/// <summary>
/// 驗證登錄賬號和密碼是否正確
/// </summary>
/// <param name=”userName”>登錄賬號</param>
/// <param name=”userPwd”>登錄密碼</param>
/// <returns></returns>
private bool ValidateUserInfo(string userName, string userPwd)
{
//從數據庫中讀取,驗證登錄賬號和密碼
//略...
return true;
}

protected void Login1_Authenticate(object sender, AuthenticateEventArgs e)
{
if (string.IsNullOrEmpty(Login1.UserName) || string.IsNullOrEmpty(Login1.Password))
{
Page.RegisterClientScriptBlock(”Add”, ”<mce:script lanuage=\”javascript\”><!--
alert('用戶名密碼不能為空!');
// --></mce:script>”);
return;
}
else if (ValidateUserInfo(Login1.UserName, Login1.Password) == false)
{
Page.RegisterClientScriptBlock(”Add”, ”<mce:script lanuage=\”javascript\”><!--
alert('用戶名密碼錯誤!');
// --></mce:script>”);
return;
}
else
{
Session[”CurrUserName”] = Login1.UserName;
Session.Timeout = 120;

SSORequest ssoRequest = ViewState[”SSORequest”] as SSORequest;

// 如果不是從各分站 Post 過來的請求,則默認登錄主站
if (ssoRequest == null)
{
FormsAuthentication.SetAuthCookie(Login1.UserName, false);

ssoRequest = new SSORequest();
//主站標識ID
ssoRequest.IASID = ”00”;
ssoRequest.AppUrl = ”SiteList.aspx”;
ssoRequest.TimeStamp = DateTime.Now.ToString(”yyyy-MM-dd HH:mm”);
ssoRequest.Authenticator = string.Empty;

Response.Redirect(”SiteList.aspx”);
}
ssoRequest.UserAccount = Login1.UserName;

//創建Token
if (Authentication.CreateEACToken(ssoRequest))
{
string expireTime = DateTime.Now.AddHours(3).ToString(”yyyy-MM-dd HH:mm”);

Authentication.CreatEACCookie(ssoRequest.UserAccount, ssoRequest.TimeStamp, expireTime);

Post(ssoRequest);
}

}
}


}

 


代碼說明:驗證分站post過來的Token請求,如果用戶已經登錄,則創建認證中心發往各分站的 Token驗證,轉向分站,否之則返回登錄。若是直接登錄主站則轉向站點選擇頁面sitelist.aspx,選擇你要登錄的分站點。

如圖:

 

 


二、新建站點1,代碼如下:

HTML Code:

<%@ Page Language=”C#” AutoEventWireup=”true” CodeFile=”Default.aspx.cs” Inherits=”_Default” %> 

<!DOCTYPE html PUBLIC ”-//W3C//DTD XHTML 1.0 Transitional//EN” ”http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd”> 

<html xmlns=”http://www.w3.org/1999/xhtml” > 
<head runat=”server”> 
<title> 站點一</title> 
</head> 
<body> 
<form id=”form1” runat=”server”> 
<div> 
<br /> 
<br /> 
<asp:LinkButton ID=”LinkButton1” runat=”server” OnClick=”LinkButton1_Click”>返回主站</asp:LinkButton> 

<asp:LinkButton ID=”LinkButton2” runat=”server” OnClick=”LinkButton2_Click”>注銷登錄</asp:LinkButton></div> 
</form> 
</body> 
</html> 
<%@ Page Language=”C#” AutoEventWireup=”true” CodeFile=”Default.aspx.cs” Inherits=”_Default” %>

<!DOCTYPE html PUBLIC ”-//W3C//DTD XHTML 1.0 Transitional//EN” ”http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd”>

<html xmlns=”http://www.w3.org/1999/xhtml” >
<head runat=”server”>
<title> 站點一</title>
</head>
<body>
<form id=”form1” runat=”server”>
<div>
<br />
<br />
<asp:LinkButton ID=”LinkButton1” runat=”server” OnClick=”LinkButton1_Click”>返回主站</asp:LinkButton>

<asp:LinkButton ID=”LinkButton2” runat=”server” OnClick=”LinkButton2_Click”>注銷登錄</asp:LinkButton></div>
</form>
</body>
</html>

Default.cs code:

using System; 
using System.Data; 
using System.Configuration; 
using System.Web; 
using System.Web.Security; 
using System.Web.UI; 
using System.Web.UI.WebControls; 
using System.Web.UI.WebControls.WebParts; 
using System.Web.UI.HtmlControls; 
using System.Text; 

public partial class _Default : System.Web.UI.Page 

protected void Page_Load(object sender, EventArgs e) 

if (!IsPostBack) 

#region SSO 部分代碼 
SSORequest ssoRequest = new SSORequest(); 

if (string.IsNullOrEmpty(Request[”IASID”])) 

ssoRequest.IASID = ”01”; 
ssoRequest.TimeStamp = DateTime.Now.ToString(”yyyy-MM-dd HH:mm”); 
ssoRequest.AppUrl = Request.Url.ToString(); 
Authentication.CreateAppToken(ssoRequest); 

Post(ssoRequest); 

else if (!string.IsNullOrEmpty(Request[”IASID”]) 
&& !string.IsNullOrEmpty(Request[”TimeStamp”]) 
&& !string.IsNullOrEmpty(Request[”AppUrl”]) 
&& !string.IsNullOrEmpty(Request[”UserAccount”]) 
&& !string.IsNullOrEmpty(Request[”Authenticator”])) 

ssoRequest.IASID = Request[”IASID”]; 
ssoRequest.TimeStamp = Request[”TimeStamp”]; 
ssoRequest.AppUrl = Request[”AppUrl”]; 
ssoRequest.UserAccount = Request[”UserAccount”]; 
ssoRequest.Authenticator = Request[”Authenticator”]; 

if (Authentication.ValidateEACToken(ssoRequest)) 

//從數據庫中獲取UserId 
Session[”CurrUserName”] = Request[”UserAccount”]; 
Session.Timeout = 120; 
FormsAuthentication.SetAuthCookie(Request[”UserAccount”], false); 
Response.Write(string.Format(”{0},您好!歡迎來到site1, >> 訪問<a href=”\” mce_href=”\””http://localhost/Site2/Default.aspx\”>site2</a>”,ssoRequest.UserAccount)); 



ViewState[”SSORequest”] = ssoRequest; 

#endregion 



void Post(SSORequest ssoRequest) 

PostService ps = new PostService(); 
//認證中心(主站)地址 
string EACUrl = ”http://localhost/MasterSite/Default.aspx”; 
ps.Url = EACUrl; 
//ps.Add(”UserAccount”, ssoRequest.UserAccount); 
ps.Add(”IASID”, ssoRequest.IASID); 
ps.Add(”TimeStamp”, ssoRequest.TimeStamp); 
ps.Add(”AppUrl”, ssoRequest.AppUrl); 
ps.Add(”Authenticator”, ssoRequest.Authenticator); 

ps.Post(); 



//注銷登錄 
protected void LinkButton2_Click(object sender, EventArgs e) 

FormsAuthentication.SignOut(); 

SSORequest ssoRequest = new SSORequest(); 

ssoRequest.IASID = ”01”; 
ssoRequest.TimeStamp = DateTime.Now.ToString(”yyyy-MM-dd HH:mm”); 
ssoRequest.AppUrl = Request.Url.ToString(); 

Authentication.CreateAppToken(ssoRequest); 

PostService ps = new PostService(); 

//認證中心(主站)地址 
string EACUrl = ”http://localhost/MasterSite/Default.aspx”; 
ps.Url = EACUrl; 

ps.Add(”IASID”, ssoRequest.IASID); 
ps.Add(”TimeStamp”, ssoRequest.TimeStamp); 
ps.Add(”AppUrl”, ssoRequest.AppUrl); 
ps.Add(”Authenticator”, ssoRequest.Authenticator); 

ps.Add(”Logout”, ”true”); 

ps.Post(); 


//返回主站 
protected void LinkButton1_Click(object sender, EventArgs e) 

if (Session[”CurrUserName”] != null) 

Response.Redirect(”http://localhost/MasterSite/SiteList.aspx”); 



using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Text;

public partial class _Default : System.Web.UI.Page 
{
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
#region SSO 部分代碼
SSORequest ssoRequest = new SSORequest();

if (string.IsNullOrEmpty(Request[”IASID”]))
{
ssoRequest.IASID = ”01”;
ssoRequest.TimeStamp = DateTime.Now.ToString(”yyyy-MM-dd HH:mm”);
ssoRequest.AppUrl = Request.Url.ToString();
Authentication.CreateAppToken(ssoRequest);

Post(ssoRequest);
}
else if (!string.IsNullOrEmpty(Request[”IASID”])
&& !string.IsNullOrEmpty(Request[”TimeStamp”])
&& !string.IsNullOrEmpty(Request[”AppUrl”])
&& !string.IsNullOrEmpty(Request[”UserAccount”])
&& !string.IsNullOrEmpty(Request[”Authenticator”]))
{
ssoRequest.IASID = Request[”IASID”];
ssoRequest.TimeStamp = Request[”TimeStamp”];
ssoRequest.AppUrl = Request[”AppUrl”];
ssoRequest.UserAccount = Request[”UserAccount”];
ssoRequest.Authenticator = Request[”Authenticator”];

if (Authentication.ValidateEACToken(ssoRequest))
{
//從數據庫中獲取UserId
Session[”CurrUserName”] = Request[”UserAccount”];
Session.Timeout = 120;
FormsAuthentication.SetAuthCookie(Request[”UserAccount”], false);
Response.Write(string.Format(”{0},您好!歡迎來到site1, >> 訪問<a href=”\” mce_href=”\””http://localhost/Site2/Default.aspx\”>site2</a>”,ssoRequest.UserAccount));
}
}

ViewState[”SSORequest”] = ssoRequest;

#endregion
}
}

void Post(SSORequest ssoRequest)
{
PostService ps = new PostService();
//認證中心(主站)地址
string EACUrl = ”http://localhost/MasterSite/Default.aspx”;
ps.Url = EACUrl;
//ps.Add(”UserAccount”, ssoRequest.UserAccount);
ps.Add(”IASID”, ssoRequest.IASID);
ps.Add(”TimeStamp”, ssoRequest.TimeStamp);
ps.Add(”AppUrl”, ssoRequest.AppUrl);
ps.Add(”Authenticator”, ssoRequest.Authenticator);

ps.Post();
}


//注銷登錄
protected void LinkButton2_Click(object sender, EventArgs e)
{
FormsAuthentication.SignOut();

SSORequest ssoRequest = new SSORequest();

ssoRequest.IASID = ”01”;
ssoRequest.TimeStamp = DateTime.Now.ToString(”yyyy-MM-dd HH:mm”);
ssoRequest.AppUrl = Request.Url.ToString();

Authentication.CreateAppToken(ssoRequest);

PostService ps = new PostService();

//認證中心(主站)地址
string EACUrl = ”http://localhost/MasterSite/Default.aspx”;
ps.Url = EACUrl;

ps.Add(”IASID”, ssoRequest.IASID);
ps.Add(”TimeStamp”, ssoRequest.TimeStamp);
ps.Add(”AppUrl”, ssoRequest.AppUrl);
ps.Add(”Authenticator”, ssoRequest.Authenticator);

ps.Add(”Logout”, ”true”);

ps.Post();
}

//返回主站
protected void LinkButton1_Click(object sender, EventArgs e)
{
if (Session[”CurrUserName”] != null)
{
Response.Redirect(”http://localhost/MasterSite/SiteList.aspx”);
}
}
}

配置web.config

<authentication mode=”Forms”> 
<forms name=”.AspxFormAuth” loginUrl=”Default.aspx” defaultUrl=”center.html” protection=”All” path=”/” timeout=”60”> 
</forms> 
</authentication> 
<authorization> 
<!--拒絕所有匿名用戶--> 
<deny users=”?”/> 
</authorization> 
<authentication mode=”Forms”>
<forms name=”.AspxFormAuth” loginUrl=”Default.aspx” defaultUrl=”center.html” protection=”All” path=”/” timeout=”60”>
</forms>
</authentication>
<authorization>
<!--拒絕所有匿名用戶-->
<deny users=”?”/>
</authorization>

三、同二一樣,新建站點Site2,代碼如下:

using System; 
using System.Data; 
using System.Configuration; 
using System.Web; 
using System.Web.Security; 
using System.Web.UI; 
using System.Web.UI.WebControls; 
using System.Web.UI.WebControls.WebParts; 
using System.Web.UI.HtmlControls; 

public partial class _Default : System.Web.UI.Page 

protected void Page_Load(object sender, EventArgs e) 

if (!IsPostBack) 

#region SSO 部分代碼 
SSORequest ssoRequest = new SSORequest(); 

if (string.IsNullOrEmpty(Request[”IASID”])) 

ssoRequest.IASID = ”02”; 
ssoRequest.TimeStamp = DateTime.Now.ToString(”yyyy-MM-dd HH:mm”); 
ssoRequest.AppUrl = Request.Url.ToString(); 
Authentication.CreateAppToken(ssoRequest); 

Post(ssoRequest); 

else if (!string.IsNullOrEmpty(Request[”IASID”]) 
&& !string.IsNullOrEmpty(Request[”TimeStamp”]) 
&& !string.IsNullOrEmpty(Request[”AppUrl”]) 
&& !string.IsNullOrEmpty(Request[”UserAccount”]) 
&& !string.IsNullOrEmpty(Request[”Authenticator”])) 

ssoRequest.IASID = Request[”IASID”]; 
ssoRequest.TimeStamp = Request[”TimeStamp”]; 
ssoRequest.AppUrl = Request[”AppUrl”]; 
ssoRequest.UserAccount = Request[”UserAccount”]; 
ssoRequest.Authenticator = Request[”Authenticator”]; 

if (Authentication.ValidateEACToken(ssoRequest)) 

Session[”CurrUserName”] = Request[”UserAccount”]; 
Session.Timeout = 120; 
FormsAuthentication.SetAuthCookie(Request[”UserAccount”], false); 
Response.Write(string.Format(”{0},您好!歡迎來到site2, >> 訪問<a href=”\” mce_href=”\””http://localhost/Site1/Default.aspx\”>site1</a>”, ssoRequest.UserAccount)); 



ViewState[”SSORequest”] = ssoRequest; 

#endregion 



void Post(SSORequest ssoRequest) 

PostService ps = new PostService(); 
//認證中心(主站)地址 
string EACUrl = ”http://localhost/MasterSite/Default.aspx”; 
ps.Url = EACUrl; 
//ps.Add(”UserAccount”, ssoRequest.UserAccount); 
ps.Add(”IASID”, ssoRequest.IASID); 
ps.Add(”TimeStamp”, ssoRequest.TimeStamp); 
ps.Add(”AppUrl”, ssoRequest.AppUrl); 
ps.Add(”Authenticator”, ssoRequest.Authenticator); 

ps.Post(); 



//注銷登錄 
protected void LinkButton2_Click(object sender, EventArgs e) 

FormsAuthentication.SignOut(); 

SSORequest ssoRequest = new SSORequest(); 

ssoRequest.IASID = ”02”; 
ssoRequest.TimeStamp = DateTime.Now.ToString(”yyyy-MM-dd HH:mm”); 
ssoRequest.AppUrl = Request.Url.ToString(); 

Authentication.CreateAppToken(ssoRequest); 

PostService ps = new PostService(); 

//認證中心(主站)地址 
string EACUrl = ”http://localhost/MasterSite/Default.aspx”; 
ps.Url = EACUrl; 

ps.Add(”IASID”, ssoRequest.IASID); 
ps.Add(”TimeStamp”, ssoRequest.TimeStamp); 
ps.Add(”AppUrl”, ssoRequest.AppUrl); 
ps.Add(”Authenticator”, ssoRequest.Authenticator); 

ps.Add(”Logout”, ”true”); 

ps.Post(); 


//返回主站 
protected void LinkButton1_Click(object sender, EventArgs e) 

if (Session[”CurrUserName”] != null) 

Response.Redirect(”http://localhost/MasterSite/SiteList.aspx”); 



using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;

public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
#region SSO 部分代碼
SSORequest ssoRequest = new SSORequest();

if (string.IsNullOrEmpty(Request[”IASID”]))
{
ssoRequest.IASID = ”02”;
ssoRequest.TimeStamp = DateTime.Now.ToString(”yyyy-MM-dd HH:mm”);
ssoRequest.AppUrl = Request.Url.ToString();
Authentication.CreateAppToken(ssoRequest);

Post(ssoRequest);
}
else if (!string.IsNullOrEmpty(Request[”IASID”])
&& !string.IsNullOrEmpty(Request[”TimeStamp”])
&& !string.IsNullOrEmpty(Request[”AppUrl”])
&& !string.IsNullOrEmpty(Request[”UserAccount”])
&& !string.IsNullOrEmpty(Request[”Authenticator”]))
{
ssoRequest.IASID = Request[”IASID”];
ssoRequest.TimeStamp = Request[”TimeStamp”];
ssoRequest.AppUrl = Request[”AppUrl”];
ssoRequest.UserAccount = Request[”UserAccount”];
ssoRequest.Authenticator = Request[”Authenticator”];

if (Authentication.ValidateEACToken(ssoRequest))
{
Session[”CurrUserName”] = Request[”UserAccount”];
Session.Timeout = 120;
FormsAuthentication.SetAuthCookie(Request[”UserAccount”], false);
Response.Write(string.Format(”{0},您好!歡迎來到site2, >> 訪問<a href=”\” mce_href=”\””http://localhost/Site1/Default.aspx\”>site1</a>”, ssoRequest.UserAccount));
}
}

ViewState[”SSORequest”] = ssoRequest;

#endregion
}
}

void Post(SSORequest ssoRequest)
{
PostService ps = new PostService();
//認證中心(主站)地址
string EACUrl = ”http://localhost/MasterSite/Default.aspx”;
ps.Url = EACUrl;
//ps.Add(”UserAccount”, ssoRequest.UserAccount);
ps.Add(”IASID”, ssoRequest.IASID);
ps.Add(”TimeStamp”, ssoRequest.TimeStamp);
ps.Add(”AppUrl”, ssoRequest.AppUrl);
ps.Add(”Authenticator”, ssoRequest.Authenticator);

ps.Post();
}


//注銷登錄
protected void LinkButton2_Click(object sender, EventArgs e)
{
FormsAuthentication.SignOut();

SSORequest ssoRequest = new SSORequest();

ssoRequest.IASID = ”02”;
ssoRequest.TimeStamp = DateTime.Now.ToString(”yyyy-MM-dd HH:mm”);
ssoRequest.AppUrl = Request.Url.ToString();

Authentication.CreateAppToken(ssoRequest);

PostService ps = new PostService();

//認證中心(主站)地址
string EACUrl = ”http://localhost/MasterSite/Default.aspx”;
ps.Url = EACUrl;

ps.Add(”IASID”, ssoRequest.IASID);
ps.Add(”TimeStamp”, ssoRequest.TimeStamp);
ps.Add(”AppUrl”, ssoRequest.AppUrl);
ps.Add(”Authenticator”, ssoRequest.Authenticator);

ps.Add(”Logout”, ”true”);

ps.Post();
}

//返回主站
protected void LinkButton1_Click(object sender, EventArgs e)
{
if (Session[”CurrUserName”] != null)
{
Response.Redirect(”http://localhost/MasterSite/SiteList.aspx”);
}
}
}

對於tokent請求,tokent驗證,需要對它進行加密、解密。


其它代碼:

Authentication.cs
using System; 
using System.Data; 
using System.Configuration; 
using System.Web; 
using System.Web.Security; 
using System.Collections.Generic; 
using System.Text; 

/// <summary> 
/// 安全驗證類 
/// </summary> 
public class Authentication 

static readonly string cookieName = ”EACToken”; 
static readonly string hashSplitter = ”|”; 

public Authentication() 



public static string GetAppKey(int appID) 

//string cmdText = @”select * from ”; 
return string.Empty; 


public static string GetAppKey() 

return ”22362E7A9285DD53A0BBC2932F9733C505DC04EDBFE00D70”; 


public static string GetAppIV() 

return ”1E7FA9231E7FA923”; 


/// <summary> 
/// 取得加密服務 
/// </summary> 
/// <returns></returns> 
static CryptoService GetCryptoService() 

string key = GetAppKey(); 
string IV = GetAppIV(); 

CryptoService cs = new CryptoService(key, IV); 
return cs; 


/// <summary> 
/// 創建各分站發往認證中心的 Token 
/// </summary> 
/// <param name=”ssoRequest”></param> 
/// <returns></returns> 
public static bool CreateAppToken(SSORequest ssoRequest) 

string OriginalAuthenticator = ssoRequest.IASID + ssoRequest.TimeStamp + ssoRequest.AppUrl; 
string AuthenticatorDigest = CryptoHelper.ComputeHashString(OriginalAuthenticator);
string sToEncrypt = OriginalAuthenticator + AuthenticatorDigest; 
byte[] bToEncrypt = CryptoHelper.ConvertStringToByteArray(sToEncrypt); 

CryptoService cs = GetCryptoService(); 

byte[] encrypted; 

if (cs.Encrypt(bToEncrypt, out encrypted)) 

ssoRequest.Authenticator = CryptoHelper.ToBase64String(encrypted); 

return true; 

else 

return false; 




/// <summary> 
/// 驗證從各分站發送過來的 Token 
/// </summary> 
/// <param name=”ssoRequest”></param> 
/// <returns></returns> 
public static bool ValidateAppToken(SSORequest ssoRequest) 

string Authenticator = ssoRequest.Authenticator; 

string OriginalAuthenticator = ssoRequest.IASID + ssoRequest.TimeStamp + ssoRequest.AppUrl; 
string AuthenticatorDigest = CryptoHelper.ComputeHashString(OriginalAuthenticator);
string sToEncrypt = OriginalAuthenticator + AuthenticatorDigest; 
byte[] bToEncrypt = CryptoHelper.ConvertStringToByteArray(sToEncrypt); 

CryptoService cs = GetCryptoService(); 
byte[] encrypted; 

if (cs.Encrypt(bToEncrypt, out encrypted)) 

return Authenticator == CryptoHelper.ToBase64String(encrypted); 

else 

return false; 




/// <summary> 
/// 創建認證中心發往各分站的 Token 
/// </summary> 
/// <param name=”ssoRequest”></param> 
/// <returns></returns> 
public static bool CreateEACToken(SSORequest ssoRequest) 

string OriginalAuthenticator = ssoRequest.UserAccount + ssoRequest.IASID + ssoRequest.TimeStamp + ssoRequest.AppUrl; 
string AuthenticatorDigest = CryptoHelper.ComputeHashString(OriginalAuthenticator);
string sToEncrypt = OriginalAuthenticator + AuthenticatorDigest; 
byte[] bToEncrypt = CryptoHelper.ConvertStringToByteArray(sToEncrypt); 

CryptoService cs = GetCryptoService(); 
byte[] encrypted; 

if (cs.Encrypt(bToEncrypt, out encrypted)) 

ssoRequest.Authenticator = CryptoHelper.ToBase64String(encrypted); 

return true; 

else 

return false; 




/// <summary> 
/// 驗證從認證中心發送過來的 Token 
/// </summary> 
/// <param name=”ssoRequest”></param> 
/// <returns></returns> 
public static bool ValidateEACToken(SSORequest ssoRequest) 

string Authenticator = ssoRequest.Authenticator; 

string OriginalAuthenticator = ssoRequest.UserAccount + ssoRequest.IASID + ssoRequest.TimeStamp + ssoRequest.AppUrl; 
string AuthenticatorDigest = CryptoHelper.ComputeHashString(OriginalAuthenticator);
string sToEncrypt = OriginalAuthenticator + AuthenticatorDigest; 
byte[] bToEncrypt = CryptoHelper.ConvertStringToByteArray(sToEncrypt); 

string EncryCurrentAuthenticator = string.Empty; 
CryptoService cs = GetCryptoService(); 
byte[] encrypted; 

if (cs.Encrypt(bToEncrypt, out encrypted)) 

EncryCurrentAuthenticator = CryptoHelper.ToBase64String(encrypted); 

return Authenticator == EncryCurrentAuthenticator; 

else 

return false; 




/// <summary> 
/// 創建 EAC 認證中心的 Cookie 
/// </summary> 
/// <param name=”userAccount”></param> 
/// <param name=”timeStamp”></param> 
/// <param name=”expireTime”></param> 
/// <param name=”cookieValue”></param> 
/// <returns></returns> 
public static bool CreatEACCookie(string userAccount, string timeStamp, string expireTime) 

string plainText = ”UserAccount=” + userAccount + ”;TimeStamp=” + timeStamp + ”;ExpireTime=” + expireTime; 
plainText += hashSplitter + CryptoHelper.ComputeHashString(plainText); 

CryptoService cs = GetCryptoService(); 
byte[] encrypted; 

if (cs.Encrypt(CryptoHelper.ConvertStringToByteArray(plainText), out encrypted)) 

string cookieValue = CryptoHelper.ToBase64String(encrypted); 
SetCookie(cookieValue); 

return true; 

else 

return false; 



/// <summary> 
/// 驗證 EAC 認證中心的 Cookie,驗證通過時獲取用戶登錄賬號 
/// </summary> 
/// <param name=”userAccount”>輸出用戶登錄賬號</param> 
/// <returns></returns> 
public static bool ValidateEACCookie(out string userAccount) 

userAccount = string.Empty; 
try 


string cookieValue = GetCookie().Value; 
byte[] toDecrypt = CryptoHelper.FromBase64String(cookieValue); 
CryptoService cs = GetCryptoService(); 

string decrypted = string.Empty; 
if (cs.Decrypt(toDecrypt, out decrypted)) 


string[] arrTemp = decrypted.Split(Convert.ToChar(hashSplitter)); 
string plainText = arrTemp[0]; 
string hashedText = arrTemp[1]; 

userAccount = plainText.Split(Convert.ToChar(”;”))[0].Split(Convert.ToChar(”=”))[1]; 

return hashedText.Replace(”\0”, string.Empty) == CryptoHelper.ComputeHashString(plainText); 


else 

return false; 


catch (Exception e) 

return false; 




public static void Logout() 

HttpContext.Current.Response.Cookies[cookieName].Expires = DateTime.Parse(”1900-1-1”); 
HttpContext.Current.Response.Cookies[cookieName].Path = ”/”; 


private static void SetCookie(string cookieValue) 

HttpContext.Current.Response.Cookies[cookieName].Value = cookieValue; 
HttpContext.Current.Response.Cookies[cookieName].Expires = DateTime.Now.AddHours(24); 
HttpContext.Current.Response.Cookies[cookieName].Path = ”/”; 


private static HttpCookie GetCookie() 

HttpCookie cookie = HttpContext.Current.Request.Cookies[”EACToken”]; 
return cookie; 


using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Collections.Generic;
using System.Text;

/// <summary>
/// 安全驗證類
/// </summary>
public class Authentication
{
static readonly string cookieName = ”EACToken”;
static readonly string hashSplitter = ”|”;

public Authentication()
{
}

public static string GetAppKey(int appID)
{
//string cmdText = @”select * from ”;
return string.Empty;
}

public static string GetAppKey()
{
return ”22362E7A9285DD53A0BBC2932F9733C505DC04EDBFE00D70”;
}

public static string GetAppIV()
{
return ”1E7FA9231E7FA923”;
}

/// <summary>
/// 取得加密服務
/// </summary>
/// <returns></returns>
static CryptoService GetCryptoService()
{
string key = GetAppKey();
string IV = GetAppIV();

CryptoService cs = new CryptoService(key, IV);
return cs;
}

/// <summary>
/// 創建各分站發往認證中心的 Token
/// </summary>
/// <param name=”ssoRequest”></param>
/// <returns></returns>
public static bool CreateAppToken(SSORequest ssoRequest)
{
string OriginalAuthenticator = ssoRequest.IASID + ssoRequest.TimeStamp + ssoRequest.AppUrl;
string AuthenticatorDigest = CryptoHelper.ComputeHashString(OriginalAuthenticator);
string sToEncrypt = OriginalAuthenticator + AuthenticatorDigest;
byte[] bToEncrypt = CryptoHelper.ConvertStringToByteArray(sToEncrypt);

CryptoService cs = GetCryptoService();

byte[] encrypted;

if (cs.Encrypt(bToEncrypt, out encrypted))
{
ssoRequest.Authenticator = CryptoHelper.ToBase64String(encrypted);

return true;
}
else
{
return false;
}
}


/// <summary>
/// 驗證從各分站發送過來的 Token
/// </summary>
/// <param name=”ssoRequest”></param>
/// <returns></returns>
public static bool ValidateAppToken(SSORequest ssoRequest)
{
string Authenticator = ssoRequest.Authenticator;

string OriginalAuthenticator = ssoRequest.IASID + ssoRequest.TimeStamp + ssoRequest.AppUrl;
string AuthenticatorDigest = CryptoHelper.ComputeHashString(OriginalAuthenticator);
string sToEncrypt = OriginalAuthenticator + AuthenticatorDigest;
byte[] bToEncrypt = CryptoHelper.ConvertStringToByteArray(sToEncrypt);

CryptoService cs = GetCryptoService();
byte[] encrypted;

if (cs.Encrypt(bToEncrypt, out encrypted))
{
return Authenticator == CryptoHelper.ToBase64String(encrypted);
}
else
{
return false;
}
}


/// <summary>
/// 創建認證中心發往各分站的 Token
/// </summary>
/// <param name=”ssoRequest”></param>
/// <returns></returns>
public static bool CreateEACToken(SSORequest ssoRequest)
{
string OriginalAuthenticator = ssoRequest.UserAccount + ssoRequest.IASID + ssoRequest.TimeStamp + ssoRequest.AppUrl;
string AuthenticatorDigest = CryptoHelper.ComputeHashString(OriginalAuthenticator);
string sToEncrypt = OriginalAuthenticator + AuthenticatorDigest;
byte[] bToEncrypt = CryptoHelper.ConvertStringToByteArray(sToEncrypt);

CryptoService cs = GetCryptoService();
byte[] encrypted;

if (cs.Encrypt(bToEncrypt, out encrypted))
{
ssoRequest.Authenticator = CryptoHelper.ToBase64String(encrypted);

return true;
}
else
{
return false;
}
}


/// <summary>
/// 驗證從認證中心發送過來的 Token
/// </summary>
/// <param name=”ssoRequest”></param>
/// <returns></returns>
public static bool ValidateEACToken(SSORequest ssoRequest)
{
string Authenticator = ssoRequest.Authenticator;

string OriginalAuthenticator = ssoRequest.UserAccount + ssoRequest.IASID + ssoRequest.TimeStamp + ssoRequest.AppUrl;
string AuthenticatorDigest = CryptoHelper.ComputeHashString(OriginalAuthenticator);
string sToEncrypt = OriginalAuthenticator + AuthenticatorDigest;
byte[] bToEncrypt = CryptoHelper.ConvertStringToByteArray(sToEncrypt);

string EncryCurrentAuthenticator = string.Empty;
CryptoService cs = GetCryptoService();
byte[] encrypted;

if (cs.Encrypt(bToEncrypt, out encrypted))
{
EncryCurrentAuthenticator = CryptoHelper.ToBase64String(encrypted);

return Authenticator == EncryCurrentAuthenticator;
}
else
{
return false;
}
}


/// <summary>
/// 創建 EAC 認證中心的 Cookie
/// </summary>
/// <param name=”userAccount”></param>
/// <param name=”timeStamp”></param>
/// <param name=”expireTime”></param>
/// <param name=”cookieValue”></param>
/// <returns></returns>
public static bool CreatEACCookie(string userAccount, string timeStamp, string expireTime)
{
string plainText = ”UserAccount=” + userAccount + ”;TimeStamp=” + timeStamp + ”;ExpireTime=” + expireTime;
plainText += hashSplitter + CryptoHelper.ComputeHashString(plainText);

CryptoService cs = GetCryptoService();
byte[] encrypted;

if (cs.Encrypt(CryptoHelper.ConvertStringToByteArray(plainText), out encrypted))
{
string cookieValue = CryptoHelper.ToBase64String(encrypted);
SetCookie(cookieValue);

return true;
}
else
{
return false;
}
}

/// <summary>
/// 驗證 EAC 認證中心的 Cookie,驗證通過時獲取用戶登錄賬號
/// </summary>
/// <param name=”userAccount”>輸出用戶登錄賬號</param>
/// <returns></returns>
public static bool ValidateEACCookie(out string userAccount)
{
userAccount = string.Empty;
try
{

string cookieValue = GetCookie().Value;
byte[] toDecrypt = CryptoHelper.FromBase64String(cookieValue);
CryptoService cs = GetCryptoService();

string decrypted = string.Empty;
if (cs.Decrypt(toDecrypt, out decrypted))
{

string[] arrTemp = decrypted.Split(Convert.ToChar(hashSplitter));
string plainText = arrTemp[0];
string hashedText = arrTemp[1];

userAccount = plainText.Split(Convert.ToChar(”;”))[0].Split(Convert.ToChar(”=”))[1];

return hashedText.Replace(”\0”, string.Empty) == CryptoHelper.ComputeHashString(plainText);

}
else
{
return false;
}
}
catch (Exception e)
{
return false;
}
}


public static void Logout()
{
HttpContext.Current.Response.Cookies[cookieName].Expires = DateTime.Parse(”1900-1-1”);
HttpContext.Current.Response.Cookies[cookieName].Path = ”/”;
}

private static void SetCookie(string cookieValue)
{
HttpContext.Current.Response.Cookies[cookieName].Value = cookieValue;
HttpContext.Current.Response.Cookies[cookieName].Expires = DateTime.Now.AddHours(24);
HttpContext.Current.Response.Cookies[cookieName].Path = ”/”;
}

private static HttpCookie GetCookie()
{
HttpCookie cookie = HttpContext.Current.Request.Cookies[”EACToken”];
return cookie;
}
}


CryptoHelper.cs

using System; 
using System.Collections.Generic; 
using System.Text; 
using System.Security.Cryptography; 

public class CryptoHelper 

/// <summary> 
/// 復合 Hash:string --> byte[] --> hashed byte[] --> base64 string 
/// </summary> 
/// <param name=”s”></param> 
/// <returns></returns> 
public static string ComputeHashString(string s) 

return ToBase64String(ComputeHash(ConvertStringToByteArray(s))); 



public static byte[] ComputeHash(byte[] buf) 

//return ((HashAlgorithm)CryptoConfig.CreateFromName(”SHA1”)).ComputeHash(buf);
return SHA1.Create().ComputeHash(buf); 



/// <summary> 
/// //System.Convert.ToBase64String 
/// </summary> 
/// <param name=”buf”></param> 
/// <returns></returns> 
public static string ToBase64String(byte[] buf) 

return System.Convert.ToBase64String(buf); 



public static byte[] FromBase64String(string s) 

return System.Convert.FromBase64String(s); 


/// <summary> 
/// //Encoding.UTF8.GetBytes(s) 
/// </summary> 
/// <param name=”s”></param> 
/// <returns></returns> 
public static byte[] ConvertStringToByteArray(String s) 

return Encoding.UTF8.GetBytes(s);//gb2312 



public static string ConvertByteArrayToString(byte[] buf) 

//return System.Text.Encoding.GetEncoding(”utf-8”).GetString(buf); 

return Encoding.UTF8.GetString(buf); 



/// <summary> 
/// 字節數組轉換為十六進制字符串 
/// </summary> 
/// <param name=”buf”></param> 
/// <returns></returns> 
public static string ByteArrayToHexString(byte[] buf) 

StringBuilder sb = new StringBuilder(); 
for (int i = 0; i < buf.Length; i++) 

sb.Append(buf[i].ToString(”X”).Length == 2 ? buf[i].ToString(”X”) : ”0” + buf[i].ToString(”X”)); 

return sb.ToString(); 


/// <summary> 
/// 十六進制字符串轉換為字節數組 
/// </summary> 
/// <param name=”s”></param> 
/// <returns></returns> 
public static byte[] HexStringToByteArray(string s) 

Byte[] buf = new byte[s.Length / 2]; 
for (int i = 0; i < buf.Length; i++) 

buf[i] = (byte)(Char2Hex(s.Substring(i * 2, 1)) * 0x10 + Char2Hex(s.Substring(i * 2 + 1, 1))); 

return buf; 



private static byte Char2Hex(string chr) 

switch (chr) 

case ”0”: 
return 0x00; 
case ”1”: 
return 0x01; 
case ”2”: 
return 0x02; 
case ”3”: 
return 0x03; 
case ”4”: 
return 0x04; 
case ”5”: 
return 0x05; 
case ”6”: 
return 0x06; 
case ”7”: 
return 0x07; 
case ”8”: 
return 0x08; 
case ”9”: 
return 0x09; 
case ”A”: 
return 0x0a; 
case ”B”: 
return 0x0b; 
case ”C”: 
return 0x0c; 
case ”D”: 
return 0x0d; 
case ”E”: 
return 0x0e; 
case ”F”: 
return 0x0f; 

return 0x00; 


using System;
using System.Collections.Generic;
using System.Text;
using System.Security.Cryptography;

public class CryptoHelper
{
/// <summary>
/// 復合 Hash:string --> byte[] --> hashed byte[] --> base64 string
/// </summary>
/// <param name=”s”></param>
/// <returns></returns>
public static string ComputeHashString(string s)
{
return ToBase64String(ComputeHash(ConvertStringToByteArray(s)));
}


public static byte[] ComputeHash(byte[] buf)
{
//return ((HashAlgorithm)CryptoConfig.CreateFromName(”SHA1”)).ComputeHash(buf);
return SHA1.Create().ComputeHash(buf);

}

/// <summary>
/// //System.Convert.ToBase64String
/// </summary>
/// <param name=”buf”></param>
/// <returns></returns>
public static string ToBase64String(byte[] buf)
{
return System.Convert.ToBase64String(buf);
}


public static byte[] FromBase64String(string s)
{
return System.Convert.FromBase64String(s);
}

/// <summary>
/// //Encoding.UTF8.GetBytes(s)
/// </summary>
/// <param name=”s”></param>
/// <returns></returns>
public static byte[] ConvertStringToByteArray(String s)
{
return Encoding.UTF8.GetBytes(s);//gb2312
}


public static string ConvertByteArrayToString(byte[] buf)
{
//return System.Text.Encoding.GetEncoding(”utf-8”).GetString(buf);

return Encoding.UTF8.GetString(buf);
}


/// <summary>
/// 字節數組轉換為十六進制字符串
/// </summary>
/// <param name=”buf”></param>
/// <returns></returns>
public static string ByteArrayToHexString(byte[] buf)
{
StringBuilder sb = new StringBuilder();
for (int i = 0; i < buf.Length; i++)
{
sb.Append(buf[i].ToString(”X”).Length == 2 ? buf[i].ToString(”X”) : ”0” + buf[i].ToString(”X”));
}
return sb.ToString();
}

/// <summary>
/// 十六進制字符串轉換為字節數組
/// </summary>
/// <param name=”s”></param>
/// <returns></returns>
public static byte[] HexStringToByteArray(string s)
{
Byte[] buf = new byte[s.Length / 2];
for (int i = 0; i < buf.Length; i++)
{
buf[i] = (byte)(Char2Hex(s.Substring(i * 2, 1)) * 0x10 + Char2Hex(s.Substring(i * 2 + 1, 1)));
}
return buf;
}


private static byte Char2Hex(string chr)
{
switch (chr)
{
case ”0”:
return 0x00;
case ”1”:
return 0x01;
case ”2”:
return 0x02;
case ”3”:
return 0x03;
case ”4”:
return 0x04;
case ”5”:
return 0x05;
case ”6”:
return 0x06;
case ”7”:
return 0x07;
case ”8”:
return 0x08;
case ”9”:
return 0x09;
case ”A”:
return 0x0a;
case ”B”:
return 0x0b;
case ”C”:
return 0x0c;
case ”D”:
return 0x0d;
case ”E”:
return 0x0e;
case ”F”:
return 0x0f;
}
return 0x00;
}
}


CryptoService.cs

using System; 
using System.Data; 
using System.Configuration; 
using System.Web; 
using System.Web.Security; 
using System.Web.UI; 
using System.Web.UI.WebControls; 
using System.Web.UI.WebControls.WebParts; 
using System.Web.UI.HtmlControls; 
using System.Text; 
using System.Security.Cryptography; 
using System.IO; 

public class CryptoService 

/// <summary> 
/// 加密的密鑰 
/// </summary> 
string sKey = ”22362E7A9285DD53A0BBC2932F9733C505DC04EDBFE00D70”; 
string sIV = ”1E7FA9231E7FA923”; 

byte[] byteKey; 
byte[] byteIV; 

/// <summary> 
/// 加密向量 
/// </summary> 
static byte[] bIV ={ 1, 2, 3, 4, 5, 6, 7, 8 }; 

public CryptoService() 
{ } 

public CryptoService(string key, string IV) 

sKey = key; 
sIV = IV; 

byteKey = CryptoHelper.HexStringToByteArray(sKey); 
byteIV = CryptoHelper.HexStringToByteArray(sIV); 




/// <summary> 
/// 將明文加密,返回密文 
/// </summary> 
/// <param name=”Data”>要加密的字串</param> 
/// <returns></returns> 
public byte[] Encrypt(string Data) 

try 

byte[] ret; 

using (MemoryStream mStream = new MemoryStream()) 
using (CryptoStream cStream = new CryptoStream(mStream, 
new TripleDESCryptoServiceProvider().CreateEncryptor(byteKey, byteIV), 
CryptoStreamMode.Write)) 


byte[] toEncrypt = new ASCIIEncoding().GetBytes(Data); 

// Write the byte array to the crypto stream and flush it. 
cStream.Write(toEncrypt, 0, toEncrypt.Length); 
cStream.FlushFinalBlock(); 

// Get an array of bytes from the 
// MemoryStream that holds the 
// encrypted data. 
ret = mStream.ToArray(); 



return ret; 

catch (CryptographicException e) 

//Console.WriteLine(”A Cryptographic error occurred: {0}”, e.Message); 
return null; 





/// <summary> 
/// 將明文加密,返回密文 
/// </summary> 
/// <param name=”toEncrypt”>明文</param> 
/// <param name=”encrypted”>密文</param> 
/// <returns></returns> 
public bool Encrypt(byte[] toEncrypt, out byte[] encrypted) 

encrypted = null; 
try 

// Create a new MemoryStream using the passed 
// array of encrypted data. 
// Create a CryptoStream using the MemoryStream 
// and the passed key and initialization vector (IV). 
using (MemoryStream mStream = new MemoryStream()) 
using (CryptoStream cStream = new CryptoStream(mStream, 
new TripleDESCryptoServiceProvider().CreateEncryptor(byteKey, byteIV), 
CryptoStreamMode.Write)) 


// Write the byte array to the crypto stream and flush it. 
cStream.Write(toEncrypt, 0, toEncrypt.Length); 
cStream.FlushFinalBlock(); 

// Get an array of bytes from the 
// MemoryStream that holds the 
// encrypted data. 
encrypted = mStream.ToArray(); 


return true; 

catch (CryptographicException e) 

//Console.WriteLine(”A Cryptographic error occurred: {0}”, e.Message); 
return false; 






/// <summary> 
/// 將明文加密,返回 Base64 字符串 
/// </summary> 
/// <param name=”Data”></param> 
/// <returns></returns> 
public string EncryptToString(string Data) 

try 

string base64String = string.Empty; 

using (MemoryStream mStream = new MemoryStream()) 
using (CryptoStream cStream = new CryptoStream(mStream, 
new TripleDESCryptoServiceProvider().CreateEncryptor(byteKey, byteIV), 
CryptoStreamMode.Write)) 


byte[] toEncrypt = new ASCIIEncoding().GetBytes(Data); 

cStream.Write(toEncrypt, 0, toEncrypt.Length); 
cStream.FlushFinalBlock(); 

byte[] ret = mStream.ToArray(); 

base64String = Convert.ToBase64String(ret); 


return base64String; 

catch (CryptographicException e) 

return null; 





/// <summary> 
/// 將密文解密,返回明文 
/// </summary> 
/// <param name=”Data”>密文</param> 
/// <returns>明文</returns> 
public bool Decrypt(byte[] Data, out string decrypted) 

decrypted = string.Empty; 
try 


using (MemoryStream msDecrypt = new MemoryStream(Data)) 
using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, 
new TripleDESCryptoServiceProvider().CreateDecryptor(byteKey, byteIV), 
CryptoStreamMode.Read)) 


byte[] fromEncrypt = new byte[Data.Length]; 

// Read the decrypted data out of the crypto stream 
// and place it into the temporary buffer. 
csDecrypt.Read(fromEncrypt, 0, fromEncrypt.Length); 

decrypted = Encoding.UTF8.GetString(fromEncrypt);//new ASCIIEncoding().GetString(fromEncrypt); 

return true; 


catch (CryptographicException e) 

return false; 




using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Text;
using System.Security.Cryptography;
using System.IO;

public class CryptoService
{
/// <summary>
/// 加密的密鑰
/// </summary>
string sKey = ”22362E7A9285DD53A0BBC2932F9733C505DC04EDBFE00D70”;
string sIV = ”1E7FA9231E7FA923”;

byte[] byteKey;
byte[] byteIV;

/// <summary>
/// 加密向量
/// </summary>
static byte[] bIV ={ 1, 2, 3, 4, 5, 6, 7, 8 };

public CryptoService()
{ }

public CryptoService(string key, string IV)
{
sKey = key;
sIV = IV;

byteKey = CryptoHelper.HexStringToByteArray(sKey);
byteIV = CryptoHelper.HexStringToByteArray(sIV);
}

 

/// <summary>
/// 將明文加密,返回密文
/// </summary>
/// <param name=”Data”>要加密的字串</param>
/// <returns></returns>
public byte[] Encrypt(string Data)
{
try
{
byte[] ret;

using (MemoryStream mStream = new MemoryStream())
using (CryptoStream cStream = new CryptoStream(mStream,
new TripleDESCryptoServiceProvider().CreateEncryptor(byteKey, byteIV),
CryptoStreamMode.Write))
{

byte[] toEncrypt = new ASCIIEncoding().GetBytes(Data);

// Write the byte array to the crypto stream and flush it.
cStream.Write(toEncrypt, 0, toEncrypt.Length);
cStream.FlushFinalBlock();

// Get an array of bytes from the 
// MemoryStream that holds the 
// encrypted data.
ret = mStream.ToArray();

}

return ret;
}
catch (CryptographicException e)
{
//Console.WriteLine(”A Cryptographic error occurred: {0}”, e.Message);
return null;
}

}


/// <summary>
/// 將明文加密,返回密文
/// </summary>
/// <param name=”toEncrypt”>明文</param>
/// <param name=”encrypted”>密文</param>
/// <returns></returns>
public bool Encrypt(byte[] toEncrypt, out byte[] encrypted)
{
encrypted = null;
try
{
// Create a new MemoryStream using the passed 
// array of encrypted data.
// Create a CryptoStream using the MemoryStream 
// and the passed key and initialization vector (IV).
using (MemoryStream mStream = new MemoryStream())
using (CryptoStream cStream = new CryptoStream(mStream,
new TripleDESCryptoServiceProvider().CreateEncryptor(byteKey, byteIV),
CryptoStreamMode.Write))
{

// Write the byte array to the crypto stream and flush it.
cStream.Write(toEncrypt, 0, toEncrypt.Length);
cStream.FlushFinalBlock();

// Get an array of bytes from the 
// MemoryStream that holds the 
// encrypted data.
encrypted = mStream.ToArray();
}

return true;
}
catch (CryptographicException e)
{
//Console.WriteLine(”A Cryptographic error occurred: {0}”, e.Message);
return false;
}

}

 

/// <summary>
/// 將明文加密,返回 Base64 字符串
/// </summary>
/// <param name=”Data”></param>
/// <returns></returns>
public string EncryptToString(string Data)
{
try
{
string base64String = string.Empty;

using (MemoryStream mStream = new MemoryStream())
using (CryptoStream cStream = new CryptoStream(mStream,
new TripleDESCryptoServiceProvider().CreateEncryptor(byteKey, byteIV),
CryptoStreamMode.Write))
{

byte[] toEncrypt = new ASCIIEncoding().GetBytes(Data);

cStream.Write(toEncrypt, 0, toEncrypt.Length);
cStream.FlushFinalBlock();

byte[] ret = mStream.ToArray();

base64String = Convert.ToBase64String(ret);
}

return base64String;
}
catch (CryptographicException e)
{
return null;
}

}


/// <summary>
/// 將密文解密,返回明文
/// </summary>
/// <param name=”Data”>密文</param>
/// <returns>明文</returns>
public bool Decrypt(byte[] Data, out string decrypted)
{
decrypted = string.Empty;
try
{

using (MemoryStream msDecrypt = new MemoryStream(Data))
using (CryptoStream csDecrypt = new CryptoStream(msDecrypt,
new TripleDESCryptoServiceProvider().CreateDecryptor(byteKey, byteIV),
CryptoStreamMode.Read))
{

byte[] fromEncrypt = new byte[Data.Length];

// Read the decrypted data out of the crypto stream
// and place it into the temporary buffer.
csDecrypt.Read(fromEncrypt, 0, fromEncrypt.Length);

decrypted = Encoding.UTF8.GetString(fromEncrypt);//new ASCIIEncoding().GetString(fromEncrypt);

return true;
}
}
catch (CryptographicException e)
{
return false;
}
}

}

PostService.cs

using System; 
using System.Collections.Generic; 
using System.Text; 

public class PostService 

private System.Collections.Specialized.NameValueCollection Inputs = new System.Collections.Specialized.NameValueCollection(); 
public string Url = ””; 
public string Method = ”post”; 
public string FormName = ”form1”; 

/// <summary> 
/// 添加需要提交的名和值 
/// </summary> 
/// <param name=”name”></param> 
/// <param name=”value”></param> 
public void Add(string name, string value) 

Inputs.Add(name, value); 


/// <summary> 
/// 以輸出Html方式POST 
/// </summary> 
public void Post() 

System.Web.HttpContext.Current.Response.Clear(); 

string html = string.Empty; 

html += (”<html><head>”); 
html += (string.Format(”</head><body onload=\”document.{0}.submit()\”>”, FormName)); 
html += (string.Format(”<form name=\”{0}\” method=\”{1}\” action=\”{2}\” >”, FormName, Method, Url)); 
try 

for (int i = 0; i < Inputs.Keys.Count; i++) 

html += (string.Format(”<input name=\”{0}\” type=\”hidden\” value=\”{1}\”>”, Inputs.Keys[i], Inputs[Inputs.Keys[i]])); 

html += (”</form>”); 
html += (”</body></html>”); 

System.Web.HttpContext.Current.Response.Write(html); 
System.Web.HttpContext.Current.Response.End(); 

catch (Exception ee) 

// 



using System;
using System.Collections.Generic;
using System.Text;

public class PostService
{
private System.Collections.Specialized.NameValueCollection Inputs = new System.Collections.Specialized.NameValueCollection();
public string Url = ””;
public string Method = ”post”;
public string FormName = ”form1”;

/// <summary>
/// 添加需要提交的名和值
/// </summary>
/// <param name=”name”></param>
/// <param name=”value”></param>
public void Add(string name, string value)
{
Inputs.Add(name, value);
}

/// <summary>
/// 以輸出Html方式POST
/// </summary>
public void Post()
{
System.Web.HttpContext.Current.Response.Clear();

string html = string.Empty;

html += (”<html><head>”);
html += (string.Format(”</head><body onload=\”document.{0}.submit()\”>”, FormName));
html += (string.Format(”<form name=\”{0}\” method=\”{1}\” action=\”{2}\” >”, FormName, Method, Url));
try
{
for (int i = 0; i < Inputs.Keys.Count; i++)
{
html += (string.Format(”<input name=\”{0}\” type=\”hidden\” value=\”{1}\”>”, Inputs.Keys[i], Inputs[Inputs.Keys[i]]));
}
html += (”</form>”);
html += (”</body></html>”);

System.Web.HttpContext.Current.Response.Write(html);
System.Web.HttpContext.Current.Response.End();
}
catch (Exception ee)
{
//
}
}
}


SSORequest.cs

using System; 
using System.Data; 
using System.Configuration; 
using System.Web; 
using System.Web.Security; 
using System.Web.UI; 
using System.Web.UI.WebControls; 
using System.Web.UI.WebControls.WebParts; 
using System.Web.UI.HtmlControls; 

[Serializable] 
public class SSORequest : MarshalByRefObject 

public string IASID; //各獨立站點標識ID 
public string TimeStamp; //時間戳 
public string AppUrl; //各獨立站點的訪問地址 
public string Authenticator; //各獨立站點的 Token 

public string UserAccount; //賬號 
public string Password; //密碼 

public string IPAddress; //IP地址 

//為ssresponse對象做准備 
public string ErrorDescription = ”認證失敗”; //用戶認證通過,認證失敗,包數據格式不正確,數據校驗不正確 
public int Result = -1; 

public SSORequest() 





/// <summary> 
/// 獲取當前頁面上的SSORequest對象 
/// </summary> 
/// <param name=”CurrentPage”></param> 
/// <returns></returns> 
public static SSORequest GetRequest(Page CurrentPage) 

SSORequest request = new SSORequest(); 
request.IPAddress = CurrentPage.Request.UserHostAddress; 
request.IASID = CurrentPage.Request[”IASID”].ToString();// Request本身會Decode 
request.UserAccount = CurrentPage.Request[”UserAccount”].ToString();//this.Text 
request.Password = CurrentPage.Request[”Password”].ToString(); 
request.AppUrl = CurrentPage.Request[”AppUrl”].ToString(); 
request.Authenticator = CurrentPage.Request[”Authenticator”].ToString(); 
request.TimeStamp = CurrentPage.Request[”TimeStamp”].ToString(); 
return request; 


using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;

[Serializable]
public class SSORequest : MarshalByRefObject
{
public string IASID; //各獨立站點標識ID
public string TimeStamp; //時間戳
public string AppUrl; //各獨立站點的訪問地址
public string Authenticator; //各獨立站點的 Token

public string UserAccount; //賬號
public string Password; //密碼

public string IPAddress; //IP地址

//為ssresponse對象做准備
public string ErrorDescription = ”認證失敗”; //用戶認證通過,認證失敗,包數據格式不正確,數據校驗不正確
public int Result = -1;

public SSORequest()
{

}


/// <summary>
/// 獲取當前頁面上的SSORequest對象
/// </summary>
/// <param name=”CurrentPage”></param>
/// <returns></returns>
public static SSORequest GetRequest(Page CurrentPage)
{
SSORequest request = new SSORequest();
request.IPAddress = CurrentPage.Request.UserHostAddress;
request.IASID = CurrentPage.Request[”IASID”].ToString();// Request本身會Decode
request.UserAccount = CurrentPage.Request[”UserAccount”].ToString();//this.Text
request.Password = CurrentPage.Request[”Password”].ToString();
request.AppUrl = CurrentPage.Request[”AppUrl”].ToString();
request.Authenticator = CurrentPage.Request[”Authenticator”].ToString();
request.TimeStamp = CurrentPage.Request[”TimeStamp”].ToString();
return request;
}
}

配置web.config

<authentication mode=”Forms”> 
<forms name=”.AspxFormAuth” loginUrl=”Default.aspx” defaultUrl=”center.html” protection=”All” path=”/” timeout=”60”> 
</forms> 
</authentication> 
<authorization> 
<!--拒絕所有匿名用戶--> 
<deny users=”?”/> 
</authorization> 
<authentication mode=”Forms”>
<forms name=”.AspxFormAuth” loginUrl=”Default.aspx” defaultUrl=”center.html” protection=”All” path=”/” timeout=”60”>
</forms>
</authentication>
<authorization>
<!--拒絕所有匿名用戶-->
<deny users=”?”/>
</authorization>

最後效果如下:登錄總站後,各站點之間無需再登錄,可以互相訪問。

 

 


另外,注銷登錄後,訪問站點1 http://localhost/Site1/Default.aspx ,會自動跳轉到主站登錄頁面 http://localhost/MasterSite/Default.aspx ,同樣訪問站點2 http://localhost/Site2/Default.aspx 也會轉到主站登錄頁面。從主站登錄後,分別訪問站點1和站點2。

在IIS配置虛擬目錄MasterSite Site1 Site2,當然你也可以新建站點MasterSite Site1 Site2,修改hosts表
127.0.0.1 www.MasterSite.com

127.0.0.1 www.Site1.com

127.0.0.1 www.Site2.com

源代碼下載:http://download.csdn.net/source/1571879

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved