XSLT SOAP envelope wsse username and password with Parameters

How to best inject username and password into SOAP envelope...Looking for tips on below code. Not working yet. Thanks!

  1. GET FROM KVM
<KeyValueMapOperations name="KVM_E_GetProperties" mapIdentifier="CIB_KVM_E">
  <DisplayName>KVM_E_GetProperties</DisplayName>
  <Properties/>
  <ExclusiveCache>false</ExclusiveCache>
  <ExpiryTimeInSecs>300</ExpiryTimeInSecs>
  <Get assignTo="private.abs.v1.pmtusername">
    <Key>
      <Parameter>cib.abs.v1.pmtusername</Parameter>
    </Key>
  </Get>
  <Get assignTo="private.abs.v1.pmtpassword">
    <Key>
      <Parameter>cib.abs.v1.pmtpassword</Parameter>
    </Key>
  </Get>
  <Scope>environment</Scope>
</KeyValueMapOperations>

2.XSL POLICY

<XSL async="false" continueOnError="false" enabled="true" name="XSLTransform_LoanInquiryReq">
  <DisplayName>XSLTransform_LoanInquiryReq</DisplayName>
  <Properties/>
  <Source>sourceXmlContent</Source>
  <ResourceURL>xsl://Script-1.xslt</ResourceURL>
  <OutputVariable>LoanInquirySoapPayload</OutputVariable>
  <Parameter name="username" ref="private.abs.v1.pmtusername"/>
  <Parameter name="password" ref="private.abs.v1.pmtpassword"/>
  <Parameters ignoreUnresolvedVariables="true"/>
</XSL>

3.XSLT

<xsl:param name="username"/>
<xsl:param name="password"/>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:soap="com.pnc.pmt.acbsService">
  <soapenv:Header>
    <wsse:Security soapenv:mustUnderstand="1" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
      <wsse:UsernameToken wsu:Id="UsernameToken-20" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
        <wsse:Username><xsl:value-of select="$username"/></wsse:Username>
        <wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText"><xsl:value-of select="$password"/></wsse:Password>
      </wsse:UsernameToken>
    </wsse:Security>
  </soapenv:Header>
Solved Solved
1 5 651
1 ACCEPTED SOLUTION

I looked at your API Proxy... I have some feedback.

The XSL sheet should have xsl:param elements, and then you should reference those with xsl:value-of elements. It looks like this:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <!-- declare parameters provided by the XSL policy -->
  <xsl:param name="pmtusername" select="''"/>
  <xsl:param name="pmtpassword" select="''"/>
  <!-- this element is optional -->
  <xsl:output method="xml"
              indent="yes"
              omit-xml-declaration="yes"
              version="1.0" encoding="UTF-8" />
  <xsl:template match="/">
    <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:soap="com.pnc.pmt.acbsService">
      <soapenv:Header>
        <wsse:Security soapenv:mustUnderstand="1" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
          <wsse:UsernameToken wsu:Id="UsernameToken-20" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
            <wsse:Username><xsl:value-of select="$pmtusername"/></wsse:Username>
            <wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText"><xsl:value-of select="$pmtpassword"/></wsse:Password>
          </wsse:UsernameToken>
        </wsse:Security>
      </soapenv:Header>
      <soapenv:Body>
        <soap:getLoanInquiryRequest>
          <soap:IdentifierType>
            <!--Optional:-->
            <soap:demo><xsl:value-of select="/Root/demo"/></soap:demo>
            <soap:appID><xsl:value-of select="/Root/appID"/></soap:appID>
            <soap:messageID><xsl:value-of select="/Root/messageID"/></soap:messageID>
          </soap:IdentifierType>
          <soap:search><xsl:value-of select="/Root/search"/></soap:search>
          <!--Optional:-->
          <soap:queryType><xsl:value-of select="/Root/queryType"/></soap:queryType>
          <!--Optional:-->
          <soap:obligorNumber><xsl:value-of select="/Root/obligorNumber"/></soap:obligorNumber>
          <!--Optional:-->
          <soap:facilityNumber><xsl:value-of select="/Root/facilityNumber"/></soap:facilityNumber>
          <!--Optional:-->
          <soap:loanNumber><xsl:value-of select="/Root/loanNumber"/></soap:loanNumber>
          <!--Optional:-->
          <soap:dependency><xsl:value-of select="/Root/dependency"/></soap:dependency>
          <!--Optional:-->
          <soap:loans><xsl:value-of select="/Root/loans"/></soap:loans>
        </soap:getLoanInquiryRequest>
      </soapenv:Body>
    </soapenv:Envelope>
  </xsl:template>
