2016-02-15 40 views
1

我試圖實現Amadeus Soap4 Web服務。根據實施文檔建議創建標題條目。但總是會收到 12 | Presentation | Soap消息頭不正確的錯誤。我已經嘗試過在SOAP UI中生成的SOAP頭,並且其工作原理沒有任何更改。所以我正在尋找解決方案來確定應用程序中發生的問題。在amadeus web服務SOAP故障錯誤的opensge中實現WS-security

+0

歡迎來到Stack Overflow!始終嘗試發佈代碼。即使錯了 - 這會表明你至少在嘗試着! – Jensd

回答

0

在OpenEdge中實現WS-Security時需要採取幾個步驟,因爲基本上沒有任何內置支持!

首先,您需要能夠創建密碼摘要。這裏有幾個缺陷可以避免(不同類型的字符集之間的字符轉換,處理二進制數據等)。

此過程將採用指向「Nonce」,日期和密碼的指針並返回「摘要」。

PROCEDURE generatePasswordDigest : 

    DEFINE INPUT PARAMETER mNonce  AS MEMPTR  NO-UNDO. 
    DEFINE INPUT PARAMETER pcCreated AS CHARACTER NO-UNDO. 
    DEFINE INPUT PARAMETER pcPassword AS CHARACTER NO-UNDO. 

    DEFINE OUTPUT PARAMETER pcHash  AS CHARACTER NO-UNDO. 

    DEFINE VARIABLE mBytes  AS MEMPTR  NO-UNDO. 
    DEFINE VARIABLE mSHA1   AS MEMPTR  NO-UNDO. 

    /* 
    Set size of mempointer, created + 36 because of all data that should fit. 
    */ 
    SET-SIZE(mBytes) = 36 + LENGTH(pcCreated). 

    /* Put the decoded nonce first */ 
    PUT-BYTES(mBytes, 1) = mNonce. 

    /* Add create time */ 
    PUT-STRING(mBytes, 1 + 16) = pcCreated. 

    /* Set SHA1 returns a 20 byte raw string. */ 
    SET-SIZE(mSHA1) = 20. 
    mSHA1 = SHA1-DIGEST(pcPassword). 

    /* Add password, SHA1-digested (so we need to put bytes instead of a string */ 
    PUT-BYTES(mBytes, 17 + LENGTH(pcCreated)) = mSHA1. 

    /* Create out-data in B64-encoded format */ 
    pcHash = STRING(BASE64-ENCODE(SHA1-DIGEST(mBytes))). 

    /* Clean up mempointers */ 
    SET-SIZE(mBytes) = 0. 
    SET-SIZE(mSHA1) = 0. 
    SET-SIZE(mNonce) = 0. 

END PROCEDURE. 

一旦你有了摘要,你將不得不做很大的工作來把SOAP標頭放在一起。最有可能的是這樣做的更有效的方式,你可以創建程序,以更加模塊化的方式編碼等等,但這實際上是有效的。不用說,你需要改變很多以下。至少所有的「XXXYYY」應該根據您的需求進行定製。

