需求是這樣的,ASP.NET 的網站登入(Session)後,點選其他 ASP 的網站,也要變成登入狀態。

搜尋過有幾種作法:

  1. 透過資料庫,存入 Session_id 供查閱。
  2. 透過 ASP.NET2ASP POST 的方法,但要注意安全性。
  3. 將帳號加密,用 GET 方式附帶在 .asp 網址後方,ASP 端使用該加密字串丟到 ASP.NET 的 Web Service 解密並查詢該帳號是否正確,若正確則傳回 true,ASP 再設定 Session 登入狀態。

最後在條件考量下,決定使用第三種方法。
也許有更便捷的方式,有高手路過請提點一下囉 :D

* 以 ASP.NET (VB) 為例
* 加密方法參考來源:http://stackoverflow.com/questions/240713/how-can-i-encrypt-a-querystring-in-asp-net

1.
依照上方參考連結,增加一支加密方法

Imports Microsoft.VisualBasic
Imports System.Security.Cryptography
Imports System
Imports System.IO
Imports System.Xml
Imports System.Text

Public Class Encryption64
    Private key() As Byte = {}
    Private IV() As Byte = {&H12, &H34, &H56, &H78, &H90, &HAB, &HCD, &HEF}
    Public Function Decrypt(ByVal stringToDecrypt As String, _
        ByVal sEncryptionKey As String) As String
        Dim inputByteArray(stringToDecrypt.Length) As Byte
        Try
            key = System.Text.Encoding.UTF8.GetBytes(Left(sEncryptionKey, 8))
            Dim des As New DESCryptoServiceProvider()
            inputByteArray = Convert.FromBase64String(stringToDecrypt)
            Dim ms As New MemoryStream()
            Dim cs As New CryptoStream(ms, des.CreateDecryptor(key, IV), _
                CryptoStreamMode.Write)
            cs.Write(inputByteArray, 0, inputByteArray.Length)
            cs.FlushFinalBlock()
            Dim encoding As System.Text.Encoding = System.Text.Encoding.UTF8
            Return encoding.GetString(ms.ToArray())
        Catch e As Exception
            Return e.Message
        End Try
    End Function
    Public Function Encrypt(ByVal stringToEncrypt As String, _
        ByVal SEncryptionKey As String) As String
        Try
            key = System.Text.Encoding.UTF8.GetBytes(Left(SEncryptionKey, 8))
            Dim des As New DESCryptoServiceProvider()
            Dim inputByteArray() As Byte = Encoding.UTF8.GetBytes( _
                stringToEncrypt)
            Dim ms As New MemoryStream()
            Dim cs As New CryptoStream(ms, des.CreateEncryptor(key, IV), _
                CryptoStreamMode.Write)
            cs.Write(inputByteArray, 0, inputByteArray.Length)
            cs.FlushFinalBlock()
            Return Convert.ToBase64String(ms.ToArray())
        Catch e As Exception
            Return e.Message
        End Try
    End Function
End Class

2.
作一支 WebService:

<%@ WebService Language="VB" Class="Member" %>

Imports System.Web
Imports System.Web.Services
Imports System.Web.Services.Protocols
Imports System.Data
Imports System.Data.SqlClient
Imports System.Security.Cryptography
Imports System

' 若要允許使用 ASP.NET AJAX 從指令碼呼叫此 Web 服務,請取消註解下一行。
' <System.Web.Script.Services.ScriptService()> _
<WebService(Namespace:="http://localhost/")> _
<WebServiceBinding(ConformsTo:=WsiProfiles.BasicProfile1_1)> _
Public Class Member
    Inherits System.Web.Services.WebService

    <WebMethod(EnableSession:=True)> _
    Public Function LoginAccount(ByVal UserName As String) As String
        Try

            If UserName.Trim() = "" Then
                Return "登入失敗"
            End If

            Dim Acct As String = decryptQueryString(UserName)
            If ChkLogin(Acct) Then
                Return Acct
            Else
                Return "登入失敗"
            End If
        Catch ex As Exception
            Return "登入失敗"
        End Try
    End Function

    Private _key As String = "000000" '加密金鑰

    Public Function decryptQueryString(ByVal strQueryString As String) As String
        Dim oES As New Encryption64()
        Return oES.Decrypt(strQueryString, _key)
    End Function

    Public Function ChkLogin(ByVal UserName As String) As Boolean
          '連線至資料庫做查詢,若正確則返回 True,反之返回 False
    End Function

End Class

3.
加密的 Code 如下:(會用在 .aspx 頁面,某個目的 .asp 網址後方)

    Public Function encryptQueryString(ByVal strQueryString As String) As String
        Dim _key As String = "000000" '要跟上面用的金鑰一樣,比較好的方式是拔出來寫在一個地方啦.. 像可以放在 Web.config 中
        Dim oES As New Encryption64()
        Return oES.Encrypt(strQueryString, _key)
    End Function

然後使用 encryptQueryString 方法去產生加密過的帳號 ..
例如:

".asp?account=" & encryptQueryString(Session("帳號"))

4.
ASP 端收到加密過的帳號之後,連線到 ASP.NET 的 Web Service 中做帳號比對,若正確則輸出帳號,反之會吐出「登入錯誤」(可以依需求改成正確的話就取得登入 Session)。

<%
Set objHTTP = Server.CreateObject("MSXML2.XMLHTTP")
Set xmlDOC =Server.CreateObject("MSXML.DOMDocument")
strWebserviceURL = "http://放置WebService的host/WebService.asmx/LoginAccount"
strRequest = "username=" & Replace(Server.URLEncode(Request.QueryString("account")),"+","%2b")
objHTTP.Open "POST", strWebserviceURL, False
objHTTP.SetRequestHeader "Content-Type", "application/x-www-form-urlencoded"
objHTTP.Send strRequest
bOK = xmlDOC.load(objHTTP.responseXML)
if objHTTP.Status=200 then
xmlStr = xmlDOC.xml
xmlStr = Replace(xmlStr,"<","<",1,-1,1)
xmlStr = Replace(xmlStr,">",">",1,-1,1)
Response.Write xmlStr
else
Response.Write objHTTP.Status
end if
%>

其中要注意的,此種加密方法可能會產生+號,若不編碼一下,可能會造成錯誤「Base-64 字串中的無效字元」無法解析,因此利用 Replace(加密字串,"+","%2b") 將+號編碼再做傳遞。

4.
另外.. Web Service 這邊的 Web.config 中須加入:

    <webServices>
        <protocols>
            <add name="HttpGet"/>
            <add name="HttpPost"/>
        </protocols>
    </webServices>

讓非本機也可對 WebService 進行 HttpGet, HttpPost 方式的存取 ..

作法粗略如上,Code 尚未整理過.. 先作個解法紀錄囉 :P