</xsl:stylesheet>

The corresponding XSL POLICY tells Apigee what values to place into the parameters. I think you want something like this:

<XSL name="XSLTransform_LoanInquiryReq">
  <Source>sourceXmlContent</Source>
  <ResourceURL>xsl://Script-1.xslt</ResourceURL>
  <OutputVariable>LoanInquirySoapPayload</OutputVariable>
  <!-- provide parameters to the XSL sheet -->
  <Parameters ignoreUnresolvedVariables='false'>
    <Parameter name='pmtusername' ref='private.abs.v1.pmtusername'/>
    <Parameter name='pmtpassword' ref='private.abs.v1.pmtpassword'/>
  </Parameters>
</XSL>

You can see there I am declaring parameters for the XSL sheet, with specific names, and then referring (ref=) to context variables to use as the source of the value for those parameters. According to my reading of your proxy, those values come from the KVM-Get you have that runs previously.

When I use this combination I get ... something reasonable on output

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
                  xmlns:soap="com.pnc.pmt.acbsService">
   <soapenv:Header>
      <wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"
                     soapenv:mustUnderstand="1">
         <wsse:UsernameToken xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"
                             wsu:Id="UsernameToken-20">
            <wsse:Username>dino@example.com</wsse:Username>
            <wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">Secret123</wsse:Password>
         </wsse:UsernameToken>
      </wsse:Security>
   </soapenv:Header>
   <soapenv:Body>
      <soap:getLoanInquiryRequest>
         <soap:IdentifierType>
            <soap:demo/>
            <soap:appID/>
            <soap:messageID/>
         </soap:IdentifierType>
         <soap:search/>
         <soap:queryType/>
         <soap:obligorNumber/>
         <soap:facilityNumber/>
         <soap:loanNumber/>
         <soap:dependency/>
         <soap:loans/>
      </soap:getLoanInquiryRequest>
   </soapenv:Body>
</soapenv:Envelope>

View solution in original post

5 REPLIES 5

I feel your pain. I'm not in love with XSLT. I mean, I can use it, but... it always hurts a little. (Sometimes a lot)

Attached please find an API Proxy that injects a WSSE header into a SOAP message. This one uses PasswordDigest, not PasswordText, but same idea.

Maybe this will help you.

apiproxy-add-ws-sec-header-20210226.zip

Before:

<Envelope xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"
          xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"
          xmlns="http://schemas.xmlsoap.org/soap/envelope/">
  <Body>
    <GetProxy xmlns="">
      <ProxiesList/>
    </GetProxy>
  </Body>
</Envelope>

After

<soap:Envelope xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"
               xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"
               xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
   <soap:Header>
      <wsse:Security>
         <wsse:UsernameToken>
            <wsse:Username>user1234567</wsse:Username>
            <wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordDigest">5zH6WUyiPhkSJRDKs5srSzW2cpI=</wsse:Password>
            <wsse:Nonce>rrt-0c17d2ff51eab062b-b-ea-27447-18015146-1</wsse:Nonce>
            <wsu:Created>2017-12-20T18:19:58Z</wsu:Created>
         </wsse:UsernameToken>
      </wsse:Security>
   </soap:Header>
   <soap:Body>
      <GetProxy>
         <ProxiesList/>
      </GetProxy>
   </soap:Body>
</soap:Envelope>


But you should be able to tweak this proxy to do what you want.

Let me know.

Frank, was this helpful?

Hi Dino - I think so - I'm looking at proper placement in my existing proxy - I'm pulling from encrypted KVM - see attached - any help appreciated - thank you so muchapigeecicd-2021-03-02-13-20-4-588.zip

I looked at your API Proxy... I have some feedback.

