Hi, I’m having a problem upgrading one application that uses axis2 version 1.6.0 to the 1.8.2 version. The situation is that I’m trying to connect to one IIS webservice from a linux server, and the IIS use in the authentication Negotiate. In version 1.6.0 its working using a custom class to handle the request. I try to upgrade the client part to use axis2 1.8.2 but there are changes on axis in HttpTransportProperties class that now doesn’t have Authenticator. I’m trying to use the HttpTransportPropertiesImpl class but it’s not working. Using HttpTransportPropertiesImpl I can’t use the custom class that handles the Negotiate authentication. I’m going to expose the situation using the code.
This is the code using axis2 1.6.0, and using wsdl2java to create the stub ProfilesStub stub = new ProfilesStub(wsURL); // Stub created by wsdl2java System.setProperty("java.security.auth.login.config", kbr5LoginConfigFile); System.setProperty("java.security.krb5.conf", kbr5ConfigFile); System.setProperty("javax.security.auth.useSubjectCredsOnly", "false"); System.setProperty("sun.security.krb5.debug", "true"); System.setProperty("sun.security.jgss.debug", "true"); System.setProperty("java.security.debug", "logincontext,policy,scl,gssloginconfig"); AuthPolicy.unregisterAuthScheme("BASIC"); AuthPolicy.unregisterAuthScheme("DIGEST"); AuthPolicy.unregisterAuthScheme("NTLM"); ArrayList authSchemes = new ArrayList(); if ( AuthSchemeId.equals("Negotiate") ) // <-- I’m using AuthSchemeId=Negotiate { AuthPolicy.registerAuthScheme("Negotiate", NegotiateSchemeCustom.class); //<-- the custom class that handles the Negotiate authentication authSchemes.add("Negotiate"); } else { if ( AuthSchemeId.equals("Kerberos") ) { AuthPolicy.registerAuthScheme("Kerberos", KerberosSchemeCustom.class); authSchemes.add("Kerberos"); } else throw new Exception("Invalid authentication scheme '" + (AuthSchemeId == null ? "(null)" : AuthSchemeId) + "'"); } HttpTransportProperties.Authenticator auth = new HttpTransportProperties.Authenticator(); auth.setDomain(userDomain); auth.setHost((new URL(wsURL)).getHost()); java.util.Properties properties = new java.util.Properties(); // absolute from the classpath String configFileName = "wsURL.config"; try { properties.load(new java.io.FileInputStream(configFileName)); } catch ( Exception exception ) { System.out.println("ERROR oppening file " + configFileName + "--"); System.out.println("EX:" + exception.getMessage() +"--"); } String username = properties.getProperty("username"); String password = properties.getProperty("password"); auth.setUsername(username); auth.setPassword(password); auth.setAuthSchemes(authSchemes); HttpParams params = DefaultHttpParams.getDefaultParams(); params.setParameter(AuthPolicy.AUTH_SCHEME_PRIORITY, authSchemes); Options options = stub._getServiceClient().getOptions(); options.setProperty(org.apache.axis2.transport.http.HTTPConstants.AUTHENTICATE, auth); options.setProperty(org.apache.axis2.transport.http.HTTPConstants.CHUNKED, Boolean.FALSE); options.setProperty(org.apache.axis2.transport.http.HTTPConstants.REUSE_HTTP_CLIENT, "true"); stub._getServiceClient().setOptions(options); GetUserInfo userInfo = GetUserInfo.Factory.newInstance(); // GetUserInfo class created by wsdl2java userInfo.setSUserName(userName); userInfo.setSDomain(domain); userInfo.setSApplication(application); GetUserInfoDocument getUserInfoDocument = GetUserInfoDocument.Factory.newInstance();// GetUserInfoDocument class created by wsdl2java getUserInfoDocument.setGetUserInfo(userInfo); GetUserInfoResponseDocument response = stub.getUserInfo(getUserInfoDocument); // getUserInfo method to invoke, GetUserInfoResponseDocument class created by wsdl2java String userData = response.getGetUserInfoResponse().getGetUserInfoResult().toString(); And using trace on the NegotiateSchemeCustom.class I confirm that this class is used In the class public NegotiateSchemeCustom () { super(); state = UNINITIATED; System.out.println("Created NegotiateSchemeCustom()"); } The output Jan 31, 2024 5:09:09 PM org.apache.commons.httpclient.auth.AuthChallengeProcessor selectAuthScheme INFO: negotiate authentication scheme selected Created NegotiateSchemeCustom() And the invocation is successful. But when I try using 1.8.2 version ProfilesStub stub = new ProfilesStub(wsURL); // Stub created by wsdl2java version 1.8.2 System.setProperty("java.security.auth.login.config", kbr5LoginConfigFile); System.setProperty("java.security.krb5.conf", kbr5ConfigFile); System.setProperty("javax.security.auth.useSubjectCredsOnly", "false"); System.setProperty("sun.security.krb5.debug", "true"); System.setProperty("sun.security.jgss.debug", "true"); System.setProperty("java.security.debug", "logincontext,policy,scl,gssloginconfig"); AuthPolicy.unregisterAuthScheme("BASIC"); AuthPolicy.unregisterAuthScheme("DIGEST"); AuthPolicy.unregisterAuthScheme("NTLM"); ArrayList authSchemes = new ArrayList(); if ( AuthSchemeId.equals("Negotiate") ) // <-- I’m using AuthSchemeId=Negotiate { AuthPolicy.registerAuthScheme("Negotiate", NegotiateSchemeCustom.class); //<-- the custom class that handles the Negotiate authentication, same as the 1.6.0 authSchemes.add("Negotiate"); } else { if ( AuthSchemeId.equals("Kerberos") ) { AuthPolicy.registerAuthScheme("Kerberos", KerberosSchemeCustom.class); authSchemes.add("Kerberos"); } else throw new Exception("Invalid authentication scheme '" + (AuthSchemeId == null ? "(null)" : AuthSchemeId) + "'"); } HttpTransportPropertiesImpl.Authenticator auth = new HttpTransportPropertiesImpl.Authenticator(); // <-- Using HttpTransportPropertiesImpl that has Authenticator auth.setDomain(userDomain); auth.setHost((new URL(wsURL)).getHost()); java.util.Properties properties = new java.util.Properties(); // absolute from the classpath String configFileName = "wsURL.config"; try { properties.load(new java.io.FileInputStream(configFileName)); } catch ( Exception exception ) { System.out.println("ERROR oppening file " + configFileName + "--"); System.out.println("EX:" + exception.getMessage() +"--"); } String username = properties.getProperty("username"); String password = properties.getProperty("password"); auth.setUsername(username); auth.setPassword(password); auth.setAuthSchemes(authSchemes); HttpParams params = DefaultHttpParams.getDefaultParams(); params.setParameter(AuthPolicy.AUTH_SCHEME_PRIORITY, authSchemes); Options options = stub._getServiceClient().getOptions(); options.setProperty(org.apache.axis2.transport.http.HTTPConstants.AUTHENTICATE, auth); options.setProperty(org.apache.axis2.transport.http.HTTPConstants.CHUNKED, Boolean.FALSE); options.setProperty(org.apache.axis2.transport.http.HTTPConstants.REUSE_HTTP_CLIENT, "true"); stub._getServiceClient().setOptions(options); GetUserInfo userInfo = GetUserInfo.Factory.newInstance(); // GetUserInfo class created by wsdl2java userInfo.setSUserName(userName); userInfo.setSDomain(domain); userInfo.setSApplication(application); GetUserInfoDocument getUserInfoDocument = GetUserInfoDocument.Factory.newInstance();// GetUserInfoDocument class created by wsdl2java getUserInfoDocument.setGetUserInfo(userInfo); GetUserInfoResponseDocument response = stub.getUserInfo(getUserInfoDocument); // getUserInfo method to invoke, GetUserInfoResponseDocument class created by wsdl2java String userData = response.getGetUserInfoResponse().getGetUserInfoResult().toString(); My problems started, first is with HttpTransportPropertiesImpl, it does not recognizes Negotiate schema. I checked the code and when the method getAuthPolicyPref of the Authenticator class of the HttpTransportPropertiesImpl is called with Negotiate its returns null. Where is part of the code of axis2-1.8.2\modules\transport\http\src\org\apache\axis2\transport\http\impl\httpclient4\HttpTransportPropertiesImpl.java @Override public Object getAuthPolicyPref(String scheme) { if (BASIC.equals(scheme)) { return AuthPolicy.BASIC; } else if (NTLM.equals(scheme)) { return AuthPolicy.NTLM; } else if (DIGEST.equals(scheme)) { return AuthPolicy.DIGEST; } return null; } There is no Negotiate so it returns null and in the AuthenticationStrategyImpl select method it causes one exception bellow, because id is null for (final String id: authPrefs) { final Header challenge = challenges.get(id.toLowerCase(Locale.ROOT)); My solution to this was to create a custom HttpTransportPropertiesImplCustom that includes Negotiate and Kerberos This is my custom class. public class HttpTransportPropertiesImplCustom extends HttpTransportProperties { protected HttpVersion httpVersion; @Override public void setHttpVersion(Object httpVerion) { this.httpVersion = (HttpVersion) httpVerion; } @Override public Object getHttpVersion() { return this.httpVersion; } public static class Authenticator extends HTTPAuthenticator { private int port = -1; private String realm = null; public static final String NTLM = "NTLM"; public static final String DIGEST = "Digest"; public static final String BASIC = "Basic"; public static final String SPNEGO = "Negotiate"; public static final String KERBEROS = "Kerberos"; public int getPort() { return port; } public void setPort(int port) { this.port = port; } public String getRealm() { return realm; } public void setRealm(String realm) { this.realm = realm; } @Override public Object getAuthPolicyPref(String scheme) { if (BASIC.equals(scheme)) { return "Basic"; } else if (NTLM.equals(scheme)) { return "NTLM"; } else if (DIGEST.equals(scheme)) { return "Digest"; } else if (SPNEGO.equals(scheme)) { return "Negotiate"; } else if (KERBEROS.equals(scheme)) { return "Kerberos"; } return null; } } } With this now I have a valid schema for Negotiate but still can’t invoke my custom class. Debugging I see that the class used when the schema is Negotiate is SPNegoScheme of the package org.apache.http.impl.auth. It ignores my NegotiateSchemeCustom.class I also tried to create a custom SPNegoScheme with the code of NegotiateSchemeCustom.class but have other problems. But instead of trying to use this solution why my custom class NegotiateSchemeCustom.class isn’t used as the schema for Negotiate? I’m I missing some new configuration? Any help/suggestion is appreciated . Best Regards, Luis Silva