Android: NTLM-Authentifizierung, ksoap und dauerhafte Verbindungen

Nach der Arbeit mit iOS und dem Umgang mit Authentifizierungsherausforderungen ohne großen Lernaufwand habe ich festgestellt, dass die Windows-Authentifizierung bei einem Prozess in Java / Android viel komplizierter ist.

Ich habe mehrere verschiedene Ansätze ausprobiert. Ohne zu viel in diese Ansätze zu investieren, komme ich zu dem Ansatz, der zum größten Teil funktioniert hat. Ich verwende jetzt die für NTLM und ksoap erstellte Klasse mit dem Namen NtlmTransport

Ich authentifiziere mich jetzt erfolgreich auf folgende Weise:

NtlmTransport httpTransport = new NtlmTransport();
            httpTransport.setCredentials(serverURL, Login.username, Login.password, deviceIp, "DOMAINNAME");
            httpTransport.call(SOAP_ACTION, envelope);

Wenn Sie sich die NtlmTransport-Klasse ansehen, werden Sie feststellen, dass sie die folgenden Header von setupNtlm () zurückgibt:

status Line HTTP / 1.1 200 OKSetup Cache-Control: privat, maximales Alter = 0Setup Inhaltstyp: text / html; Zeichensatz = utf-8Setup Server: Microsoft-IIS / 8.0Setup X-AspNet-Version: 4.0.30319Setup Persistent-Auth: trueSetup X-Powered-By: ASP.NETEinstellungsdatum: Di, 17. September 2013 20:57:45 GMTSetup Content-Length: 11549

The "Persistent-Auth: true ist das wichtigste, um das ich mich derzeit kümmere. Ich erhalte die SoapObjects einwandfrei und kann die benötigten Daten von dieser einen Verbindung abrufen, aber sobald ich versuche, auf die zuzugreifen Wieder ein Webservice, der nach erfolgreicher Authentifizierung vermutlich getroffen werden kann. Ich kann mit HttpTransportSE nicht auf eine andere Methode zugreifen:

private void setSomething() {

    xml = null;
    final String SOAP_ACTION = "http://this.ismy.org/AWebServiceMethod";
    final String METHOD_NAME = "AWebServiceMethod";
    final String URL = protocol + "://" + host  + ":" + port + "/WebService.asmx";
    SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME);
    SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
    envelope.dotNet = true;
    envelope.setOutputSoapObject(request);
    envelope.implicitTypes = true;
    envelope.setAddAdornments(false);

    try
    {
        HttpTransportSE transport = new HttpTransportSE(URL);
        transport.debug = true;
        transport.call(SOAP_ACTION, envelope);
        xml = transport.responseDump.toString();
        Log.d(TAG, xml);
    }
    catch(SocketException ex)
    {
        Log.e("SocketException : " , "Error on setSomething() " + ex.getMessage());
    }
    catch (Exception e)
    {
        Log.e("Exception : " , "Error on setSomething() " + e.getMessage());
    }
}

Dies alles funktioniert einwandfrei als Hintergrundaufgabe einer AsyncTask, die dann die "xml" an eine XMLPullParser-Methode übergibt.

Die Hauptfrage hier ist, warum bekomme ich ein:

Error on setSomething () Keine Authentifizierungsprobleme gefunden

??

Nachdem IIS den Benutzer erfolgreich mit 200 validiert hat, warum werde ich aufgefordert, mich erneut zu authentifizieren? Wie kann ich diese erste authentifizierte Herausforderung bestehen, um die gewünschte Methode in WebService.asmx zu erreichen? Welche Header müssen hinzugefügt / geändert werden, um bei Bedarf eine Sitzung zu erstellen? Was fehlt mir, damit dieser gesamte NTLM-Prozess funktioniert und länger als die WS-Methode besteht, die die Authentifizierungsherausforderungen bestehen muss?

EDIT: Hinzufügen des Bibliothekscodes

Hier ist der Link zumJCIFS von Apache

public static final class JCIFSEngine implements NTLMEngine {

    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;

    public String generateType1Msg(final String domain, final String workstation)
            throws NTLMEngineException {
        final Type1Message type1Message = new Type1Message(TYPE_1_FLAGS, domain, workstation);
        return jcifs.util.Base64.encode(type1Message.toByteArray());
    }

    public String generateType3Msg(final String username, final String password,
                                   final String domain, final String workstation, final String challenge)
            throws NTLMEngineException {
        Type2Message type2Message;
        try {
            type2Message = new Type2Message(jcifs.util.Base64.decode(challenge));
        } catch (final IOException exception) {
            throw new NTLMEngineException("Invalid NTLM type 2 message", exception);
        }
        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, Login.password, "",
                Login.username, deviceIp, type3Flags);

            System.out.println("type3Message: " + type3Message.toByteArray());

        return jcifs.util.Base64.encode(type3Message.toByteArray());
    }
}

So verursacht "NtlmFlags.NTLMSSP_NEGOTIATE_ALWAYS_SIGN" dieses Problem? Gibt es eine andere Flagge, die ich für den Keep-Alive setzen soll? Außerdem habe ich eine großartige Ressource für eine Liste von NTLM-Flags und mehr gefunden:http: //fossies.org/dox/jcifs-1.3.17/interfacejcifs_1_1ntlmssp_1_1NtlmFlags.htm