« Honey Balsamic Vinaigrette | Main | Chief Leatherlips »

Using Apache Axis with Integrated Windows Security

I haven't seen a single place that describes everything that you need to do in order to use Apache Axis to access web services that are protected using IIS's Integrated Windows Authentication (or NTLM) scheme. Its not very hard to get the product to support it, but the documentation isn't all in one place.

In order for Axis to support Integrated Windows Authentication, you need to tell the Axis client to use a different class for HTTP communications. In Axis parlance, these classes are called Handlers, that is they are subclasses of Handler. By default, the Axis client uses the HTTPSender for its communications. The CommonsHTTPSender however is the one that supports Integrated Windows Authentication. The easiest way to use to instruct the Axis client to use this class for HTTP communications is to create a custom client-config.wsdd file. Here is a simple one that enables using the CommonsHTTPSender class for HTTP communication:


<?xml version="1.0" encoding="UTF-8"?>
<deployment name="commonsHTTPConfig"
xmlns="http://xml.apache.org/axis/wsdd/"
xmlns:java="http://xml.apache.org/axis/wsdd/providers/java">

<transport name="http" pivot="java:org.apache.axis.transport.http.CommonsHTTPSender" />
<transport name="local" pivot="java:org.apache.axis.transport.local.LocalSender" />
<transport name="java" pivot="java:org.apache.axis.transport.java.JavaSender" />

</deployment>

One easy way to make sure that Axis notices your configuration file is to store this file in the classpath at the location org/apache/axis/client. The client will find this configuration file dynamically at runtime. There are several other ways configure the Axis client that may be more appropriate to your situation.

Lastly, make sure your classpath includes Apache Jakarta Commons Http Client and Apache Jakarta Commons Codec. If you are using Apache Axis 1.3, you must use the 3.x series of Http Client.

Once you have done this, you should be able to use Apache Axis against web services that are protected by Integrated Windows Authentication.

Update: To answer Yuhua's question from below, specifing usernames and passwords is no different than any other Axis based webservice. For whatever generated class implements the Stub interface, you can call the setUsername(String) and setPassword(String) methods. The username component would consist of your domain name as well as your username, seperated by a backslash.

TrackBack

TrackBack URL for this entry:
http://people.etango.com/cgi-bin/mt-tb.cgi/754

Comments (37)

Yuhua Zhang:

Mark,

I would really appreciate if you can also give an example on how to specify username, password and domain and make the call in client Java code after enabling CommonsHTTPSender.

Yuhua from Houston

Jem:

Thanks Mark. This entry of yours was a great find.
Cheers
Jem

Thanks Jem, I am glad you found it useful.

Dean Miley:

Hey Mark

Which version of Axis does this relate to.

Cheers

Dean

Dean, I believe I tested that against Axis 1.2 and 1.3. --mark

Josh:

With browsers like IE and Firefox (properly configured), the information for session credentials can be picked up from the OS automatically and passed to the IIS server. Is there any way to imitate this behavior with the Axis client - rather than having to ask the user again for userid and password. Trying to get to a true SSO implementation.

Martin:

Mark,

great to see this. I tried to use it but currently the client still uses basic authentication despite the client-config below. I'm using axis 1.3 Any ideas what I'm doing wrong?

<?xml version="1.0" encoding="utf-8"?>
<deployment name="NTLMClientConfig"
xmlns="http://xml.apache.org/axis/wsdd/"
xmlns:java="http://xml.apache.org/axis/wsdd/providers/java">

<transport name="http"
pivot="java:org.apache.axis.transport.http.CommonsHTTPSender"/>
</deployment>

Martin,
I would make sure that you are specifing a DOMAINNAME\USERNAME as the parameter to setUsername() and that your client stub is using this wsdd file.

Martin:

Mark,

thanks a lot for your advice. The client didn't pick up the wsdd :-(. Now it works!

Great Martin, I am glad things worked out for you.

Wayne:

Will this type of configuration work on the server side as well. I am trying to use the HTTPCommons client on the server to replace the HTTP comms supplied by Axis 1.3. I have comms in another part of my application using the HTTP commons client an it seems to work much better than the Axis Http comms.
Any advice would be apprciated

