企業常有舊系統(JSP)與新系統(ASP.NET)並存,需實現單點登入(SSO)。直接序列化 Session 物件跨語言反序列化極其困難(物件結構、類加載器、序列化格式不兼容)。本文採用「資料庫中轉 Session 關鍵值」的替代方案。
iis_session。aspnetsessionid 參數。CREATE TABLE iis_session (
id VARCHAR(26) PRIMARY KEY, -- ASP.NET SessionID
userid INT, -- 用戶編號
power INT -- 權限編碼
);
private void WriteSession2DB(string sessionID, string sUID, string sPWR) {
string sql = "INSERT INTO iis_session (id, userid, power) VALUES (@sid, @uid, @pwr)";
using (SqlCommand cmd = new SqlCommand(sql, conn)) {
cmd.Parameters.AddWithValue("@sid", sessionID);
cmd.Parameters.AddWithValue("@uid", Convert.ToInt32(sUID));
cmd.Parameters.AddWithValue("@pwr", Convert.ToInt32(sPWR));
cmd.ExecuteNonQuery();
}
}
private void RemoveSession4DB() {
string sql = "DELETE FROM iis_session WHERE id = @sid";
using (SqlCommand cmd = new SqlCommand(sql, conn)) {
cmd.Parameters.AddWithValue("@sid", Session.SessionID);
cmd.ExecuteNonQuery();
}
}
private void Page_Load(object sender, EventArgs e) {
string url = "https://localhost/test.jsp?aspnetsessionid=" + Session.SessionID;
Response.Redirect(url, true);
}
<%@ page contentType="text/html;charset=gb2312" %>
<jsp:useBean id="db" scope="page" class="com.itbaby.bean.dbx.database"/>
<%
String aspNetSid = request.getParameter("aspnetsessionid");
db.dbConnOpen("itbaby_dbpool");
String sql = "SELECT userid, power FROM iis_session WHERE id = '" + aspNetSid + "'";
ResultSet rs = db.getRs(sql);
if (rs.next()) {
String uid = rs.getString(1);
String power = rs.getString(2);
session.setAttribute("userId", uid);
session.setAttribute("power", power);
// 可選:輸出驗證信息
out.println("ASP.Net Session Value UserID = " + uid);
out.println("ASP.Net Session Value Power = " + power);
}
rs.close();
db.dbConnClose();
%>
aspnetsessionid 僅作為一次性憑證,JSP 讀取後應立即建立自身 Session,不再依賴該參數。| 優點 | 缺點 |
|---|---|
| 實現簡單,跨語言無序列化難題 | 僅共享關鍵值,非完整 Session 物件 |
| 不暴露用戶敏感 ID(如 UserID)於 URL | 依賴資料庫可用性,引入單點故障 |
| 雙向登出易於同步 | Session 過期時間需雙端一致維護 |
若需共享完整 Session 狀態,可引入集中式 Session 存儲(Redis/Memcached),雙端統一讀寫序列化後的 Map/JSON,配合統一 SessionID 生成策略(如 UUID),實現真正的跨語言 Session 共享。