NTLM Authentication returns 401 error code. below is OKHttpClient call
private fun getOkHttpClient(): OkHttpClient? {return try {
val trustAllCerts = arrayOf<TrustManager>(
object : X509TrustManager {
@Throws(CertificateException::class)
override fun checkClientTrusted(chain: Array<X509Certificate?>?, authType: String?) {}
@Throws(CertificateException::class)
override fun checkServerTrusted(chain: Array<X509Certificate?>?,authType: String?) {
}
override fun getAcceptedIssuers(): Array<X509Certificate?>? {
return arrayOf()
}
}
)
// Install the all-trusting trust manager
val sslContext = SSLContext.getInstance("SSL")
sslContext.init(null, trustAllCerts, SecureRandom())
// Create an ssl socket factory with our all-trusting manager
val sslSocketFactory = sslContext.socketFactory
val builder = OkHttpClient.Builder()
builder.writeTimeout(60, TimeUnit.SECONDS)
builder.readTimeout(60, TimeUnit.SECONDS)
builder.connectTimeout(60, TimeUnit.SECONDS)
builder.protocols(Util.immutableList(Protocol.HTTP_1_1))
builder.sslSocketFactory(sslSocketFactory, trustAllCerts[0] as X509TrustManager)
builder.hostnameVerifier { hostname, session -> true }
builder.authenticator(NtlmAuthHelper(Common.USERNAME, Common.PASSWORD))
builder.build()
} catch (e: java.lang.Exception) {
throw RuntimeException(e)
}
}
Above code is okHttpClient Call and also using library for NTLM auth implementation group: 'org.codelibs', name: 'jcifs', version: '1.3.18.1'
public class NtlmAuthHelper implements Authenticator { private static final String CLASS_TAG = "NtlmAuthHelper";
private static final String AUTHENTICATE_HEADERS = "WWW-Authenticate";
private static final String HEADER_NEGOTIATE = "Negotiate";
private static final String HEADER_NTLM = "NTLM";
private static final String HEADER_AUTHORIZATION = "Authorization";
private static final int TYPE_1_FLAGS =
NtlmFlags.NTLMSSP_NEGOTIATE_56 |
NtlmFlags.NTLMSSP_NEGOTIATE_128 |
NtlmFlags.NTLMSSP_NEGOTIATE_NTLM2 |
NtlmFlags.NTLMSSP_NEGOTIATE_ALWAYS_SIGN |
NtlmFlags.NTLMSSP_REQUEST_TARGET;
private String m_login;
private String m_password;
private String m_domain;
private String m_workstation;
private int m_contaAutenticazioni;
private HttpUrl m_url;
public NtlmAuthHelper(@NonNull String login, @NonNull String password) {
this(login, password, "", "");
}
public NtlmAuthHelper(@NonNull String login, @NonNull String password, @NonNull String domain) {
this(login, password, domain, "");
}
public NtlmAuthHelper(@NonNull String login, @NonNull String password, @NonNull String domain, @NonNull String workstation) {
m_login = login;
m_password = password;
m_domain = domain;
m_workstation = workstation;
m_contaAutenticazioni = 0;
Log.e( "constructor - m_cont " , String.valueOf(m_contaAutenticazioni));
Log.e( "constructor - m_login " , m_login);
Log.e( "constructor - m_pass " , m_password);
}
@Override
public Request authenticate(Route route, Response response) throws IOException {
if (m_url == null || response.request().url() != m_url) {
m_contaAutenticazioni = 0;
m_url = response.request().url();
}
m_contaAutenticazioni++;
if (m_contaAutenticazioni >= 4) {
throw new IOException(String.format("challenge request count too big (%s)",m_contaAutenticazioni));
}
List<String> authHeaders = response.headers(AUTHENTICATE_HEADERS);
if (authHeaders != null) {
boolean negotiate = false;
boolean ntlm = false;
String ntlmValue = null;
for (String authHeader : authHeaders) {
if (authHeader.equalsIgnoreCase(HEADER_NEGOTIATE)) {
negotiate = true;
Log.e( "constructor - 3 " , String.valueOf(response.code()));
}
if (authHeader.equalsIgnoreCase(HEADER_NTLM)) {
ntlm = true;
Log.e( "constructor - 4 " , String.valueOf(response.code()));
}
if (authHeader.startsWith(HEADER_NTLM + " ")) {
ntlmValue = authHeader.substring(5);
Log.e( "constructor - 5 " , String.valueOf(response.code()));
}
}
if (negotiate && ntlm) {
String type1Msg = generateType1Msg(m_domain, m_workstation);
String header = HEADER_NTLM + " " + type1Msg;
Log.v(CLASS_TAG, HEADER_AUTHORIZATION + " " + header);
Log.e( "constructor - 6 " , String.valueOf(response.code()));
return response.request().newBuilder().header(HEADER_AUTHORIZATION, header).build();
} else if (ntlmValue != null) {
String type3Msg = generateType3Msg(m_login, m_password, m_domain, m_workstation, ntlmValue);
String ntlmHeader = HEADER_NTLM + " " + type3Msg;
Log.v(CLASS_TAG, HEADER_AUTHORIZATION + " " + ntlmHeader);
Log.e( "constructor - 7 " , String.valueOf(response.code()));
return response.request().newBuilder().header(HEADER_AUTHORIZATION, ntlmHeader).build();
}
}
if (responseCount(response) <= 3) {
String credential = Credentials.basic(m_login, m_password);
Log.v(CLASS_TAG, HEADER_AUTHORIZATION + " " + credential);
Log.e( "constructor - cred " , String.valueOf(response.code()));
return response.request().newBuilder().header(HEADER_AUTHORIZATION, credential).build();
}
return null;
}
private String generateType1Msg(@NonNull String domain, @NonNull String workstation) {
final Type1Message type1Message = new Type1Message(TYPE_1_FLAGS, domain, workstation);
byte[] source = type1Message.toByteArray();
Log.e( "constructor - Msg1 " , "MSG1");
return Base64.encode(source);
}
private String generateType3Msg(final String login, final String password, final String domain, final String workstation, final String challenge) {
Type2Message type2Message;
try {
byte[] decoded = Base64.decode(challenge);
type2Message = new Type2Message(decoded);
Log.e( "constructor - Msg2 " , "MSG2");
} catch (final IOException exception) {
exception.printStackTrace();
Log.e( "constructor - Msg3 " , "MSG3");
return null;
}
final int type2Flags = type2Message.getFlags();
final int type3Flags = type2Flags & ~(NtlmFlags.NTLMSSP_TARGET_TYPE_DOMAIN | NtlmFlags.NTLMSSP_TARGET_TYPE_SERVER);
final Type3Message type3Message = new Type3Message(type2Message, password, domain, login, workstation, type3Flags);
Log.e( "constructor - Msg4 " , "MSG4");
return Base64.encode(type3Message.toByteArray());
}
private int responseCount(Response response) {
int result = 1;
while ((response = response.priorResponse()) != null) {
Log.e( "constructor - Redirect " , "" +response.isRedirect());
if (!response.isRedirect())
result++;
}
return result;
}
}
Always returns 401 Error, not 200 OK. Any help would be appreciated.