web services - 401: Unauthorized Exception occurred with an apache axis client(java) to invoke a webservice(.net) with an NTLM Authentication Technique -
i calling web service written in .net located remotely running under iis server.
i created respective stub using apache axis 1.4
eclipse ide , created respective web service client. test client in actual web application going call web service.
we have kept 2 different endpoint keeping security credential enable/disable.
- "ip:port/pigeon/pigeon.svc;" // authentication disabled
"ip:port/pwa/pigeon.svc; // authentiction enabled
so when using endpoint no (1) able call web service , gets things done, since want apply security credential mandatory when use endpoint no (2) getting below exception
(401)unauthorized
(401)unauthorized axisfault
faultcode: {http://xml.apache.org/axis/}http
faultsubcode:
faultstring: (401)unauthorized
faultactor:
faultnode:
faultdetail: {}:return code: 401
i want pass credential in format :
1) domain\username
2) password
i tried adding suggestion of other post on here says set respective before call method in stub getting same above mentioned exception.
(mystub)._setproperty(javax.xml.rpc.stub.username_property, domain + "\" + username);
(mystub)._setproperty(javax.xml.rpc.stub.password_property, password);
hhowever search able ntml authentication java stand alone program invoking remote .net web service doing :
public static void main(string[] args) throws exception { string urlstr = “http://example.com/root/action.dll?p1=value1″; string domain = “”; // may referred realm string username = “change_me”; string password = “change_me”; string responsetext = getauthenticatedresponse(urlstr, domain, username, password); system.out.println(”response: ” + responsetext); } private static string getauthenticatedresponse(final string urlstr, final string domain, final string username, final string password) throws ioexception { stringbuilder response = new stringbuilder(); authenticator.setdefault(new authenticator() { @override public passwordauthentication getpasswordauthentication() { return new passwordauthentication(domain + “\\” + username, password.tochararray()); } }); url urlrequest = new url(urlstr); httpurlconnection conn = (httpurlconnection) urlrequest.openconnection(); conn.setdooutput(true); conn.setdoinput(true); conn.setrequestmethod(”get”); inputstream stream = conn.getinputstream(); bufferedreader in = new bufferedreader(new inputstreamreader(stream)); string str = “”; while ((str = in.readline()) != null) { response.append(str); } in.close(); return response.tostring(); }
but not able axis client stub generated wsdl provided .net web service in web service client. tried changing @stub level before invoke() call modifying according above demo throws same unauthorized exception.
this fyi/all remote iis server using ntlm authentication technique.
help expected on windows authentication using java in order pass security credential iis.
[note : axis client(java) passes domain\user password ,this configured iis server on otherside properly]
the problem axis 1.4 not implement correctly ntlm v2 protocol.
i experienced problem sharepoint 2010 web services. had client working sharepoint 2007 running on windows 2003 server. then, tested client sharepoint 2010 web services running on windows 2008 r2 server , stop working. error was:
caused by: (401)unauthorized @ org.apache.axis.transport.http.commonshttpsender.invoke(commonshttpsender.java:218) @ org.apache.axis.strategies.invocationstrategy.visit(invocationstrategy.java:32) @ org.apache.axis.simplechain.dovisiting(simplechain.java:118) @ org.apache.axis.simplechain.invoke(simplechain.java:83) @ org.apache.axis.client.axisclient.invoke(axisclient.java:165) @ org.apache.axis.client.call.invokeengine(call.java:2784) @ org.apache.axis.client.call.invoke(call.java:2767) @ org.apache.axis.client.call.invoke(call.java:2443) @ org.apache.axis.client.call.invoke(call.java:2366) @ org.apache.axis.client.call.invoke(call.java:1812)
searching in google, problem windows 2003 using ntlm v1 protocol default, while windows 2008 r2 using ntlm v2 default.
i found solution , problem explained in following url:
http://devsac.blogspot.com.es/2010/10/supoprt-for-ntlmv2-with-apache.html
the solution creating following class resolve httpclient 3.x:
public class jcifs_ntlmscheme implements authscheme { private static applogger logger = new applogger(httphelper.class.getname()); /** ntlm challenge string. */ private string ntlmchallenge = null; private static final int uninitiated = 0; private static final int initiated = 1; private static final int type1_msg_generated = 2; private static final int type2_msg_received = 3; private static final int type3_msg_generated = 4; private static final int failed = integer.max_value; /** authentication process state */ private int state; public jcifs_ntlmscheme() throws authenticationexception { // check if jcifs present. if not present, not proceed. try { class.forname("jcifs.ntlmssp.ntlmmessage",false,this.getclass().getclassloader()); } catch (classnotfoundexception e) { throw new authenticationexception("unable proceed jcifs library not found."); } } public string authenticate(credentials credentials, httpmethod method) throws authenticationexception { logger.dolog(applogger.finest, "enter jcifs_ntlmscheme.authenticate(credentials, httpmethod)", null); if (this.state == uninitiated) { throw new illegalstateexception( "ntlm authentication process has not been initiated"); } ntcredentials ntcredentials = null; try { ntcredentials = (ntcredentials) credentials; } catch (classcastexception e) { throw new invalidcredentialsexception( "credentials cannot used ntlm authentication: " + credentials.getclass().getname()); } ntlm ntlm = new ntlm(); ntlm.setcredentialcharset(method.getparams().getcredentialcharset()); string response = null; if (this.state == initiated || this.state == failed) { response = ntlm.generatetype1msg(ntcredentials.gethost(), ntcredentials.getdomain()); this.state = type1_msg_generated; } else { response = ntlm.generatetype3msg(ntcredentials.getusername(), ntcredentials.getpassword(), ntcredentials.gethost(), ntcredentials.getdomain(), this.ntlmchallenge); this.state = type3_msg_generated; } return "ntlm " + response; } public string authenticate(credentials credentials, string method, string uri) throws authenticationexception { throw new runtimeexception( "not implemented deprecated anyway in httpclient 3.x"); } public string getid() { throw new runtimeexception( "not implemented deprecated anyway in httpclient 3.x"); } /** * returns authentication parameter given name, if available. * * <p> * there no valid parameters ntlm authentication method * returns <tt>null</tt>. * </p> * * @param name * name of parameter returned * * @return parameter given name */ public string getparameter(string name) { if (name == null) { throw new illegalargumentexception("parameter name may not null"); } return null; } /** * concept of authentication realm not supported ntlm * authentication scheme. returns <code>null</code>. * * @return <code>null</code> */ public string getrealm() { return null; } /** * returns textual designation of ntlm authentication scheme. * * @return <code>ntlm</code> */ public string getschemename() { return "ntlm"; } /** * tests if ntlm authentication process has been completed. * * @return <tt>true</tt> if basic authorization has been processed, * <tt>false</tt> otherwise. * * @since 3.0 */ public boolean iscomplete() { return this.state == type3_msg_generated || this.state == failed; } /** * returns <tt>true</tt>. ntlm authentication scheme connection based. * * @return <tt>true</tt>. * * @since 3.0 */ public boolean isconnectionbased() { return true; } /** * processes ntlm challenge. * * @param challenge * challenge string * * @throws malformedchallengeexception * thrown if authentication challenge malformed * * @since 3.0 */ public void processchallenge(final string challenge) throws malformedchallengeexception { string s = authchallengeparser.extractscheme(challenge); if (!s.equalsignorecase(getschemename())) { throw new malformedchallengeexception("invalid ntlm challenge: " + challenge); } int = challenge.indexof(' '); if (i != -1) { s = challenge.substring(i, challenge.length()); this.ntlmchallenge = s.trim(); this.state = type2_msg_received; } else { this.ntlmchallenge = ""; if (this.state == uninitiated) { this.state = initiated; } else { this.state = failed; } } } private class ntlm { /** character encoding */ public static final string default_charset = "ascii"; /** * character used 3.x's ntlm encode username , * password. apparently, not needed in when passing username, * password ntcredentials jcifs library */ private string credentialcharset = default_charset; void setcredentialcharset(string credentialcharset) { this.credentialcharset = credentialcharset; } private string generatetype1msg(string host, string domain) { jcifs.ntlmssp.type1message t1m = new jcifs.ntlmssp.type1message(jcifs.ntlmssp.type1message.getdefaultflags(), domain, host); return jcifs.util.base64.encode(t1m.tobytearray()); } private string generatetype3msg(string username, string password, string host, string domain, string challenge) { jcifs.ntlmssp.type2message t2m; try { t2m = new jcifs.ntlmssp.type2message(jcifs.util.base64.decode(challenge)); } catch (ioexception e) { throw new runtimeexception("invalid type2 message", e); } jcifs.ntlmssp.type3message t3m = new jcifs.ntlmssp.type3message(t2m, password, domain, username, host, 0); return jcifs.util.base64.encode(t3m.tobytearray()); } }
}
then register new jcifs_ntlmscheme class replacement ntlmscheme using following command:
authpolicy.registerauthscheme(authpolicy.ntlm, org.xyz.jcifs_ntlmscheme.class);
Comments
Post a Comment