1

使用的Webservice是:https://domain.name.com/EWS/Exchange.asmx,在soapUI中完美工作。對於AuthScope,也試過new AuthScope(AuthScope.ANY_HOST, AuthScope.ANY_PORT),但沒有運氣。在Android SDK(使用4.2.2)HttpClient基本搶先認證與HttpPost總是返回401

下面的代碼是基於ClientPreemptiveBasicAuthentication.java的版本4.0.3中的Apache示例代碼。在http://archive.apache.org/dist/httpcomponents/httpclient/source/

private void callBasicAuthencationWebService() { 
    DefaultHttpClient httpclient = new DefaultHttpClient(); 

    Credentials creds = new UsernamePasswordCredentials(username, password); 

    httpclient.getCredentialsProvider().setCredentials(
      new AuthScope("domain.name.com", 443), 
      creds); 

    BasicHttpContext localcontext = new BasicHttpContext(); 

    // Generate BASIC scheme object and stick it to the local 
    // execution context 
    BasicScheme basicAuth = new BasicScheme(); 
    localcontext.setAttribute("preemptive-auth", basicAuth); 

    HttpHost targetHost = new HttpHost("domain.name.com", 443, "https"); 

    HttpPost httppost = new HttpPost(urlString); 
    // add headers 
    httppost.setHeader("soapaction", soapAction); 
    httppost.setHeader("Content-Type", "text/xml; charset=utf-8"); 

    try { 
     httppost.setEntity(new StringEntity(envelope)); 
     //httppost.addHeader(BasicScheme.authenticate(creds,"US-ASCII",false)); 
     Header bs = new BasicScheme().authenticate(creds, httppost); 
     httppost.addHeader("Proxy-Authorization", bs.getValue()); 
    } 
    catch (Exception e) { 
     System.out.println(e.toString()); 
    } 

    // Add as the first request interceptor 
    httpclient.addRequestInterceptor(new PreemptiveAuth(), 0); 

    System.out.println("executing request: " + httppost.getRequestLine()); 
    System.out.println("to target: " + targetHost); 

    for (int i = 0; i < 3; i++) { 
     try { 
     HttpResponse response = httpclient.execute(targetHost, httppost, localcontext); 
     HttpEntity entity = response.getEntity(); 

     System.out.println("----------------------------------------"); 
     StatusLine statusLine = response.getStatusLine(); 
     int statusCode = statusLine.getStatusCode(); 
     String statusMessage = statusLine.getReasonPhrase(); 
     System.out.println("Status Code: " + statusCode + statusMessage); 

     if (entity != null) { 
      System.out.println("Response content length: " + entity.getContentLength()); 
      entity.consumeContent(); 
     } 
     } catch (Exception e) { 
      System.out.println(e.toString()); 
     } 
    } 

    // When HttpClient instance is no longer needed, 
    // shut down the connection manager to ensure 
    // immediate deallocation of all system resources 
    httpclient.getConnectionManager().shutdown();   
} 

PreemptiveAuth內部類,使用HttpRequestInterceptor

static class PreemptiveAuth implements HttpRequestInterceptor { 

    public void process(
      final HttpRequest request, 
      final HttpContext context) throws HttpException, IOException { 

     AuthState authState = (AuthState) context.getAttribute(
       ClientContext.TARGET_AUTH_STATE); 

     // If no auth scheme avaialble yet, try to initialize it preemptively 
     if (authState.getAuthScheme() == null) { 
      AuthScheme authScheme = (AuthScheme) context.getAttribute(
        "preemptive-auth"); 
      CredentialsProvider credsProvider = (CredentialsProvider) context.getAttribute(
        ClientContext.CREDS_PROVIDER); 
      HttpHost targetHost = (HttpHost) context.getAttribute(
        ExecutionContext.HTTP_TARGET_HOST); 
      if (authScheme != null) { 
       Credentials creds = credsProvider.getCredentials(
         new AuthScope(
           targetHost.getHostName(), 
           targetHost.getPort())); 
       if (creds == null) { 
        throw new HttpException("No credentials for preemptive authentication"); 
       } 
       authState.setAuthScheme(authScheme); 
       authState.setCredentials(creds); 
      } 
     } 

    } 
} 

回答

0

其NTLM基於Web服務調用。您可以使用以下代碼連接到Web服務。

  HttpClient httpclient = new DefaultHttpClient(); 
      ((AbstractHttpClient) httpclient).getAuthSchemes().register("ntlm",new NTLMSchemeFactory()); 

      NTCredentials creds = new NTCredentials("username", "password", "", "domain"); 

      ((AbstractHttpClient) httpclient).getCredentialsProvider().setCredentials(AuthScope.ANY, creds); 
      HttpConnectionParams.setConnectionTimeout(httpclient.getParams(), 5000); 

      HttpPost httppost = new HttpPost("https://domain.xxx.com/EWS/Exchange.asmx"); 
      httppost.getParams().setBooleanParameter(CoreProtocolPNames.USE_EXPECT_CONTINUE, false); 

      try { 
       StringBuffer sbnew = new StringBuffer(); 
       sbnew.append("your soap request body"); 
       StringEntity se = new StringEntity(sbnew.toString(), HTTP.UTF_8); 
       se.setContentType("text/xml"); 
       httppost.setEntity(se); 

       HttpResponse httpresponse = httpclient.execute(httppost); 
       HttpEntity resEntity = httpresponse.getEntity(); 

       System.out.println("Status OK: \n" + EntityUtils.toString(resEntity)); 

      } catch (ClientProtocolException e) { 
       e.printStackTrace(); 
       System.out.println("Status NOT OK: \n" + e.getMessage()); 
      } catch (IOException e) { 
       e.printStackTrace(); 
       System.out.println("Status NOT OK: \n" + e.getMessage()); 
      } 

記得從以下鏈接 http://hc.apache.org/httpcomponents-client-ga/ntlm.html

+0

包括兩個類,如Apache的鏈接提示,改變代碼使用NTLMSchemeFactory包括JCIFS圖書館和它的作品! EWS webservice使用NTLM Scheme而不是BasicAuthScheme,我猜測任何微軟的webservice都會使用NTLMScheme。謝謝一堆! – user2205998 2013-03-28 14:22:48

+1

也找到:http://www.robertkuzma.com/2011/07/manipulating-sharepoint-list-items-with-android-java-and-ntlm-authentication/ – user2205998 2013-03-28 15:04:41

相關問題