私はSharepoint Webサービスにアクセスし、SOAP処理を行うAndroidアプリケーションを開発しています。私はJCIFSのように様々な方法を試しました。AndroidのNTLM認証
ここで私を助けることができますか?私は何日もそれをグーグルで見つけましたが、この問題を抱えている人は誰もがイライラしています。
おかげで、 インドラジット
私はSharepoint Webサービスにアクセスし、SOAP処理を行うAndroidアプリケーションを開発しています。私はJCIFSのように様々な方法を試しました。AndroidのNTLM認証
ここで私を助けることができますか?私は何日もそれをグーグルで見つけましたが、この問題を抱えている人は誰もがイライラしています。
おかげで、 インドラジット
チェックこの...........................
私はNTLMの専門家ではありませんが、JCIFSライブラリを使用してバックエンドに接続し、ヘッダーを使って手作業で作業することに成功しました。
また、OkHttp 3ライブラリをネットワーク接続に使用していますが、おそらく他のライブラリに自分のコードを適合させることができます。
主なアイデアは、接続するサーバーとネゴシエートする必要があるということです。
ステップ1:
WWW認証をネゴシエート:
WWW認証:
あなたが失敗するだろう第一の時間を接続して、ヘッダ内のいくつかの情報を受信しよう: NTLM
ステップ2:
jcifsライブラリーを使用してタイプ1の鍵(オプションのドメイン&ワークステーション・パラメーターを使用)を生成し、再度接続を試みる必要があります。 あなたは再び失敗したが、いくつかの有用なヘッダの情報が届きます:
WWW認証:very_long_challenge_key NTLMを
ステップ3:あなたがその挑戦とタイプ3のキーを生成する必要が
jcifsライブラリを使用して、key + login + passwordを入力します。その後、接続は成功します!瓶はここで見つけることができます
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 –