1

NTLM을 사용하여 DefaultHttpClient에 대한 선제 인증을 구현하려고합니다. 나는 정상적인 인증을 위해 잘 작동하는 Dan Hounshell에서 도서관을 발견했다.DefaultHttpClient를 통한 선점 인증

하지만 선제 인증으로이 작업을 수행하는 방법을 알아낼 수는 없습니다. 나는이 멋진 answer에 질문 Preemptive Basic authentication with Apache HttpClient 4을 발견 : 내 문제지만 좋은 아이디어

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

완벽하지. 그래서 NTLMSchemeFactory을 사용하여 AuthScheme의 새 인스턴스를 만들어 내고 authenticate 함수를 제공합니다.

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

이 기능은 내가 예외거야 호출 될 때 :

org.apache.http.auth.AuthenticationException을 : 예기치 않은 상태 : 미숙

나는 것을 해결할 수있는 방법을 ?

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=... 

나는 첫 번째 요청이 절대적으로 쓸모 없다고 생각합니다.

답변

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)); 

는 그래서 DefaultHttpClient가 초기 요청을 건너 뛰는 Authorization: NTLM AAA... 헤더를 보낼 것입니다. 이 헤더를 처음 사용하면이 헤더가 실제 인증 프로세스를 무시하지 않도록이 헤더가 자체 삭제됩니다. 이것은 나를 위해 작동합니다.

-1

우선적으로 NTLM 인증을 수행 할 수 없습니다. 그것은 다중 (3) 메시지 교환을 포함하는 복잡한 계획입니다.

+0

하지만 첫 번째 호출은 실제로 쓸모가 없으며 그와 같은 챌린지 응답이 없습니다. 내 업데이트를 참조하십시오. – rekire

+0

핸드 셰이크는 항상 클라이언트에게 요청하여 NTLM 서버에 의해 시작됩니다. 부담없이 사양을 참조하십시오. – oleg

+0

글쎄, 사양을 읽지는 않았지만, 그 통신을보고이 지식을 바탕으로 고객이 chellange 응답 인증에 사용되는 일종의 소금으로 시작한다고 생각합니다. 지금까지 Server가 NTLM을 지원한다고 알리는 부분은 건너 뛸 수 있다고 생각합니다. – rekire