在openge中为amadeus webservice soap故障错误实现WS-security

时间:2016-02-15 08:48:24

标签: ws-security openedge

我正在尝试实施Amadeus Soap4网络服务。按照“实施”文档的建议创建了标题条目。但总是收到 12 |演示文稿| Soap消息头不正确错误。我在SOAP UI中尝试了生成的soap头,它可以在不对其进行任何更改的情况下工作。所以我正在寻找一种解决方案来解决应用程序中发生的问题。

2 个答案:

答案 0 :(得分: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-header放在一起的相当大的工作。最有可能是更有效的方法,你可以创建程序,以更加模块化的方式编码等等。但这实际上是有效的。不用说,你需要在下面做出很多改变。至少所有“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" ).

基本上应该是它。一个粗略的例子,但可能不是很漂亮...

答案 1 :(得分:0)

这是由于Amadeus的网络服务URL。请确保网络请求的网址与“add:To”标记的值相匹配,包括字母大小写。请求将以小写形式发送到地址,如 noded1 ,而不是 nodeD1

供参考,请参阅以下链接 Amadeus webservice address point Issue