Pass。若無效 → 導向 Service/Validate.aspx 攜帶 WebSite (回呼網址) 與 Security (單次驗證碼)。Security 的雜湊值。Security 雜湊值,通過則建立本地 Session,導向原請求頁面。protected void Session_Start(object sender, EventArgs e)
{
Session["UserID"] = 0;
Session["Pass"] = false;
Session["Security"] = "";
Session["ReturnUrl"] = "";
}
public class BasePage : Page
{
protected override void OnInit(EventArgs e)
{
base.OnInit(e);
if (!ValidateSession())
RedirectToAuthCenter();
}
private bool ValidateSession()
{
return (bool)Session["Pass"];
}
private void RedirectToAuthCenter()
{
// 產生單次驗證碼
string security = GenerateSecurityToken();
Session["Security"] = security;
Session["ReturnUrl"] = Request.RawUrl;
string authUrl = $"{AuthCenterUrl}/Validate.aspx?WebSite={Server.UrlEncode(AppUrl)}&Security={security}";
Response.Redirect(authUrl);
}
private string GenerateSecurityToken()
{
byte[] bytes = new byte[32];
using (var rng = System.Security.Cryptography.RandomNumberGenerator.Create())
rng.GetBytes(bytes);
return Convert.ToBase64String(bytes);
}
}
protected void Page_Load(object sender, EventArgs e)
{
string webSite = Request.QueryString["WebSite"];
string security = Request.QueryString["Security"];
Session["WebSite"] = webSite;
Session["Security"] = security; // 記錄原始驗證碼
if ((bool)Session["Pass"]) // 已登入
{
// 回傳雜湊後的 Security 給應用系統
string hashed = HashSecurity(security);
Response.Redirect($"{webSite}/Synchronous.aspx?Security={Server.UrlEncode(hashed)}");
}
else
{
Response.Redirect("Login.aspx");
}
}
private string HashSecurity(string input)
{
using (var sha = SHA512.Create())
{
byte[] hash = sha.ComputeHash(Encoding.Unicode.GetBytes(input));
return Convert.ToBase64String(hash);
}
}
protected void Page_Load(object sender, EventArgs e)
{
string returnedHash = Request.QueryString["Security"];
string original = (string)Session["Security"];
string expectedHash = HashSecurity(original);
if (returnedHash == expectedHash)
{
Session["Pass"] = true;
Session["UserID"] = 123; // 實際應從 Service 取得 UserID
string returnUrl = (string)Session["ReturnUrl"] ?? "Default.aspx";
Response.Redirect(returnUrl);
}
else
{
Response.Write("驗證失敗,可能遭竄改");
}
}
本文展示傳統 ASP.NET WebForms 時代的 SSO 手工實作邏輯,理解其原理有助於掌握現代標準協定的運作基礎。新專案強烈建議採用成熟的 Identity Provider 框架。