Subversion Repositories javautils

Rev

Blame | Last modification | View Log | RSS feed

  1. /*
  2.  * ====================================================================
  3.  *
  4.  *  Licensed to the Apache Software Foundation (ASF) under one or more
  5.  *  contributor license agreements.  See the NOTICE file distributed with
  6.  *  this work for additional information regarding copyright ownership.
  7.  *  The ASF licenses this file to You under the Apache License, Version 2.0
  8.  *  (the "License"); you may not use this file except in compliance with
  9.  *  the License.  You may obtain a copy of the License at
  10.  *
  11.  *      http://www.apache.org/licenses/LICENSE-2.0
  12.  *
  13.  *  Unless required by applicable law or agreed to in writing, software
  14.  *  distributed under the License is distributed on an "AS IS" BASIS,
  15.  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  16.  *  See the License for the specific language governing permissions and
  17.  *  limitations under the License.
  18.  * ====================================================================
  19.  *
  20.  * This software consists of voluntary contributions made by many
  21.  * individuals on behalf of the Apache Software Foundation.  For more
  22.  * information on the Apache Software Foundation, please see
  23.  * <http://www.apache.org/>.
  24.  */
  25.  
  26. package org.apache.http.examples.client;
  27.  
  28. import java.io.IOException;
  29.  
  30. import org.apache.http.HttpEntity;
  31. import org.apache.http.HttpException;
  32. import org.apache.http.HttpHost;
  33. import org.apache.http.HttpRequest;
  34. import org.apache.http.HttpRequestInterceptor;
  35. import org.apache.http.HttpResponse;
  36. import org.apache.http.HttpResponseInterceptor;
  37. import org.apache.http.auth.AuthScheme;
  38. import org.apache.http.auth.AuthScope;
  39. import org.apache.http.auth.AuthState;
  40. import org.apache.http.auth.Credentials;
  41. import org.apache.http.auth.UsernamePasswordCredentials;
  42. import org.apache.http.client.CredentialsProvider;
  43. import org.apache.http.client.methods.HttpGet;
  44. import org.apache.http.client.protocol.ClientContext;
  45. import org.apache.http.impl.auth.DigestScheme;
  46. import org.apache.http.impl.client.DefaultHttpClient;
  47. import org.apache.http.protocol.BasicHttpContext;
  48. import org.apache.http.protocol.ExecutionContext;
  49. import org.apache.http.protocol.HttpContext;
  50.  
  51. /**
  52.  * An example of HttpClient can be customized to authenticate
  53.  * preemptively using DIGEST scheme.
  54.  * <b/>
  55.  * Generally, preemptive authentication can be considered less
  56.  * secure than a response to an authentication challenge
  57.  * and therefore discouraged.
  58.  * <b/>
  59.  * This code is NOT officially supported! Use at your risk.
  60.  */
  61. public class ClientPreemptiveDigestAuthentication {
  62.  
  63.     public static void main(String[] args) throws Exception {
  64.  
  65.         DefaultHttpClient httpclient = new DefaultHttpClient();
  66.  
  67.         httpclient.getCredentialsProvider().setCredentials(
  68.                 new AuthScope("localhost", 80),
  69.                 new UsernamePasswordCredentials("username", "password"));
  70.  
  71.         BasicHttpContext localcontext = new BasicHttpContext();
  72.         // Generate DIGEST scheme object, initialize it and stick it to
  73.         // the local execution context
  74.         DigestScheme digestAuth = new DigestScheme();
  75.         // Suppose we already know the realm name
  76.         digestAuth.overrideParamter("realm", "some realm");        
  77.         // Suppose we already know the expected nonce value
  78.         digestAuth.overrideParamter("nonce", "whatever");        
  79.         localcontext.setAttribute("preemptive-auth", digestAuth);
  80.        
  81.         // Add as the first request interceptor
  82.         httpclient.addRequestInterceptor(new PreemptiveAuth(), 0);
  83.         // Add as the last response interceptor
  84.         httpclient.addResponseInterceptor(new PersistentDigest());
  85.        
  86.         HttpHost targetHost = new HttpHost("localhost", 80, "http");
  87.  
  88.         HttpGet httpget = new HttpGet("/");
  89.  
  90.         System.out.println("executing request: " + httpget.getRequestLine());
  91.         System.out.println("to target: " + targetHost);
  92.        
  93.         for (int i = 0; i < 3; i++) {
  94.             HttpResponse response = httpclient.execute(targetHost, httpget, localcontext);
  95.             HttpEntity entity = response.getEntity();
  96.  
  97.             System.out.println("----------------------------------------");
  98.             System.out.println(response.getStatusLine());
  99.             if (entity != null) {
  100.                 System.out.println("Response content length: " + entity.getContentLength());
  101.                 entity.consumeContent();
  102.             }
  103.         }
  104.        
  105.         // When HttpClient instance is no longer needed,
  106.         // shut down the connection manager to ensure
  107.         // immediate deallocation of all system resources
  108.         httpclient.getConnectionManager().shutdown();        
  109.     }
  110.    
  111.     static class PreemptiveAuth implements HttpRequestInterceptor {
  112.  
  113.         public void process(
  114.                 final HttpRequest request,
  115.                 final HttpContext context) throws HttpException, IOException {
  116.            
  117.             AuthState authState = (AuthState) context.getAttribute(
  118.                     ClientContext.TARGET_AUTH_STATE);
  119.            
  120.             // If no auth scheme avaialble yet, try to initialize it preemptively
  121.             if (authState.getAuthScheme() == null) {
  122.                 AuthScheme authScheme = (AuthScheme) context.getAttribute(
  123.                         "preemptive-auth");
  124.                 CredentialsProvider credsProvider = (CredentialsProvider) context.getAttribute(
  125.                         ClientContext.CREDS_PROVIDER);
  126.                 HttpHost targetHost = (HttpHost) context.getAttribute(
  127.                         ExecutionContext.HTTP_TARGET_HOST);
  128.                 if (authScheme != null) {
  129.                     Credentials creds = credsProvider.getCredentials(
  130.                             new AuthScope(
  131.                                     targetHost.getHostName(),
  132.                                     targetHost.getPort()));
  133.                     if (creds == null) {
  134.                         throw new HttpException("No credentials for preemptive authentication");
  135.                     }
  136.                     authState.setAuthScheme(authScheme);
  137.                     authState.setCredentials(creds);
  138.                 }
  139.             }
  140.            
  141.         }
  142.        
  143.     }
  144.  
  145.     static class PersistentDigest implements HttpResponseInterceptor {
  146.  
  147.         public void process(
  148.                 final HttpResponse response,
  149.                 final HttpContext context) throws HttpException, IOException {
  150.             AuthState authState = (AuthState) context.getAttribute(
  151.                     ClientContext.TARGET_AUTH_STATE);
  152.             if (authState != null) {
  153.                 AuthScheme authScheme = authState.getAuthScheme();
  154.                 // Stick the auth scheme to the local context, so
  155.                 // we could try to authenticate subsequent requests
  156.                 // preemptively
  157.                 if (authScheme instanceof DigestScheme) {
  158.                     context.setAttribute("preemptive-auth", authScheme);
  159.                 }
  160.             }
  161.         }
  162.        
  163.     }
  164.    
  165. }
  166.