M
mdh
I have an application written for mod_perl and Apache that needs to be
able to send some XML queries to a WebMethods server for access to
corporate systems. I have been attempting to use LWP to POST my XML
query to the target WebMethods server and find I only get 401s
(authorization errors) from the WebMethods server when it is
configured for username/password authentication. If credentials are
turned off on the WM server, I can get my expected XML replies.
Here's what I've tried:
1) WORKS: my basic PERL code hitting a local Apache server
(1.3.29 or 2.0.48) simulating WebMethods by sending
canned XML replies and requiring a username/password
credential in a known realm of "webMethods"
2) WORKS: the same PERL code hitting a real WebMethods
server that has authentication turned off
3) WORKS: using a browser to surf to a second real WebMethods
server with authentication turned on that requires:
username: myuser
password: mypasswd
realm: webMethods
4) BROKE: the same PERL code hitting that second WM server
using the credentials in bullet #3 using base64 encoding
of username and password
When the admin of the WebMethods server looks at his logs, he sees the
hit coming from LWP trying to perform the post as default/default (or
no authentication). Seems to indicate LWP doesn't recognize something
unique coming back from WebMethods when it wants credentials to be
supplied for a realm. Obvious things I HAVE confirmed are:
QUESTIONS:
1) has anyone else ever gotten a PERL script to post XML to a
WebMethods server with credentials using LWP?
2) is there a special agent string I can use that WebMethods
might like?
3) WebMethods provides a client.jar class library to write
Java scripts to access the server -- am I just going to
have to invoke a Java wrapper script and solve the problem
with more indirection (smile)?
Any insight would be greatly appreciated. THANKS
(e-mail address removed)
=========CODE SNIPPET BELOW==============
# IMPORTANT - documentation for the LWP::UserAgent::credentials
# function is slightly out of date regarding the net
# location parameter (the first one) - it must
# be of the form "host.domain.comort" even if you
# are using the default default 80 for http or 443
# for https
my $WEBMETHODSUSERID = 'myuser';
my $WEBMETHODSPASSWORD = 'mypasswd';
$WEBMETHODSUSERID = MIME::Base64::encode($WEBMETHODSUSERID);
$WEBMETHODSPASSWORD = MIME::Base64::encode($WEBMETHODSPASSWORD);
$WEBMETHODSUSERID =~ tr/\n//d; # strip trailing LF (???)
$WEBMETHODSPASSWORD =~ tr/\n//d;
my $WEBMETHODSREALM;
my $WEBMETHODSNETLOCATION;
my $WEBMETHODS_GETACCOUNTINFO_URL;
$WEBMETHODS_GETACCOUNTINFO_URL =
"http://192.168.29.41:5555/invoke/myServices.Transaction:CustomerLookup";
$WEBMETHODSNETLOCATION = "192.168.29.41:5555";
$WEBMETHODSREALM = "webMethods"; # has to match Realm name
# displayed in browser prompt
my $ua = LWP::UserAgent->new();
$ua->credentials($WEBMETHODSNETLOCATION, $WEBMETHODSREALM,
$WEBMETHODSUSERID, $WEBMETHODSPASSWORD);
$ua->agent('Mozilla/5.0');
my $req = HTTP::Request->new(POST => $WEBMETHODS_GETACCOUNTINFO_URL );
$req->content_type('text/xml');
$req->content($webmethodsQuery);
my $response = $ua->request($req);
#----------------------------------------------------------
# upon return, we either have:
# a) an error indicated by a response code other than 200
# b) a reply from WebMethods with <Response>xxx</Response>
# indicating success
# c) a reply from WebMethods with no <Response> but with
# <FailureReasonID> and other error tags
#-----------------------------------------------------------
if ($response->code() != 200) {
%result = ( errorcode => $response->code(),
errormsg => 'ERROR: unexpected reply from WebMethods
in GetAccountInfo' );
}
else {
# if we got a reply from WebMethods, it will either have
<Response>xxx</Response> data
# or the following XML values below the <MyAppMessage> level:
# <FailureReasonID>ERROR OCCURRED</FailureReasonID>
# <ErrorNumber>100</ErrorNumber>
# <ErrorMessage>Timeout</ErrorMessage>
my $entireXMLreply = $response->content(); # get the whole
convoluted XML structure
able to send some XML queries to a WebMethods server for access to
corporate systems. I have been attempting to use LWP to POST my XML
query to the target WebMethods server and find I only get 401s
(authorization errors) from the WebMethods server when it is
configured for username/password authentication. If credentials are
turned off on the WM server, I can get my expected XML replies.
Here's what I've tried:
1) WORKS: my basic PERL code hitting a local Apache server
(1.3.29 or 2.0.48) simulating WebMethods by sending
canned XML replies and requiring a username/password
credential in a known realm of "webMethods"
2) WORKS: the same PERL code hitting a real WebMethods
server that has authentication turned off
3) WORKS: using a browser to surf to a second real WebMethods
server with authentication turned on that requires:
username: myuser
password: mypasswd
realm: webMethods
4) BROKE: the same PERL code hitting that second WM server
using the credentials in bullet #3 using base64 encoding
of username and password
When the admin of the WebMethods server looks at his logs, he sees the
hit coming from LWP trying to perform the post as default/default (or
no authentication). Seems to indicate LWP doesn't recognize something
unique coming back from WebMethods when it wants credentials to be
supplied for a realm. Obvious things I HAVE confirmed are:
QUESTIONS:
1) has anyone else ever gotten a PERL script to post XML to a
WebMethods server with credentials using LWP?
2) is there a special agent string I can use that WebMethods
might like?
3) WebMethods provides a client.jar class library to write
Java scripts to access the server -- am I just going to
have to invoke a Java wrapper script and solve the problem
with more indirection (smile)?
Any insight would be greatly appreciated. THANKS
(e-mail address removed)
=========CODE SNIPPET BELOW==============
# IMPORTANT - documentation for the LWP::UserAgent::credentials
# function is slightly out of date regarding the net
# location parameter (the first one) - it must
# be of the form "host.domain.comort" even if you
# are using the default default 80 for http or 443
# for https
my $WEBMETHODSUSERID = 'myuser';
my $WEBMETHODSPASSWORD = 'mypasswd';
$WEBMETHODSUSERID = MIME::Base64::encode($WEBMETHODSUSERID);
$WEBMETHODSPASSWORD = MIME::Base64::encode($WEBMETHODSPASSWORD);
$WEBMETHODSUSERID =~ tr/\n//d; # strip trailing LF (???)
$WEBMETHODSPASSWORD =~ tr/\n//d;
my $WEBMETHODSREALM;
my $WEBMETHODSNETLOCATION;
my $WEBMETHODS_GETACCOUNTINFO_URL;
$WEBMETHODS_GETACCOUNTINFO_URL =
"http://192.168.29.41:5555/invoke/myServices.Transaction:CustomerLookup";
$WEBMETHODSNETLOCATION = "192.168.29.41:5555";
$WEBMETHODSREALM = "webMethods"; # has to match Realm name
# displayed in browser prompt
my $ua = LWP::UserAgent->new();
$ua->credentials($WEBMETHODSNETLOCATION, $WEBMETHODSREALM,
$WEBMETHODSUSERID, $WEBMETHODSPASSWORD);
$ua->agent('Mozilla/5.0');
my $req = HTTP::Request->new(POST => $WEBMETHODS_GETACCOUNTINFO_URL );
$req->content_type('text/xml');
$req->content($webmethodsQuery);
my $response = $ua->request($req);
#----------------------------------------------------------
# upon return, we either have:
# a) an error indicated by a response code other than 200
# b) a reply from WebMethods with <Response>xxx</Response>
# indicating success
# c) a reply from WebMethods with no <Response> but with
# <FailureReasonID> and other error tags
#-----------------------------------------------------------
if ($response->code() != 200) {
%result = ( errorcode => $response->code(),
errormsg => 'ERROR: unexpected reply from WebMethods
in GetAccountInfo' );
}
else {
# if we got a reply from WebMethods, it will either have
<Response>xxx</Response> data
# or the following XML values below the <MyAppMessage> level:
# <FailureReasonID>ERROR OCCURRED</FailureReasonID>
# <ErrorNumber>100</ErrorNumber>
# <ErrorMessage>Timeout</ErrorMessage>
my $entireXMLreply = $response->content(); # get the whole
convoluted XML structure