Using AGENT_INCLUDE.TXT to Add HTTP Header

This Q&A forum allows users to post and respond to "How Do I Do ....." questions. Please do not use to report (suspected) errors - you must use your regional help desk for this. The information contained in this forum has not been validated by LANSA and, as such, LANSA cannot guarantee the accuracy of the information.
Post Reply
caseywhite
Posts: 192
Joined: Thu May 26, 2016 1:17 am

Using AGENT_INCLUDE.TXT to Add HTTP Header

Post by caseywhite »

I am currently using the SOAP service with an AGENT_INCLUDE to include an AuthToken element into the BasicAuthenticationElement in the header as shown below.
org.apache.axis.message.SOAPHeaderElement elementHead = new org.apache.axis.message.SOAPHeaderElement("http://webservices.partsearch.com/Servi ... ityHeader/", "BasicAuthenticationHeader") ;
javax.xml.soap.SOAPElement elementAuthToken = elementHead.addChildElement("AuthToken") ;
elementAuthToken.addTextNode( user ) ;
stub.setHeader ( elementHead ) ;


A new version of this API has been created by an outside vendor whether they would like a Bearer token passed in the HTTP header instead of the message header.

I tried, unsuccessfully of course to add an HTTP header to the SOAP call using the SET PROPERTY method but confirmed that you can't do this. Even the documentation states that SET PROPERTY isn't a valid option.

My question is whether I can do what I want using the AGENT_INCLUDE.TXT so set an HTTP header variable.

Has anyone done this before?
René Houba
Posts: 220
Joined: Thu Nov 26, 2015 7:03 am

Using AGENT_INCLUDE.TXT to Add HTTP Header

Post by René Houba »

Hi Casey,

In this example, the SOAP Header contains two values in UsernameToken: Username and Password:
<soapenv:Header>
<wsse:Security soapenv:mustUnderstand="1" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/ ... xt-1.0.xsd">
<wsse:UsernameToken>
<wsse:Username>{{MID}}</wsse:Username>
<wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/ ... e:Password>
</wsse:UsernameToken>
</wsse:Security>
</soapenv:Header>

In a WSDL SOAP solution using Integrator, SOAP Header values can be filled using an AGENT_INCLUDE.TXT text file. When you compile the SOAP solution, this file should be there and the compile will implement this in the final .jar file:
AGENT_INCLUDE (1).JPG
AGENT_INCLUDE (1).JPG (28.47 KiB) Viewed 22016 times

The AGENT_INCLUDE.TXT contains the username and password:
*********************************************************************************************************************

/*
Add SOAP header session
*/
javax.xml.soap.SOAPFactory soapFactory = new org.apache.axis.soap.SOAPFactoryImpl () ;
javax.xml.soap.Name headerName = soapFactory.createName ( "Security", "wsse", "http://docs.oasis-open.org/wss/2004/01/ ... xt-1.0.xsd" ) ;
org.apache.axis.message.SOAPHeaderElement elementHead = new org.apache.axis.message.SOAPHeaderElement ( headerName ) ;
elementHead.addAttribute(soapFactory.createName("soapenv:mustUnderstand"), "1");
javax.xml.soap.SOAPElement elementUsernameToken = elementHead.addChildElement ( "UsernameToken" ) ;

javax.xml.soap.SOAPElement elementUsername = elementUsernameToken.addChildElement( "Username" ) ;
elementUsername.addTextNode ( user ) ;

javax.xml.soap.SOAPElement elementPassword = elementUsernameToken.addChildElement ( "Password" ) ;
elementPassword.addTextNode ("pLnpcwb3Jk0QO5ogqg9OlhEkwBbo0QP5zA7zIXEjsxXYmhvSJhVJYtcIYf0z7mphdDh2DSDg9iwUeLAHNLr81qB8jEcDrjE3fMiNAyv116KbzdtgZDw04rm9cKhRu+nNJqjkeABtF/SgCI42WOfM19WpVdcsZ0LaFTMxOHscZ3PV/EK+Pyhz4F+b5i+dmHl544BtEbAmL8yP8tFIZB+Ovi67wjccZyas+4ITNPuzD3KEzW8WTrk9NLScEpMYQXvlGU1wILj6b+v2lsXYMg9E2TT9r4Qpc0Pv6u2stx34Td47Ha9Q4ulfUgbd/9B2kwNFNme3dvi7t4Ywa3ml3Ui1Zg==") ;
elementPassword.addAttribute(soapFactory.createName("Type"), "http://docs.oasis-open.org/wss/2004/01/ ... sswordText");


stub.setHeader ( elementHead ) ;
*********************************************************************************************************************

The password in the example above is hardcoded in the AGENT_INCLUDE.TXT. The username is not. If a value is not filled hardcoded in the agent include, it needs to be filled in the LANSA program, as part of the service CALL, for example:

