나는 셰어 포인트 웹 서비스에 액세스하고 SOAP 처리를 수행하는 안드로이드 애플리케이션을 개발 중이다. 나는 JCIFS와 같은 다양한 방법을 시도했다.안드로이드에서 NTLM 인증
아무도 여기 도와 줄 수 있습니까? 나는 여러 날부터 그것을 인터넷 검색하지만,이 문제가있는 모든 사람들은 좌절하고 있습니다.
감사합니다, Indrajit
나는 셰어 포인트 웹 서비스에 액세스하고 SOAP 처리를 수행하는 안드로이드 애플리케이션을 개발 중이다. 나는 JCIFS와 같은 다양한 방법을 시도했다.안드로이드에서 NTLM 인증
아무도 여기 도와 줄 수 있습니까? 나는 여러 날부터 그것을 인터넷 검색하지만,이 문제가있는 모든 사람들은 좌절하고 있습니다.
감사합니다, Indrajit
확인이 ...........................
NTLM 전문가는 아니지만 JCIFS 라이브러리를 사용하여 백엔드에 연결하고 헤더를 사용하여 수동 작업을 수행했습니다.
또한 네트워크 연결을 위해 OkHttp 3 라이브러리를 사용하지만 내 코드를 다른 라이브러리에 적용 할 수 있습니다.
주요 아이디어는 연결할 서버와 협상해야한다는 것입니다.
1 단계 :
WWW 인증을 협상 :
WWW 인증 :
당신이 실패 할 수 있습니다 1 시간을 연결하고 헤더에 몇 가지 정보를 수신하려고 : NTLM
2 단계 :
jcifs 라이브러리를 사용하여 유형 1 (선택적인 도메인 & 워크 스테이션 매개 변수 사용)의 키를 생성하고 다시 연결해야합니다. 다시 실패하지만, 몇 가지 유용한 헤더의 정보를받을 수 있습니다 :
WWW 인증 : very_long_challenge_key NTLM을
3 단계 : 당신은 그 문제와 유형 3의 키를 생성해야
key + login + password, jcifs 라이브러리 사용. 그러면 연결이 성공합니다! 항아리는 여기에서 찾을 수 있습니다
compile files('libs/jcifs-1.3.18.jar')
compile 'com.squareup.okhttp3:okhttp:3.4.1'
:
이제 몇 가지 코드는 앱의 build.gradle 파일의 라이브러리에 종속성을 추가 https://jcifs.samba.org/src/
그런 다음 NTLMAuthenticator 클래스
import android.support.annotation.NonNull;
import java.io.IOException;
import java.util.List;
import jcifs.ntlmssp.NtlmFlags;
import jcifs.ntlmssp.Type1Message;
import jcifs.ntlmssp.Type2Message;
import jcifs.ntlmssp.Type3Message;
import jcifs.util.Base64;
import okhttp3.Authenticator;
import okhttp3.Credentials;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.Route;
/**
* Created by Arnaud Guyon on 07.02.17.
*/
public class NTLMAuthenticator implements Authenticator {
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 mLogin;
private String mPassword;
private String mDomain;
private String mWorkstation;
public NTLMAuthenticator(@NonNull String login, @NonNull String password) {
this(login, password, "", "");
}
public NTLMAuthenticator(@NonNull String login, @NonNull String password, @NonNull String domain, @NonNull String workstation) {
mLogin = login;
mPassword = password;
mDomain = domain;
mWorkstation = workstation;
}
@Override
public Request authenticate(Route route, Response response) throws IOException {
List<String> authHeaders = response.headers("WWW-Authenticate");
if (authHeaders != null) {
boolean negociate = false;
boolean ntlm = false;
String ntlmValue = null;
for (String authHeader : authHeaders) {
if (authHeader.equalsIgnoreCase("Negotiate")) {
negociate = true;
}
if (authHeader.equalsIgnoreCase("NTLM")) {
ntlm = true;
}
if (authHeader.startsWith("NTLM ")) {
ntlmValue = authHeader.substring(5);
}
}
if (negociate && ntlm) {
String type1Msg = generateType1Msg(mDomain, mWorkstation);
String header = "NTLM " + type1Msg;
return response.request().newBuilder().header("Authorization", header).build();
} else if (ntlmValue != null) {
String type3Msg = generateType3Msg(mLogin, mPassword, mDomain, mWorkstation, ntlmValue);
String ntlmHeader = "NTLM " + type3Msg;
return response.request().newBuilder().header("Authorization", ntlmHeader).build();
}
}
if (responseCount(response) <= 3) {
String credential = Credentials.basic(mLogin, mPassword);
return response.request().newBuilder().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();
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);
} catch (final IOException exception) {
exception.printStackTrace();
return null;
}
final int type2Flags = type2Message.getFlags();
final int type3Flags = type2Flags
& (0xffffffff^(NtlmFlags.NTLMSSP_TARGET_TYPE_DOMAIN | NtlmFlags.NTLMSSP_TARGET_TYPE_SERVER));
final Type3Message type3Message = new Type3Message(type2Message, password, domain,
login, workstation, type3Flags);
return Base64.encode(type3Message.toByteArray());
}
private int responseCount(Response response) {
int result = 1;
while ((response = response.priorResponse()) != null) {
result++;
}
return result;
}
}
다음 OkHttpClient를 만들 때이 인증자를 추가하십시오.
OkHttpClient okHttpClient = new OkHttpClient.Builder()
.authenticator(new NTLMAuthenticator(login, password))
// .some other init here if necessary
.build();
그런 다음 평소와 같이 요청하십시오.
"평소와 같이 요청 하시겠습니까?"에 대해 자세히 설명해 주시겠습니까? Okhttp에 익숙하지 않다. –
여기에 OkHttp에 대한 간단한 샘플이있다 : https://square.github.io/okhttp/#overview –