0

警告巨大投稿!

今年の初めに、次の質問を投稿しました: Orbeon Single sign-on to SAP Netweaver

他の作業を数か月行った後、もう一度見直して Orbeons のアドバイスを受け、Scala コードのデバッグを開始しました。

これはすべて、CE ソース形式の github (4.4CE) で行われました。私が見たファイルは Connection.scala https://github.com/orbeon/orbeon-forms/blob/master/src/main/scala/org/orbeon/oxf/util/Connection.scalaでした

最初に注意すべきことは、SAP Netweaver AS は Tomcat とは少し異なるセッション ID を処理するということです。sessionid と JSESSIONID が同じではありません。以前の投稿で既に示したように、セッション ID は JSESSIONID の短いバージョンであり、Tomcat ではこれらは同じです。

1.

メソッド sessionCookieFromIncoming (537) を見てみましょう: このメソッドで、Netweaver の最初の問題を見つけました。

 def requestedSessionIdMatches =
        Option(externalContext.getSession(false)) exists { session ⇒
            val requestedSessionId = externalContext.getRequest.getRequestedSessionId
            session.getId == requestedSessionId
        }

    val cookies = Option(nativeRequest.getCookies) getOrElse Array.empty[Cookie]
    if (requestedSessionIdMatches && cookies.nonEmpty) {

コード行:

 session.getId == requestedSessionId

これらは Netweaver では同じではありません (セッションで述べたように、JSESSIONID の短縮版です)。したがって、私の最初の修正案は次のとおりです (私は Scala プログラマーではないので、悪いコードを許してください):

 requestedSessionId contains session.getId 

デバッグのために、余分なコードを追加しました。デバッグを有効にしたことがないので、コンソールと同じ方法ですべてをダンプしました

val pairsToForward =
            for {
                cookie ← cookies
                if cookiesToForward.contains(cookie.getName)
            } yield
                cookie.getName + '=' + cookie.getValue
if (pairsToForward.nonEmpty) {

            // Multiple cookies in the header, separated with ";"
            val cookieHeaderValue = pairsToForward mkString "; "

            debug("forwarding cookies", Seq(
                "cookie" → cookieHeaderValue,
                "requested session id" → externalContext.getRequest.getRequestedSessionId))
              System.out.println("\nForwarding cookies " + "cookie " → cookieHeaderValue + "\nRequested session id " → externalContext.getRequest.getRequestedSessionId) 

            Some("cookie" → Array(cookieHeaderValue))

コンソール出力:

forwarding cookies (cookie , MYSAPSSO2=AjExMDAgABBwb3J0YWw6ZV9nYW1zbTAxiAAHZGVmYXVsdAEACUVfR0FNU00wMQIAAzAwMAMAA1NQRAQADDIwMTMxMTMwMjEyMAUABAAAAAgKAAlFX0dBTVNNMDH%2FAQYwggECBgkqhkiG9w0BBwKggfQwgfECAQExCzAJBgUrDgMCGgUAMAsGCSqGSIb3DQEHATGB0TCBzgIBATAkMBsxCzAJBgNVBAYTAk5MMQwwCgYDVQQDEwNTUEQCBQCEogh2MAkGBSsOAwIaBQCgXTAYBgkqhkiG9w0BCQMxCwYJKoZIhvcNAQcBMBwGCSqGSIb3DQEJBTEPFw0xMzExMzAyMTIwMzdaMCMGCSqGSIb3DQEJBDEWBBSryP8YWrWBPrzQBMyIypyfgGJT2TAJBgcqhkjOOAQDBC4wLAIUaMRLpG%2FxZYhzRIbyXzibMJJIGNcCFF4mmIESPh9o7kd7k46NNkr9ESLg; 
JSESSIONID=TCaFUY3kaqppP-IakFa0KDRgeOKqQgGScngA_SAP158n6gVEgGH7sItNCAOyfIFO)(
Requested session id ,TCaFUY3kaqppP-IakFa0KDRgeOKqQgGScngA_SAP158n6gVEgGH7sItNCAOyfIFO)

よさそうですね。SSO Cookie と適切な長さの JSESSIONID を取得しました

いくつかのデバッグ機能が実装されていますが、コンソールにダンプしました。コード 523 の行を参照してください。sessionID と着信セッション cookie (JSESSIONID) の違いは明らかです。

Debug sessie:(
new session,false)(
session id,TCaFUY3kaqppP-IakFa0KDRgeOKqQgGScngA_SAP)(
requested session id,TCaFUY3kaqppP-IakFa0KDRgeOKqQgGScngA_SAP158n6gVEgGH7sItNCAOyfIFO)(
session cookie name,JSESSIONID)(
incoming session cookies,TCaFUY3kaqppP-IakFa0KDRgeOKqQgGScngA_SAP158n6gVEgGH7sItNCAOyfIFO)(
incoming session headers,saplb_*=(J2EE7893620)7893650;     MYSAPSSO2=AjExMDAgABBwb3J0YWw6ZV9nYW1zbTAxiAAHZGVmYXVsdAEACUVfR0FNU00wMQIAAzAwMAMAA1NQRAQADDIwMTMxMTMwMjEyMAUABAAAAAgKAAlFX0dBTVNNMDH%2FAQYwggECBgkqhkiG9w0BBwKggfQwgfECAQExCzAJBgUrDgMCGgUAMAsGCSqGSIb3DQEHATGB0TCBzgIBATAkMBsxCzAJBgNVBAYTAk5MMQwwCgYDVQQDEwNTUEQCBQCEogh2MAkGBSsOAwIaBQCgXTAYBgkqhkiG9w0BCQMxCwYJKoZIhvcNAQcBMBwGCSqGSIb3DQEJBTEPFw0xMzExMzAyMTIwMzdaMCMGCSqGSIb3DQEJBDEWBBSryP8YWrWBPrzQBMyIypyfgGJT2TAJBgcqhkjOOAQDBC4wLAIUaMRLpG%2FxZYhzRIbyXzibMJJIGNcCFF4mmIESPh9o7kd7k46NNkr9ESLg; JSESSIONID=TCaFUY3kaqppP-IakFa0KDRgeOKqQgGScngA_SAP158n6gVEgGH7sItNCAOyfIFO)

2.

def buildConnectionHeaders (398) に戻ります。メソッドの最後で、Orbeon は Cookie を転送するための新しいヘッダーを作成します (これが正しいことを願っています)。

headersToForwardLowercase.toMap ++ explicitHeadersLowercase ++ newCookieHeader ++ tokenHeader

したがって、newCookieHeader には MYSAPSSO2 Cookie と有効な JSESSIONID が必要です。

このコードを追加したことを確認するには: Code from Orbeon (441):

 val newCookieHeader = credentials match {
        case None    ⇒ sessionCookieHeader(externalContext)
        case Some(_) ⇒ None
    }

この値を出力するために、次のコード行を追加しました。

var map = newCookieHeader.toMap
println(map("cookie")(0));

驚いたことに、コンソールに次のように表示されました。

JSESSIONID=TCaFUY3kaqppP-IakFa0KDRgeOKqQgGScngA_SAP

本当に私が望んでいたものではありません。では、これはどのようにして可能になるのでしょうか? こことその間で空想的なことは何も起こっていません。正しい値を示した印刷ステートメントが sessionCookieFromIncoming にあったため、値が sessionCookieFromGuess メソッドから来ていないことはわかっています。

3.

そこで私はハッキングを開始し、これを思いつきました (これも Scala コードの最良の例ではありません)。直前に、このコードを buildConnectionHeaders メソッドに追加しました

 // Don't forward headers for which a value is explicitly passed by the caller, so start with headersToForward
    // New cookie header, if present, overrides any existing cookies
    headersToForwardLowercase.toMap ++ explicitHeadersLowercase ++ newCookieHeader ++ tokenHeader

私のコード。Orbeon コードから断片を取り出して貼り付けました。次に、externalContext から JSESSIONID と MYSAPSSO2 を取得し、独自の newCookieHeader を作成します。

val requestOption = Option(externalContext.getRequest)
     val nativeRequestOption =
            requestOption flatMap
            (r ⇒ Option(r.getNativeRequest)) collect
            { case r: HttpServletRequest ⇒ r }

    val MYSAP =
                for {
                    nativeRequest ← nativeRequestOption.toList
                    cookies       ← Option(nativeRequest.getCookies).toList
                    cookie        ← cookies
                    if cookie.getName == "MYSAPSSO2"
                } yield
                    cookie.getValue

     val MYJS =
        for {
            nativeRequest ← nativeRequestOption.toList
            cookies       ← Option(nativeRequest.getCookies).toList
            cookie        ← cookies
            if cookie.getName == "JSESSIONID"
        } yield
            cookie.getValue


     var values = "MYSAPSSO2=" + MYSAP(0) + "; JSESSIONID=" + MYJS(0)

     def test : Option[(String, Array[String])]  = {
        Some("cookie" → Array(values))
    }

その後、この結果でテスト関数をコンソールにダンプします (新しくデプロイされたアプリであるため、id は異なります:

MYSAPSSO2=AjExMDAgABBwb3J0YWw6ZV9nYW1zbTAxiAAHZGVmYXVsdAEACUVfR0FNU00wMQIAAzAwMAMAA1NQRAQADDIwMTMxMTMwMjEyMAUABAAAAAgKAAlFX0dBTVNNMDH%2FAQYwggECBgkqhkiG9w0BBwKggfQwgfECAQExCzAJBgUrDgMCGgUAMAsGCSqGSIb3DQEHATGB0TCBzgIBATAkMBsxCzAJBgNVBAYTAk5MMQwwCgYDVQQDEwNTUEQCBQCEogh2MAkGBSsOAwIaBQCgXTAYBgkqhkiG9w0BCQMxCwYJKoZIhvcNAQcBMBwGCSqGSIb3DQEJBTEPFw0xMzExMzAyMTIwMzdaMCMGCSqGSIb3DQEJBDEWBBSryP8YWrWBPrzQBMyIypyfgGJT2TAJBgcqhkjOOAQDBC4wLAIUaMRLpG%2FxZYhzRIbyXzibMJJIGNcCFF4mmIESPh9o7kd7k46NNkr9ESLg; 
JSESSIONID=TCaFUY3kaqppP-IakFa0KDRgeOKqQgGScngA_SAP158n6gVEgGH7sItNCAOyfIFO

では、例 3 のコードが 2 では機能しないのに、なぜ機能するのかという疑問が生じます。Orbeon が、この問題の根本を追跡し、例 1 に示すような、より Netweaver に適した Cookie 転送方法を埋め込むのに役立つことを願っています。

4

0 に答える 0