* Call remote service
#JSMXCMD := 'CALL USER(renetest11)'
Use Builtin(JSMX_COMMAND) With_Args(#JSMXHDLE1 #JSMXCMD) To_Get(#JSMXSTS #JSMXMSG)
Execute Subroutine(CHECK) With_Parms(#JSMXSTS #JSMXMSG)


This AGENT_INCLUDE.TXT does not contain hardcoded values:
*********************************************************************************************************************
/*
Add SOAP header session
*/
javax.xml.soap.SOAPFactory soapFactory = new org.apache.axis.soap.SOAPFactoryImpl () ;
javax.xml.soap.Name headerName = soapFactory.createName ( "Security", "wsse", "http://docs.oasis-open.org/wss/2004/01/ ... xt-1.0.xsd" ) ;
org.apache.axis.message.SOAPHeaderElement elementHead = new org.apache.axis.message.SOAPHeaderElement ( headerName ) ;
elementHead.addAttribute(soapFactory.createName("soapenv:mustUnderstand"), "1");
javax.xml.soap.SOAPElement elementUsernameToken = elementHead.addChildElement ( "UsernameToken" ) ;

javax.xml.soap.SOAPElement elementUsername = elementUsernameToken.addChildElement( "Username" ) ;
elementUsername.addTextNode ( user ) ;

javax.xml.soap.SOAPElement elementPassword = elementUsernameToken.addChildElement ( "Password" ) ;
elementPassword.addTextNode ( password ) ;

stub.setHeader ( elementHead ) ;
*********************************************************************************************************************

And could be filled by aLANSA program like:

* Call remote service

#JSMXCMD := 'CALL USER(renetest11) PASSWORD(pLnpcwb3Jk0QO5ogqg9OlhEkwBbo0QP5zA7zIXEjsxXYmhvSJhVJYtcIYf0z7mphdDh2DSDg9iwUeLAHNLr81qB8jEcDrjE3fMiNAyv116KbzdtgZDw04rm7cKhRu+nNJqjkeABtF/SgCI42WOfM19WpVdcsZ0LaFTMxOHscZ3PV/EK+Pyhz4F+b5i+dmHl544BtEbAmL8yP8tFIZB+Ovi67wjclTyas+4ITNPuzD3KEzW8WTrk9NLScEpXYZXvlGU1wILj6b+v2lsXYMg9E2TT9r4Qpc0Pv6u2stx34Td47Xt9Q4ulfUgbd/9B2kwNFNme3dvi7t4Ywa3ml3Ui1Zg==)'

Use Builtin(JSMX_COMMAND) With_Args(#JSMXHDLE1 #JSMXCMD) To_Get(#JSMXSTS #JSMXMSG)
Execute Subroutine(CHECK) With_Parms(#JSMXSTS #JSMXMSG)


The AGENT_INCLUDE.TXT can always be extended with other SOAP Header values, like:
*********************************************************************************************************************
/*
Add SOAP header session
*/
javax.xml.soap.SOAPFactory soapFactory = new org.apache.axis.soap.SOAPFactoryImpl () ;
javax.xml.soap.Name headerName = soapFactory.createName ( "SecuritySoapHeader", "vrm", "EurotaxGlass's/WebService/VehicleLookup/VRM" ) ;
org.apache.axis.message.SOAPHeaderElement elementHead = new org.apache.axis.message.SOAPHeaderElement ( headerName ) ;
// org.apache.axis.message.SOAPHeaderElement elementHead = new org.apache.axis.message.SOAPHeaderElement ( "SecuritySoapHeader" ) ;

javax.xml.soap.SOAPElement elementClientCode = elementHead.addChildElement ( "ClientCode" ) ;
elementClientCode.addTextNode ( "Demo" ) ;


javax.xml.soap.SOAPElement elementAccount = elementHead.addChildElement ( "AccountName" ) ;
elementAccount.addTextNode ( user ) ;

javax.xml.soap.SOAPElement elementPwd = elementHead.addChildElement ( "Password" ) ;
elementPwd.addTextNode ( password ) ;

stub.setHeader ( elementHead ) ;

*********************************************************************************************************************

Kind regards,
René
caseywhite
Posts: 192
Joined: Thu May 26, 2016 1:17 am

Re: Using AGENT_INCLUDE.TXT to Add HTTP Header

Post by caseywhite »

Hi Rene. We are currently using the AGENT_INCLUDE to set the SOAP Header. They issue is the API we want to call has been changed to use a Bearer token in the HTTP header. So the solution you posted won't work.

What I tried to do was access the MessageContext so that I could add a custom HTTP header to it as shown below. However, when I call getCurrentContext it is null, so I can't add the headers to it.

I have posed this question to LANSA support but haven't gotten an answer yet of why the MessageContext is null in the AGENT_INCLUDE.txt. Maybe what I want to do isn't possible but I am trying to get a firm answer of whether what I want to do is possible or not.

org.apache.axis.MessageContext msgContext = org.apache.axis.MessageContext.getCurrentContext();
if (msgContext != null)
{
java.util.Hashtable userHeaderTable = (java.util.Hashtable) msgContext.getProperty(org.apache.axis.transport.http.HTTPConstants.REQUEST_HEADERS);
}
userHeaderTable.put("Authorization", "Bearer MYBEARERTOKEN");
caseywhite
Posts: 192
Joined: Thu May 26, 2016 1:17 am

Re: Using AGENT_INCLUDE.TXT to Add HTTP Header

Post by caseywhite »

I got a response from LANSA support with an example someone used in the past to set an HTTP Header value. However, their example only worked for a statically set value. I was able to determine that it will work with a dynamically provided value if you also set the SOAP Header. Here is what will work. The dynamic value is passed in on the CALL to the SOAP API like CALL PASSWORD(XXXXXXX). The only thing you can't do is set the header name to "Authorization".

stub.setPassword ( null ) ;

org.apache.axis.message.SOAPHeaderElement elementHead2 = new org.apache.axis.message.SOAPHeaderElement("http://docs.oasis-open.org/wss/2004/01/ ... xt-1.0.xsd", "Security") ;
javax.xml.soap.SOAPElement elementAuthToken2 = elementHead2.addChildElement("Base64Assertion") ;
elementAuthToken2.addTextNode( password ) ;
stub.setHeader ( elementHead2 ) ;

// This only works if you also add the password to the SOAP Header as some type of header element as is done above.
String APIKey = "Bearer " + password;
org.apache.axis.utils.LockableHashtable headers = new org.apache.axis.utils.LockableHashtable();
headers.put("x-access-token", APIKey);
stub._setProperty ( org.apache.axis.transport.http.HTTPConstants.REQUEST_HEADERS, headers ) ;
Post Reply