1

NTLMを使用してDefaultHttpClientのプリエンプティブ認証を実装したいと思います。通常の認証で正常に機能するDanHounshellのライブラリを見つけました。

しかし、プリエンプティブ認証でこれを機能させる方法を理解することはできません。このクールな答えで、 ApacheHttpClient4を使用したプリエンプティブ基本認証という質問を見つけました。

UsernamePasswordCredentials creds = new UsernamePasswordCredentials(username, password);
HttpRequest request = ...
request.addHeader(new BasicScheme().authenticate(creds, request));

私の問題には完璧ではありませんが、良い考えです。そこで、を使用してwithNTLMSchemeFactoryの新しいインスタンスを作成しようとするAuthSchemeと、関数が得られauthenticateます。

NTCredentials ntc = new NTCredentials("example.com/user:pwd");
httpPost.addHeader(new NTLMScheme(new JCIFSEngine()).authenticate(ntc, httpPost));

この関数が呼び出されると、例外が発生します。

org.apache.http.auth.AuthenticationException:予期しない状態:UNINITIATED

どうすれば修正できますか?

POST /login/ HTTP/1.1
Content-Length: 21
Content-Type: application/x-www-form-urlencoded
Host: example.com
Connection: Keep-Alive
data=...

HTTP/1.1 401 Unauthorized
Content-Type: text/html
Server: Microsoft-IIS/7.5
WWW-Authenticate: Negotiate
WWW-Authenticate: NTLM
X-Powered-By: ASP.NET
Date: Wed, 12 Dec 2012 14:36:26 GMT
Content-Length: 1344

Much data...

POST /login/ HTTP/1.1
Content-Length: 21
Content-Type: application/x-www-form-urlencoded
Host: example.com
Connection: Keep-Alive
Authorization: NTLM AAABBBCCC...FFF==
data=...

最初のリクエストは絶対に役に立たないと思います。

4

2 に答える 2

0

私の解決策はこれです:

public class PreemptiveNTLMHeader implements Header {
    private HttpRequest request;
    private NTCredentials ntc;

    public PreemptiveNTLMHeader(HttpRequest request, NTCredentials ntc) {
        this.request = request;
        this.ntc = ntc;
    }

    /* (non-Javadoc)
     * @see org.apache.http.Header#getName()
     */
    public String getName() {
        return "Authorization";
    }

    /* (non-Javadoc)
     * @see org.apache.http.Header#getValue()
     */
    public String getValue() {
        request.removeHeader(this);
        try {
            return "NTLM " + new JCIFSEngine().generateType1Msg(ntc.getDomain(), ntc.getWorkstation());
        } catch(NTLMEngineException e) {
            return "Failed";
        }
    }

    /* (non-Javadoc)
     * @see org.apache.http.Header#getElements()
     */
    public HeaderElement[] getElements() throws ParseException {
        return null;
    }
}

この使用法では:

NTCredentials ntc = new NTCredentials("example.com/user:password");
httpPost.addHeader(new PreemptiveNTLMHeader(httpPost, ntc));

そのため、DefaultHttpClientAuthorization: NTLM AAA...は最初の要求をスキップするヘッダーを送信します。このヘッダーを最初に使用した後、このヘッダーはそれ自体を削除して、このダミー ヘッダーが実際の認証プロセスを上書きしないようにします。これは私にとってはうまくいきます。

于 2012-12-13T08:39:42.337 に答える
-1

NTLM 認証は、プリエンプティブに実行できません。これは、複数 (3) のメッセージ交換を伴う複雑なスキームです。

于 2012-12-12T14:32:46.920 に答える