there should be no reason why this can't work on the server. the client is the client no matter where it is.

Kathryn:

I was trying to use this but do I have it the right way round. I have a IIs .NET Webservice sending to an Axis server. How can I authenticate at the Axis server end.
Is the same way ?
I have tried setting up the client-config.wsdd and with HTTPCommonsSender and sending a message from one server with my test .NET webservice client to another server with the Axis server on it. If I use a domain user or a local user to send from the.NET webservice client it still works. I can see what looks like encrypted authentication (can't see though) when looking at the packets in Ethereal before the SOAP body goes through.
any ideas ?
From checking .NET/IIs authentication:-
When using Integrated authentication, you can send credentials over HTTP, because they are not sent in clear text.

Anonymous:

I was trying to use this but do I have it the right way round. I have a IIs .NET Webservice sending to an Axis server. How can I authenticate at the Axis server end.
Is the same way ?
I have tried setting up the client-config.wsdd and with HTTPCommonsSender and sending a message from one server with my test .NET webservice client to another server with the Axis server on it. If I use a domain user or a local user to send from the.NET webservice client it still works. I can see what looks like encrypted authentication (can't see though) when looking at the packets in Ethereal before the SOAP body goes through.
any ideas ?
From checking .NET/IIs authentication:-
When using Integrated authentication, you can send credentials over HTTP, because they are not sent in clear text.

This info saved me mucho time! Thanks!

Alon:

The web service I ise does not requires any credentials for access it, nevertheless I get:
org/apache/commons/httpclient/UsernamePasswordCredentials exception.
I am connecting through HTTPS and I setup the keystore.
Any ideas how should I overcome this problem?

Yuhua from Houston:

Mark,

It is me again. Recently my code was deployed to a different machine. On the surface, there is no difference between the original deployment (working) and new deployment. The Axis client under Tomcat tried to access the .NET web services that uses Windows NTLM authentication. However now I receive the following error on Axis client side:
+++++++++++++++++++++++
AxisFault
faultCode: {http://xml.apache.org/axis/}HTTP
faultSubcode:
faultString: (401)Unauthorized
faultActor:
faultNode:
faultDetail:
{}:return code: 401
......
......
{http://xml.apache.org/axis/}HttpErrorCode:401

(401)Unauthorized
at org.apache.axis.transport.http.CommonsHTTPSender.invoke(CommonsHTTPSender.java:218)
at org.apache.axis.strategies.InvocationStrategy.visit(InvocationStrategy.java:32)
at org.apache.axis.SimpleChain.doVisiting(SimpleChain.java:118)
at org.apache.axis.SimpleChain.invoke(SimpleChain.java:83)
at org.apache.axis.client.AxisClient.invoke(AxisClient.java:165)
at org.apache.axis.client.Call.invokeEngine(Call.java:2784)
at org.apache.axis.client.Call.invoke(Call.java:2767)
at org.apache.axis.client.Call.invoke(Call.java:2443)
at org.apache.axis.client.Call.invoke(Call.java:2366)
at org.apache.axis.client.Call.invoke(Call.java:1812)
at com.slb.sis.rr.sws.proxy.ProcessManagementService_BindingStub.getManualActivitiesInProject(ProcessManagementService_BindingStub.java:1714)
++++++++++++++++++++++
2007-01-18 17:15:31,094 [TP-Processor2] DEBUG org.apache.commons.httpclient.HttpMethodDirector: enter HttpMethodBase.processAuthenticationResponse(HttpState, HttpConnection)
2007-01-18 17:15:31,094 [TP-Processor2] DEBUG org.apache.commons.httpclient.auth.AuthChallengeProcessor: Using authentication scheme: ntlm
2007-01-18 17:15:31,094 [TP-Processor2] DEBUG org.apache.commons.httpclient.auth.AuthChallengeProcessor: Authorization challenge processed
2007-01-18 17:15:31,094 [TP-Processor2] DEBUG org.apache.commons.httpclient.HttpMethodDirector: Authentication scope: NTLM @hploandp1:8088
2007-01-18 17:15:31,094 [TP-Processor2] DEBUG org.apache.commons.httpclient.HttpMethodDirector: Credentials required
2007-01-18 17:15:31,094 [TP-Processor2] DEBUG org.apache.commons.httpclient.HttpMethodDirector: Credentials provider not available
2007-01-18 17:15:31,094 [TP-Processor2] INFO org.apache.commons.httpclient.HttpMethodDirector: Failure authenticating with NTLM @hploandp1:8088
+++++++++++++++++++++++++++

I have search online and saw suggestions of using latest Axis and commons-httpclient. I have changed to use Axis 1.4 and commons-httpclient 3.0.1. But that did not help. Can you help?

Tejas Desai [TypeKey Profile Page]:

Hi Mark,

I am running into same error as Yuhua from Houston. Was there any resolution to this issue.

I am calling .NET Web Service running under IIS with NT Authentication from a Java Application. I get the same authentication error.

help on resolving this issue is appreciated.

Thanks
Tejas

Sander Postma:

Regarding the last two posts, please double check:
1.
Make sure you do the soap call on the xxxStub class, and not another copy from ccLocator.getxxxSoap().
You can easily check if all ok by temp. adding a line String user = super.getUsername();
Put a breakpoint there and check if value ok.

2.
Make sure the username has the domain in domain\\username format. CommonsHTTPSender will not use NTLM authentication when there is no domain.

Tyson:

Thanks for the tip. I setup my Axis client the way you have recommended. When I try to run the client I get the following exception...

AxisFault
faultCode: Client
faultSubcode:
faultString: The SOAP request is invalid. The required node 'Envelope' is missing.
faultActor:
faultNode:
faultDetail:
{http://xml.apache.org/axis/}stackTrace:The SOAP request is invalid. The required node 'Envelope' is missing.
at org.apache.axis.message.SOAPFaultBuilder.createFault(SOAPFaultBuilder.java:222)
at org.apache.axis.message.SOAPFaultBuilder.endElement(SOAPFaultBuilder.java:129)
at org.apache.axis.encoding.DeserializationContext.endElement(DeserializationContext.java:1087)
at org.apache.crimson.parser.Parser2.maybeElement(Unknown Source)
at org.apache.crimson.parser.Parser2.content(Unknown Source)
at org.apache.crimson.parser.Parser2.maybeElement(Unknown Source)
at org.apache.crimson.parser.Parser2.content(Unknown Source)
at org.apache.crimson.parser.Parser2.maybeElement(Unknown Source)
at org.apache.crimson.parser.Parser2.parseInternal(Unknown Source)
at org.apache.crimson.parser.Parser2.parse(Unknown Source)
at org.apache.crimson.parser.XMLReaderImpl.parse(Unknown Source)
at javax.xml.parsers.SAXParser.parse(Unknown Source)
at org.apache.axis.encoding.DeserializationContext.parse(DeserializationContext.java:227)
at org.apache.axis.SOAPPart.getAsSOAPEnvelope(SOAPPart.java:696)
at org.apache.axis.Message.getSOAPEnvelope(Message.java:435)
at org.apache.axis.handlers.soap.MustUnderstandChecker.invoke(MustUnderstandChecker.java:62)
at org.apache.axis.client.AxisClient.invoke(AxisClient.java:206)
at org.apache.axis.client.Call.invokeEngine(Call.java:2784)
at org.apache.axis.client.Call.invoke(Call.java:2767)
at org.apache.axis.client.Call.invoke(Call.java:2443)
at org.apache.axis.client.Call.invoke(Call.java:2366)
at org.apache.axis.client.Call.invoke(Call.java:1812)
at com.stellent.www.DocInfo.DocInfoSoapStub.docInfoByName(DocInfoSoapStub.java:263)
at AxisDocInfoTest.main(AxisDocInfoTest.java:42)

{http://xml.apache.org/axis/}hostname:LPTTYSON

The SOAP request is invalid. The required node 'Envelope' is missing.
at org.apache.axis.message.SOAPFaultBuilder.createFault(SOAPFaultBuilder.java:222)
at org.apache.axis.message.SOAPFaultBuilder.endElement(SOAPFaultBuilder.java:129)
at org.apache.axis.encoding.DeserializationContext.endElement(DeserializationContext.java:1087)
at org.apache.crimson.parser.Parser2.maybeElement(Unknown Source)
at org.apache.crimson.parser.Parser2.content(Unknown Source)
at org.apache.crimson.parser.Parser2.maybeElement(Unknown Source)
at org.apache.crimson.parser.Parser2.content(Unknown Source)
at org.apache.crimson.parser.Parser2.maybeElement(Unknown Source)
at org.apache.crimson.parser.Parser2.parseInternal(Unknown Source)
at org.apache.crimson.parser.Parser2.parse(Unknown Source)
at org.apache.crimson.parser.XMLReaderImpl.parse(Unknown Source)
at javax.xml.parsers.SAXParser.parse(Unknown Source)
at org.apache.axis.encoding.DeserializationContext.parse(DeserializationContext.java:227)
at org.apache.axis.SOAPPart.getAsSOAPEnvelope(SOAPPart.java:696)
at org.apache.axis.Message.getSOAPEnvelope(Message.java:435)
at org.apache.axis.handlers.soap.MustUnderstandChecker.invoke(MustUnderstandChecker.java:62)
at org.apache.axis.client.AxisClient.invoke(AxisClient.java:206)
at org.apache.axis.client.Call.invokeEngine(Call.java:2784)
at org.apache.axis.client.Call.invoke(Call.java:2767)
at org.apache.axis.client.Call.invoke(Call.java:2443)
at org.apache.axis.client.Call.invoke(Call.java:2366)
at org.apache.axis.client.Call.invoke(Call.java:1812)
at com.stellent.www.DocInfo.DocInfoSoapStub.docInfoByName(DocInfoSoapStub.java:263)
at AxisDocInfoTest.main(AxisDocInfoTest.java:42)

If I set the transport class to HTTPSender in the client-config.wsdd file and point at a server that does not use NTLM security then my client runs without any problems. Any ideas?

Tejas Desai [TypeKey Profile Page]:

Hi Sander,

I tried the same by using stub class and set the UserName as "COMPANYCOR\TDD203", but after this I get NoEndPointException.

What could be causing this?

Does Axis suppose to give the current Logged UserID or do we always have to set the UserName by using stub.setUserName("COMPANYCOR\TDD203")?

Thanks for your response.
Tejas


Domenick Doran:

I'm having a similar problem as mentioned above, I'm attempting to call out to a web service hosted on Tomcat, redirected to Tomcat from IIS (we're using IIS simply for Integrated Windows Security in lieu of another Single Sign On product). I'm using commons-codec-1.3.jar, commons-httpclient-3.0.1.jar along with Axis 1.3.0. We've got IIS configured to work with both IWA and Basic. When we use Basic, it works fine. When we use IWA (by changing the client-config.wsdd file), I get the following stack trace:

(401)Unauthorized
at org.apache.axis.transport.http.CommonsHTTPSender.invoke(CommonsHTTPSender.java:218)
at org.apache.axis.strategies.InvocationStrategy.visit(InvocationStrategy.java:32)
at org.apache.axis.SimpleChain.doVisiting(SimpleChain.java:118)
at org.apache.axis.SimpleChain.invoke(SimpleChain.java:83)
at org.apache.axis.client.AxisClient.invoke(AxisClient.java:165)
at org.apache.axis.client.Call.invokeEngine(Call.java:2784)
at org.apache.axis.client.Call.invoke(Call.java:2767)
at org.apache.axis.client.Call.invoke(Call.java:2443)
at org.apache.axis.client.Call.invoke(Call.java:2366)
at org.apache.axis.client.Call.invoke(Call.java:1812)
at com.guidewire.pc.webservices.api.ILoginAPISoapBindingStub.login(ILoginAPISoapBindingStub.java:403)
at com.pc.integration.pc.external.AccountCreator.main(AccountCreator.java:58)

Anyone have any suggestions? I've been messing with this for days with no progress.

Greetings Everyone! I'm trying to give an attempt to understand and

solve the problem of accessing secured webservice under windows iis by

asking few questions.

1) There are request play back tools to identify how the request is

hitting the webservice under windows security zone? It might give some

clues as to how does the basic vs. IWA requests being received and

processed.

2) Can credential information be sent through SOAP headers to perform

customer authentication? There is a concept called composite web

services which allows to access the target web service (secured one)

through an intermediary web service (unsecured one / basic one). Is

there an option to explore this?

3) Okay when the web service is running in basic mode which I assume

that the authentication requirement is made as anonymous. I guess to

force the authentication, ACL on the webservice itself can be set like

this.














I dont have knowledge on windows, but if these questions are guiding to

get a resolution, you can share your experiences with me at

chandrasekhar.tondepu@gmail.com.

Wish you happy resolution & successful integration!


Steven Hines:

Mark,

First of all, thanks for the incredibly easy to read guide. I've been struggling through web services for a few weeks now and I think it's fair to say that "easy to read" cannot usually be used to describe most of the documentation out there.

I had a problem using Commons HttpClient with NTLMv2 which Apache admit here. I found my solution at Oakland Software - pricey, but cheaper than me buying a whole new head of hair... ;-)

Hope this helps anyone out there who's been scratching their heads.

Cullan:

You are the man! There is no way I could have figured this out without your article.

Thanks very much
Cullan

DT:

Does this apply to Axis 2.0 also?

Kapil:

I am trying to use axis to consume the .NET Web Services in java. The problem i am facing is that the time i restart my machine, the Web Service works fine for the first time. Subsequently there is error Access Denied(401)
Please help.
Thanks in advance
Kapil

Kapil:

I am trying to use axis to consume the .NET Web Services hosted on IIS in java.
If i turn on Basic Authentication, i am able to consume web services.
But when i turn on Integrated Windows Authentication; The problem i face is that the time i restart my machine, the Web Service works fine for the first time. Subsequently there is error Access Denied(401)
Please help.
Thanks in advance
Kapil

Santosh:

Hi Mark,

I am agree with your point that "I haven't seen a single place that describes everything that you need to do in order to use Apache Axis to access web services that are protected using IIS's Integrated Windows Authentication (or NTLM) scheme"

But sorry for that Again you have done same thing.
you have not describe it clearly.

please put example with it. that make more sense.

san:

Hi all,

I am trying to use axis1.2RC to consume the .NET Web Services hosted on IIS with Integrated Windows Authentication.
I have to set responseBean object in their service method like - objStub.updateStatus(responseBean);

i have tryied it in two different way to consume the .NET web service :

1. setting the UserName and Password in stub -

try
{
Booking responseBean = objBean.bookingResponse(response); // getting populate bean values

String url = "https://san.vie.ca/order/travel.asmx";
SampleOrderUpdateSoapStub objStub = new SampleOrderUpdateSoapStub();

objStub._setProperty(javax.xml.rpc.Stub.USERNAME_PROPERTY, "svc_san-verinf"); // also used "DOMAIN\\svc_san-verinf"
objStub._setProperty(javax.xml.rpc.Stub.PASSWORD_PROPERTY, "password123"); // i have also tested Call.USERNAME_PROPERTY and //Call.PASSWORD_PROPERTY not working
objStub._setProperty(javax.xml.rpc.Stub.ENDPOINT_ADDRESS_PROPERTY, url);

objStub.updateStatus(responseBean); // response Bean is assigned in Stub method updateStatus.
}

Without security setting it's working fine, no problem But when security enabled in IIS then below exception is thrown :
AxisFault
(401)Unauthorized
You are not authorized to view this page
You do not have permission to view this directory or page using the credentials that you supplied because your Web browser is sending a WWW-Authenticate header field that the Web server is not configured to accept.
------------------------------------
HTTP Error 401.2 - Unauthorized: Access is denied due to server configuration.Internet Information Services (IIS)


2. So, i tried this using HTTPClient it's working only to connect service but i have to populate the responseBean object in their service method like - objStub.updateStatus(responseBean). Here it's failure. 1st it's authenticate when using HTTPClient but when try to invoke Stub method then it's again throwing exception :
AxisFault
(401)Unauthorized
You are not authorized to view this page
You do not have permission to view this directory or page using the credentials that you supplied because your Web browser is sending a WWW-Authenticate header field that the Web server is not configured to accept.
------------------------------------
HTTP Error 401.2 - Unauthorized: Access is denied due to server configuration.Internet Information Services (IIS)

HTTPClient Code :

HttpClient httpClient = new HttpClient();
List authPrefs = new ArrayList(2);
authPrefs.add(AuthPolicy.NTLM);
String secProviderName = "com.sun.crypto.provider.SunJCE";
java.security.Provider secProvider = (java.security.Provider) Class.forName(secProviderName).newInstance();
Security.addProvider(secProvider);
//authPrefs.add(AuthPolicy.BASIC);

// This will exclude the NTLM authentication scheme

httpClient.getParams().setParameter(AuthPolicy.AUTH_SCHEME_PRIORITY, authPrefs);
Credentials credentials = new NTCredentials("svc_san-verinf", "password123", "ip address", "DOMAINNAME");

httpClient.getState().setCredentials(AuthScope.ANY, credentials);
HttpMethodBase method = new GetMethod("https://san.vie.ca/order/travel.asmx");

try {
method.setDoAuthentication(true);
int returnCode = httpClient.executeMethod(method);

} catch (HttpException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}

This code is working fine only to connect the service, however when i invoke their service method like - objStub.updateStatus(responseBean) after
....int returnCode = httpClient.executeMethod(method);

it gives (401)Unauthorized AND HTTP Error 401.2.

i am googling for this more than one week. Help me......

How to solve this problem...................

Thanx in advance.

PradeepSM:

Hi,
I want to call .net web service from java swings application through apache axis. The wsdl file exposing the .net web service is already built. I want to know how the java client can call the web service using this wsdl file.

Response with code samples would be greatly appriciated.

Ryan:

I also am getting the 401 Unauthorized error. It seems to stem from the fact that Commons HttpClient only supports NTLMv1, and not NTLMv2 which is much more common in corporate environments. Is there any way any one has been able to circumvent this problem?

Arivazhagan:

Mark,
How to get the credentials in the server side that is sent through HTTPClient.

Thanks,
Arivu

Kaushik Sen:

I am tring the access the deployed Siebel component extract (done using the Web UI DDK) in weblogic 8.1 workshop.
The code gets compiled successfully but once trying to login (using SADMIN/SADMIN) through login.jsp, its throws

AxisFault
faultCode: unauthrorized access
faultSubcode:
faultString: (401)Access Denied

The webservice is hosted in IIS server (we tried both 6.0 and 5.1) Axis version 1.1

Is there any way out from this??? Please help!!
Kaushik

Daniel Wayland:

for all you 401 unauthorized cats - try this

System.setProperty("httpclient.authentication.preemptive", "true");

John:

This does not work for NTLMv2 because HTTPClient does not work with NTLMv2. Use JAX-WS or go here for a fix. http://issues.apache.org/jira/browse/HTTPCLIENT-579

Mário Barbosa:

Hi!
Thanks for the incredibly usefull info, Mark.
I'm able to invoke a NTLM-protected WebService both through Tomcat and a pure-Java stand-alone client, both using JAVA 1.5.
It so happens that when I change to JAVA 1.3, I get the feared "401 Unauthorized" message.
I installed JCE (lib\ext) on my JVM and even added a JCE provider for JDK1.3 (bouncycastle) to my classpath, since I got a javax.crypto error first.
What could be the cause for this different behaviour?
Anyone?

thanks in advance




Remember Me?


(You may use HTML tags for style)

About

This page contains a single entry from the blog posted on November 21, 2005 11:43 PM.

The previous post in this blog was Honey Balsamic Vinaigrette.

The next post in this blog is Chief Leatherlips.

Many more can be found on the main index page or by looking through the archives.

Creative Commons License
This weblog is licensed under a Creative Commons License.
Powered by
Movable Type 3.33