在Android SDK中(使用4.2.2)HttpClient Basic preemptive-auth与HttpPost一起返回401

时间:2013-03-27 18:38:23

标签: android http-post httpclient exchangewebservices preemptive

使用的Webservice是:https://domain.name.com/EWS/Exchange.asmx,在soapUI中完美运行。对于AuthScope,也试过new AuthScope(AuthScope.ANY_HOST, AuthScope.ANY_PORT)但没有运气。

下面的代码基于ClientPreemptiveBasicAuthentication.java版本4.0.3的HttpClient中的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);
            }
        }

    }
}

1 个答案:

答案 0 :(得分:0)

基于NTLM的webservice调用。您可以使用以下代码连接到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());
            }

请记住从以下链接中包含JCIFS库 http://hc.apache.org/httpcomponents-client-ga/ntlm.html