The XSL sheet should have xsl:param elements, and then you should reference those with xsl:value-of elements. It looks like this:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <!-- declare parameters provided by the XSL policy -->
  <xsl:param name="pmtusername" select="''"/>
  <xsl:param name="pmtpassword" select="''"/>
  <!-- this element is optional -->
  <xsl:output method="xml"
              indent="yes"
              omit-xml-declaration="yes"
              version="1.0" encoding="UTF-8" />
  <xsl:template match="/">
    <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:soap="com.pnc.pmt.acbsService">
      <soapenv:Header>
        <wsse:Security soapenv:mustUnderstand="1" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
          <wsse:UsernameToken wsu:Id="UsernameToken-20" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
            <wsse:Username><xsl:value-of select="$pmtusername"/></wsse:Username>
            <wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText"><xsl:value-of select="$pmtpassword"/></wsse:Password>
          </wsse:UsernameToken>
        </wsse:Security>
      </soapenv:Header>
      <soapenv:Body>
        <soap:getLoanInquiryRequest>
          <soap:IdentifierType>
            <!--Optional:-->
            <soap:demo><xsl:value-of select="/Root/demo"/></soap:demo>
            <soap:appID><xsl:value-of select="/Root/appID"/></soap:appID>
            <soap:messageID><xsl:value-of select="/Root/messageID"/></soap:messageID>
          </soap:IdentifierType>
          <soap:search><xsl:value-of select="/Root/search"/></soap:search>
          <!--Optional:-->
          <soap:queryType><xsl:value-of select="/Root/queryType"/></soap:queryType>
          <!--Optional:-->
          <soap:obligorNumber><xsl:value-of select="/Root/obligorNumber"/></soap:obligorNumber>
          <!--Optional:-->
          <soap:facilityNumber><xsl:value-of select="/Root/facilityNumber"/></soap:facilityNumber>
          <!--Optional:-->
          <soap:loanNumber><xsl:value-of select="/Root/loanNumber"/></soap:loanNumber>
          <!--Optional:-->
          <soap:dependency><xsl:value-of select="/Root/dependency"/></soap:dependency>
          <!--Optional:-->
          <soap:loans><xsl:value-of select="/Root/loans"/></soap:loans>
        </soap:getLoanInquiryRequest>
      </soapenv:Body>
    </soapenv:Envelope>
  </xsl:template>
</xsl:stylesheet>

The corresponding XSL POLICY tells Apigee what values to place into the parameters. I think you want something like this:

<XSL name="XSLTransform_LoanInquiryReq">
  <Source>sourceXmlContent</Source>
  <ResourceURL>xsl://Script-1.xslt</ResourceURL>
  <OutputVariable>LoanInquirySoapPayload</OutputVariable>
  <!-- provide parameters to the XSL sheet -->
  <Parameters ignoreUnresolvedVariables='false'>
    <Parameter name='pmtusername' ref='private.abs.v1.pmtusername'/>
    <Parameter name='pmtpassword' ref='private.abs.v1.pmtpassword'/>
  </Parameters>
</XSL>

You can see there I am declaring parameters for the XSL sheet, with specific names, and then referring (ref=) to context variables to use as the source of the value for those parameters. According to my reading of your proxy, those values come from the KVM-Get you have that runs previously.

When I use this combination I get ... something reasonable on output

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
                  xmlns:soap="com.pnc.pmt.acbsService">
   <soapenv:Header>
      <wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"
                     soapenv:mustUnderstand="1">
         <wsse:UsernameToken xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"
                             wsu:Id="UsernameToken-20">
            <wsse:Username>dino@example.com</wsse:Username>
            <wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">Secret123</wsse:Password>
         </wsse:UsernameToken>
      </wsse:Security>
   </soapenv:Header>
   <soapenv:Body>
      <soap:getLoanInquiryRequest>
         <soap:IdentifierType>
            <soap:demo/>
            <soap:appID/>
            <soap:messageID/>
         </soap:IdentifierType>
         <soap:search/>
         <soap:queryType/>
         <soap:obligorNumber/>
         <soap:facilityNumber/>
         <soap:loanNumber/>
         <soap:dependency/>
         <soap:loans/>
      </soap:getLoanInquiryRequest>
   </soapenv:Body>
</soapenv:Envelope>

Dino you are THE man! 200 OK!!!!!!!!!! FIVE Stars!!!!