I have an axis2 (v1.5.3) client that needs to do Kerberos/NTLM authentication with IIS. How can I do this? This is the code I have right now and it fails with 401 - un
Based on the notes at this link NTLM issues with Axis2
Axis2 still uses old HTTPClient library and it seems that version does not support all versions(v1, v2 ) of NTLM. And also it was not trivial to switch the transport to HTTPClient v4.1
I gave up on Axis2 and used CXF instead.
The following link really us get past the Kerboros/NTLM issues
http://download.oracle.com/javase/6/docs/technotes/guides/net/http-auth.html
There is a problem with NTLM in AXIS2. It centres around the ntlm.setHost() method. The entry here is used as both WORKSTATION in the NTLM exchange and as Remote Host when AuthScope is created. This creates a Catch-22 situation where NTLM does not work using the HttpTransportProperties.Authenticator technique. You either get a "401 unauthorized" or you get a "No credentials found for < REALM>@HOST".
See https://issues.apache.org/jira/browse/AXIS2-4595
Peter
HttpClient doesnt support NTLM v2 hence I use JCIFS library to return NTLM v1,2,3 message type as described in this website
http://devsac.blogspot.com/2010/10/supoprt-for-ntlmv2-with-apache.html
I just used the JCIFS_NTLMScheme.java file from the above website to register the auth scheme and it worked !!!!
Sample client:
List authSchema = new ArrayList();
AuthPolicy.registerAuthScheme(AuthPolicy.NTLM, org.tempuri.JCIFS_NTLMScheme.class);
HttpTransportProperties.Authenticator auth = new HttpTransportProperties.Authenticator();
auth.setUsername("");
auth.setPassword("");
auth.setDomain("");
auth.setHost("");
auth.setPort();
List authPrefs = new ArrayList(1);
authPrefs.add(AuthPolicy.NTLM);
auth.setAuthSchemes(authPrefs);
stub._getServiceClient().getOptions().setProperty(org.apache.axis2.transport.http.HTTPConstants.AUTHENTICATE, auth);
An alternative to JCIFS is to use the Apache HTTPComponents 4 NTLMScheme (which works with new NTLM) inside a custom Apache Commons HTTP AuthScheme:
public class BackportedNTLMScheme extends org.apache.http.impl.auth.NTLMScheme implements org.apache.commons.httpclient.auth.AuthScheme {
@Override
public String authenticate(final Credentials credentials, final HttpMethod method) throws AuthenticationException {
org.apache.commons.httpclient.NTCredentials oldCredentials;
try {
oldCredentials = (org.apache.commons.httpclient.NTCredentials) credentials;
} catch (final ClassCastException e) {
throw new InvalidCredentialsException(
"Credentials cannot be used for NTLM authentication: "
+ credentials.getClass().getName());
}
final org.apache.http.auth.Credentials adaptedCredentials = new NTCredentials(oldCredentials.getUserName(), oldCredentials.getPassword(), oldCredentials.getHost(), oldCredentials.getDomain());
try {
final Header header = super.authenticate(adaptedCredentials, null);
return header.getValue();
} catch (final org.apache.http.auth.AuthenticationException e) {
throw new AuthenticationException("AuthenticationException", e);
}
}
@Override
public void processChallenge(final String challenge) throws MalformedChallengeException {
final String s = AuthChallengeParser.extractScheme(challenge);
if (!s.equalsIgnoreCase(getSchemeName())) {
throw new MalformedChallengeException("Invalid NTLM challenge: " + challenge);
}
int challengeIdx = challenge.indexOf(' ');
final CharArrayBuffer challengeBuffer;
if(challengeIdx != -1){
challengeBuffer = new CharArrayBuffer(challenge.length());
challengeBuffer.append(challenge);
} else {
challengeBuffer = new CharArrayBuffer(0);
challengeIdx = 0;
}
try {
parseChallenge(challengeBuffer, challengeIdx, challengeBuffer.length());
} catch (final org.apache.http.auth.MalformedChallengeException e) {
throw new MalformedChallengeException("MalformedChallengeException", e);
}
}
@Override
@Deprecated
public String getID() {
throw new RuntimeException("deprecated vc.bjn.catalyst.forecast.BackportedNTLMScheme.getID()");
}
@Override
@Deprecated
public String authenticate(final Credentials credentials, final String method, final String uri) throws AuthenticationException {
throw new RuntimeException("deprecated vc.bjn.catalyst.forecast.BackportedNTLMScheme.authenticate(Credentials, String, String)");
}
}
AuthPolicy.registerAuthScheme(AuthPolicy.NTLM, BackportedNTLMScheme.class);
I tested this on IIS 7.5 on Windows Server 2008 R2.