0

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.

0 Answers0