2012-01-07 37 views
7

Sharepoint Web Service'e erişen ve SOAP işlemini gerçekleştiren bir Android uygulaması geliştiriyorum. JCIFS, vb. Gibi çeşitli yollar denedim.NTLM Kimlik Doğrulama Android

Herhangi biri bana yardımcı olabilir mi? Ben onu birçok güne gönderiyorum ama bu sorunu yaşayan herkes hüsrana uğruyor.

sayesinde Indrajit

cevap

5

NTLM'de uzman değilim, ancak JCIFS kütüphanesini ve başlıklarla bazı manuel çalışmaları kullanarak arka ucuma başarılı bir şekilde bağlandım.

Ayrıca ağ bağlantısı için OkHttp 3 kitaplığını kullanıyorum, ancak kodumu diğer kitaplıklara da uyarlayabilirsiniz. Ana fikir, bağlanmak için sunucuyla görüşmeniz gerektiğidir.

Adım 1:

WWW-Authenticate görüş:

WWW-Authenticate:

Eğer başarısız olacak 1 kez bağlanmaya ve bazı başlıktaki bilgi almak için denemek: NTLM

Adım 2:

jcifs kütüphanesini kullanarak 1 (bir anahtar türü & iş istasyonu parametreleriyle birlikte) bir Anahtar oluşturmanız ve yeniden bağlanmayı denemeniz gerekir. Yine başarısız ancak bazı yararlı başlığında bilgi alırsınız:

WWW-Authenticate: very_long_challenge_key NTLM

Adım 3: O meydan okumayla tip 3'ün bir Anahtarı üretmek gerekir

jcifs kütüphanesini kullanarak anahtar + giriş + şifre. Sonra bağlantı başarılı olacak! kavanoz burada bulabilirsiniz

compile files('libs/jcifs-1.3.18.jar') 
compile 'com.squareup.okhttp3:okhttp:3.4.1' 

:

Şimdi bazı kod, uygulamanızın build.gradle dosyasında kütüphanelere bağımlılık eklemek https://jcifs.samba.org/src/

Sonra NTLMAuthenticator sınıfının

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'inizi oluştururken, bu kimlik doğrulayıcıyı ekleyin:

Ve isteklerinizi her zamanki gibi yapın.

+0

"Taleplerinizi her zamanki gibi yapın" konusunu detaylandırır mısınız? OkHttp –

+1

ile aşina değilim OkHttp için basit örnekler: https://square.github.io/okhttp/#overview –

İlgili konular