PROCEDURE setRequestSessionHeader : 
    DEFINE OUTPUT PARAMETER phHeader AS HANDLE. 
    DEFINE INPUT PARAMETER pcNamespace AS CHARACTER. 
    DEFINE INPUT PARAMETER pcLocalNS AS CHARACTER. 
    DEFINE OUTPUT PARAMETER plDeleteOnDone AS LOGICAL. 

    DEFINE VARIABLE hSoapHeaderEntryref1 AS HANDLE  NO-UNDO. 
    DEFINE VARIABLE hSoapHeaderEntryref2 AS HANDLE  NO-UNDO. 
    DEFINE VARIABLE hSoapHeaderEntryref3 AS HANDLE  NO-UNDO. 
    DEFINE VARIABLE hSoapHeaderEntryref4 AS HANDLE  NO-UNDO. 
    DEFINE VARIABLE hSoapHeaderEntryref5 AS HANDLE  NO-UNDO. 
    DEFINE VARIABLE hXDocument    AS HANDLE  NO-UNDO. 
    DEFINE VARIABLE hOASSecurity   AS HANDLE  NO-UNDO. 
    DEFINE VARIABLE hOASUsernameToken  AS HANDLE  NO-UNDO. 
    DEFINE VARIABLE hOASUserName   AS HANDLE  NO-UNDO. 
    DEFINE VARIABLE hOASPassword   AS HANDLE  NO-UNDO. 
    DEFINE VARIABLE hOASPasswordType  AS HANDLE  NO-UNDO. 
    DEFINE VARIABLE hOASNonce    AS HANDLE  NO-UNDO. 
    DEFINE VARIABLE hWSUCreated    AS HANDLE  NO-UNDO. 
    DEFINE VARIABLE hADDMessageID   AS HANDLE  NO-UNDO. 
    DEFINE VARIABLE hADDTo     AS HANDLE  NO-UNDO. 
    DEFINE VARIABLE hADDAction    AS HANDLE  NO-UNDO. 
    DEFINE VARIABLE hAMA_SecurityHostedUser AS HANDLE  NO-UNDO. 
    DEFINE VARIABLE hUserId     AS HANDLE  NO-UNDO. 
    DEFINE VARIABLE hTxt     AS HANDLE  NO-UNDO. 
    DEFINE VARIABLE hAttr     AS HANDLE  NO-UNDO. 
    DEFINE VARIABLE hRootNode    AS HANDLE  NO-UNDO. 

    /* Namespaces */ 
    DEFINE VARIABLE cNSAddressing   AS CHARACTER NO-UNDO. 
    DEFINE VARIABLE cNSSecurity    AS CHARACTER NO-UNDO. 
    DEFINE VARIABLE cNSSecurityUtils  AS CHARACTER NO-UNDO. 
    DEFINE VARIABLE cNSAmaSec    AS CHARACTER NO-UNDO. 
    DEFINE VARIABLE cMessageId    AS CHARACTER NO-UNDO. 
    DEFINE VARIABLE cUserName    AS CHARACTER NO-UNDO. 
    DEFINE VARIABLE cPasswordClear   AS CHARACTER NO-UNDO. 
    DEFINE VARIABLE cPasswordDigest   AS CHARACTER NO-UNDO. 
    DEFINE VARIABLE cCreated    AS CHARACTER NO-UNDO. 
    DEFINE VARIABLE cAction     AS CHARACTER NO-UNDO. 
    DEFINE VARIABLE cTo      AS CHARACTER NO-UNDO. 
    DEFINE VARIABLE cNonceB64    AS CHARACTER NO-UNDO. 
    DEFINE VARIABLE cOfficeId    AS CHARACTER NO-UNDO. 
    DEFINE VARIABLE mNonce     AS MEMPTR  NO-UNDO. 


    /* Changes might be needed here depending on what service is called */ 
    ASSIGN 
     cNSAddressing  = "http://www.w3.org/2005/08/addressing" 
     cNSSecurity  = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" 
     cNSSecurityUtils = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" 
     cNSAmaSec   = "http://xml.amadeus.com/2010/06/Security_v1" 
     cAction   = "http://webservices.amadeus.com/XXXYYY" 
     cTo    = "https://noded1.production.webservices.amadeus.com/XXXYYY". 

    /* Set your username, office ID and password */ 
    ASSIGN 
     cUserName   = "XXXYYY" 
     cOfficeId   = "XXXYYY" 
     cPasswordClear = "XXXYYY". 


    /* Delete header when done! */ 
    ASSIGN 
     plDeleteOnDone = TRUE. 


    CREATE SOAP-HEADER ghSoapHeader. 
    CREATE SOAP-HEADER-ENTRYREF hSoapHeaderEntryref1. 
    CREATE SOAP-HEADER-ENTRYREF hSoapHeaderEntryref2. 
    CREATE SOAP-HEADER-ENTRYREF hSoapHeaderEntryref3. 
    CREATE SOAP-HEADER-ENTRYREF hSoapHeaderEntryref4. 
    CREATE SOAP-HEADER-ENTRYREF hSoapHeaderEntryref5. 


    CREATE X-DOCUMENT hXDocument. 
    CREATE X-NODEREF hRootNode. 
    CREATE X-NODEREF hOASSecurity. 
    CREATE X-NODEREF hTxt. 
    CREATE X-NODEREF hOASUsernameToken. 
    CREATE X-NODEREF hOASPassword. 
    CREATE X-NODEREF hOASUserName. 
    CREATE X-NODEREF hOASNonce. 
    CREATE X-NODEREF hADDMessageID. 
    CREATE X-NODEREF hADDTo. 
    CREATE X-NODEREF hADDAction. 
    CREATE X-NODEREF hWSUCreated. 
    CREATE X-NODEREF hAMA_SecurityHostedUser. 
    CREATE X-NODEREF hUserId. 


    /* Not DATETIME-TZ! */ 
    DEFINE VARIABLE dtZuluNow AS DATETIME NO-UNDO. 

    /* Genereate a random key and base64-encode it */ 
    SET-SIZE(mNonce) = 16. 
    mNonce = GENERATE-RANDOM-KEY. 
    cNonceB64 = BASE64-ENCODE(mNonce). 

    /* Get time in UTC/GMT/ZULU/Timezone 0 */ 
    dtZuluNow = DATETIME-TZ(NOW,0). 

    /* Manipulate the date string to fit specs... */ 
    ASSIGN 
     cMessageId = LC(SUBSTRING(STRING(GENERATE-UUID), 8, 20)) 
     cCreated = STRING(dtZuluNow, "9999-99-99THH:MM:SS") + ":000Z". 

    /* Genereate digest */ 
    RUN generatePasswordDigest(mNonce, cCreated, cPasswordClear, OUTPUT cPasswordDigest). 


    /* Root node */ 
    hXDocument:CREATE-NODE-NAMESPACE(hRootNode, "", "root", "element"). 
    hXDocument:INSERT-BEFORE(hRootNode, ?). 

    /**** Addressing ****/ 
    /* MessageID */ 
    ghSoapHeader:ADD-HEADER-ENTRY(hSoapHeaderEntryref1). 
    hXDocument:CREATE-NODE-NAMESPACE(hADDMessageID, cNSAddressing, "MessageID", "ELEMENT"). 
    hRootNode:APPEND-CHILD(hAddMessageID). 
    hXDocument:CREATE-NODE(hTxt, "", "TEXT"). 
    hTxt:NODE-VALUE = cMessageId. 
    hADDMessageId:APPEND-CHILD(hTxt). 
    hSoapHeaderEntryref1:SET-NODE(hADDMessageID). 

    /* Action */ 
    ghSoapHeader:ADD-HEADER-ENTRY(hSoapHeaderEntryref2). 
    hXDocument:CREATE-NODE-NAMESPACE(hADDAction, cNSAddressing, "Action", "ELEMENT"). 
    hRootNode:APPEND-CHILD(hADDAction). 
    hXDocument:CREATE-NODE(hTxt, "", "TEXT"). 
    hTxt:NODE-VALUE = cAction. 
    hADDAction:APPEND-CHILD(hTxt). 
    hSoapHeaderEntryref2:SET-NODE(hADDAction). 

    /* To */ 
    ghSoapHeader:ADD-HEADER-ENTRY(hSoapHeaderEntryref3). 
    hXDocument:CREATE-NODE-NAMESPACE(hADDTo, cNSAddressing, "To", "ELEMENT"). 
    hRootNode:APPEND-CHILD(hADDTo). 
    hXDocument:CREATE-NODE(hTxt, "", "TEXT"). 
    hTxt:NODE-VALUE = cTo. 
    hADDTo:APPEND-CHILD(hTxt). 
    hSoapHeaderEntryref3:SET-NODE(hADDTo). 

    /**** Security ****/ 
    /* Root node */ 
    ghSoapHeader:ADD-HEADER-ENTRY(hSoapHeaderEntryref4). 
    hXDocument:CREATE-NODE-NAMESPACE(hOASSecurity, cNSSecurity, "Security", "ELEMENT"). 
    hRootNode:APPEND-CHILD(hOASSecurity). 

    /* UserNameToken node */ 
    hXDocument:CREATE-NODE-NAMESPACE(hOASUsernameToken, cNSSecurity, "UsernameToken", "ELEMENT"). 
    hOASUsernameToken:SET-ATTRIBUTE("Id", "UsernameToken-1"). 
    hOASSecurity:INSERT-BEFORE(hOASUsernameToken, ?). 

    /* Username */ 
    hXDocument:CREATE-NODE-NAMESPACE(hOASUserName, cNSSecurity, "Username", "ELEMENT"). 
    hRootNode:APPEND-CHILD(hOASUserName). 
    hXDocument:CREATE-NODE(hTxt, "", "TEXT"). 
    hTxt:NODE-VALUE = cUserName. 
    hOASUserName:APPEND-CHILD(hTxt). 
    hOASUsernameToken:APPEND-CHILD(hOASUserName). 

    /* Nonce */ 
    hXDocument:CREATE-NODE-NAMESPACE(hOASNonce, cNSSecurity, "Nonce", "ELEMENT"). 
    hOASNonce:SET-ATTRIBUTE("EncodingType", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary"). 
    hOASUsernameToken:APPEND-CHILD(hOASNonce). 
    hXDocument:CREATE-NODE(hTxt, "", "TEXT"). 
    hTxt:NODE-VALUE = cNonceB64. 
    hOASNonce:APPEND-CHILD(hTxt). 
    /* Password hash */ 
    hXDocument:CREATE-NODE-NAMESPACE(hOASPassword, cNSSecurity, "Password", "ELEMENT"). 
    hOASPassword:SET-ATTRIBUTE("Type", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordDigest"). 
    hOASUsernameToken:APPEND-CHILD(hOASPassword). 
    hXDocument:CREATE-NODE(hTxt, "", "TEXT"). 
    hTxt:NODE-VALUE = cPasswordDigest. 
    hOASPassword:APPEND-CHILD(hTxt). 

    /* Created - timestamp */ 
    hXDocument:CREATE-NODE-NAMESPACE(hWSUCreated, cNSSecurityUtils, "Created", "ELEMENT"). 
    hOASUsernameToken:APPEND-CHILD(hWSUCreated). 
    hXDocument:CREATE-NODE(hTxt, "", "TEXT"). 
    hTxt:NODE-VALUE = cCreated. 
    hWSUCreated:APPEND-CHILD(hTxt). 
    hSoapHeaderEntryref4:SET-NODE(hOASSecurity). 

    /**** AMA_SecurityHostedUser ****/ 
    /* Root node */ 
    ghSoapHeader:ADD-HEADER-ENTRY(hSoapHeaderEntryref5). 
    hXDocument:CREATE-NODE-NAMESPACE(hAMA_SecurityHostedUser, cNSAMASec, "AMA_SecurityHostedUser", "ELEMENT"). 
    hRootNode:APPEND-CHILD(hAMA_SecurityHostedUser). 


    /* UserID */ 
    hXDocument:CREATE-NODE-NAMESPACE(hUserID, cNSAMASec, "UserID", "ELEMENT"). 

    hUserID:SET-ATTRIBUTE("AgentDutyCode", "SU"). 
    hUserID:SET-ATTRIBUTE("RequestorType", "U"). 
    hUserID:SET-ATTRIBUTE("PseudoCityCode", cOfficeId). 
    hUserID:SET-ATTRIBUTE("POS_Type", "1"). 

    hAMA_SecurityHostedUser:APPEND-CHILD(hUserID). 
    hSoapHeaderEntryref5:SET-NODE(hAMA_SecurityHostedUser). 

    /* Output the header */ 
    phHeader = ghSoapHeader. 

    /* Cleanup */ 
    IF VALID-HANDLE(hOASSecurity) THEN 
     DELETE OBJECT hOASSecurity. 
    IF VALID-HANDLE(hOASUsernameToken) THEN 
     DELETE OBJECT hOASUsernameToken. 
    IF VALID-HANDLE(hOASUserName) THEN 
     DELETE OBJECT hOASUserName. 
    IF VALID-HANDLE(hOASPassword) THEN 
     DELETE OBJECT hOASPassword. 
    IF VALID-HANDLE(hADDMessageID) THEN 
     DELETE OBJECT hADDMessageID. 
    IF VALID-HANDLE(hOASNonce) THEN 
     DELETE OBJECT hOASNonce. 
    IF VALID-HANDLE(hTxt) THEN 
     DELETE OBJECT hTxt. 
    IF VALID-HANDLE(hADDTo) THEN 
     DELETE OBJECT hADDTo. 
    IF VALID-HANDLE(hWSUCreated) THEN 
     DELETE OBJECT hWSUCreated. 
    IF VALID-HANDLE(hADDAction) THEN 
     DELETE OBJECT hADDAction. 
    IF VALID-HANDLE(hXDocument) THEN 
     DELETE OBJECT hXDocument. 
    IF VALID-HANDLE(hRootNode) THEN 
     DELETE OBJECT hRootNode. 
    IF VALID-HANDLE(hSoapHeaderEntryRef1) THEN 
     DELETE OBJECT hSoapHeaderEntryRef1. 
    IF VALID-HANDLE(hSoapHeaderEntryRef2) THEN 
     DELETE OBJECT hSoapHeaderEntryRef2. 
    IF VALID-HANDLE(hSoapHeaderEntryRef3) THEN 
     DELETE OBJECT hSoapHeaderEntryRef3. 
    IF VALID-HANDLE(hSoapHeaderEntryRef4) THEN 
     DELETE OBJECT hSoapHeaderEntryRef4. 
    IF VALID-HANDLE(hSoapHeaderEntryRef5) THEN 
     DELETE OBJECT hSoapHeaderEntryRef5. 
    IF VALID-HANDLE(hAMA_SecurityHostedUser) THEN 
     DELETE OBJECT hAMA_SecurityHostedUser. 
    IF VALID-HANDLE(hUserId) THEN 
     DELETE OBJECT hUserId. 

END PROCEDURE. 

最後,調用實際的Web服務之前,您需要提供上述的過程,以便在飛行中產生標題:

XXXYYY-handle:SET-CALLBACK-PROCEDURE("REQUEST-HEADER", "setRequestSessionHeader"). 

本來應是。一個粗略的例子,但可能不是很漂亮...

+0

肥皂頭仍然會創建錯誤12 |演示|肥皂頭消息不正確。我假設問題是因爲s​​oapenv中有許多其他名稱空間:我無法以編程方式進行信封。當我使用創建的soapenv:頭時soapUI中帶有附加命名空間的程序,它工作正常。所以我認爲你可能在執行過程中遇到同樣的問題。任何想法如何解決這個問題..?是否有可能創建soapenv:信封在回調過程中與soap:body一起需要? –

+0

我發佈的代碼作品正在製作中。使用像Telerik Fiddler這樣的工具來調試您實際發送的內容! – Jensd

+0

這很可能是因爲你有名稱空間,「to」或「action」等錯誤。正確的情況也可能是一個問題。例如,我遇到了「nodeD1」與「noded1」的問題。 – Jensd

0

這是由於Amadeus的webservice網址。要確保Web請求的URL標記的值匹配「補充:要」,包括信case.the請求將被髮送到地址小寫像noded1,而不是nodeD1

僅供參考請參閱下面的鏈接 Amadeus webservice address point Issue