You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hc.apache.org by ol...@apache.org on 2008/05/23 18:47:14 UTC

svn commit: r659595 - in /httpcomponents/httpclient/trunk: ./ module-client/src/examples/org/apache/http/examples/client/ module-client/src/main/java/org/apache/http/client/params/ module-client/src/main/java/org/apache/http/impl/auth/

Author: olegk
Date: Fri May 23 09:47:14 2008
New Revision: 659595

URL: http://svn.apache.org/viewvc?rev=659595&view=rev
Log:
HTTPCLIENT-424: Preemptive authentication no longer limited to BASIC scheme only. HttpClient can be customized to authenticate preemptively with DIGEST scheme

Added:
    httpcomponents/httpclient/trunk/module-client/src/examples/org/apache/http/examples/client/ClientPreemptiveBasicAuthentication.java   (with props)
    httpcomponents/httpclient/trunk/module-client/src/examples/org/apache/http/examples/client/ClientPreemptiveDigestAuthentication.java   (with props)
Modified:
    httpcomponents/httpclient/trunk/RELEASE_NOTES.txt
    httpcomponents/httpclient/trunk/module-client/src/main/java/org/apache/http/client/params/ClientPNames.java
    httpcomponents/httpclient/trunk/module-client/src/main/java/org/apache/http/client/params/ClientParamBean.java
    httpcomponents/httpclient/trunk/module-client/src/main/java/org/apache/http/client/params/HttpClientParams.java
    httpcomponents/httpclient/trunk/module-client/src/main/java/org/apache/http/impl/auth/DigestScheme.java
    httpcomponents/httpclient/trunk/module-client/src/main/java/org/apache/http/impl/auth/RFC2617Scheme.java

Modified: httpcomponents/httpclient/trunk/RELEASE_NOTES.txt
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/trunk/RELEASE_NOTES.txt?rev=659595&r1=659594&r2=659595&view=diff
==============================================================================
--- httpcomponents/httpclient/trunk/RELEASE_NOTES.txt (original)
+++ httpcomponents/httpclient/trunk/RELEASE_NOTES.txt Fri May 23 09:47:14 2008
@@ -1,6 +1,11 @@
 Changes since 4.0 Alpha 4
 -------------------
 
+* [HTTPCLIENT-424] Preemptive authentication no longer limited to BASIC
+  scheme only. HttpClient can be customized to authenticate preemptively
+  with DIGEST scheme.
+  Contributed by Oleg Kalnichevski <olegk at apache.org>
+
 * [HTTPCLIENT-670] Pluggable hostname resolver.
   Contributed by Oleg Kalnichevski <olegk at apache.org>
 

Added: httpcomponents/httpclient/trunk/module-client/src/examples/org/apache/http/examples/client/ClientPreemptiveBasicAuthentication.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/trunk/module-client/src/examples/org/apache/http/examples/client/ClientPreemptiveBasicAuthentication.java?rev=659595&view=auto
==============================================================================
--- httpcomponents/httpclient/trunk/module-client/src/examples/org/apache/http/examples/client/ClientPreemptiveBasicAuthentication.java (added)
+++ httpcomponents/httpclient/trunk/module-client/src/examples/org/apache/http/examples/client/ClientPreemptiveBasicAuthentication.java Fri May 23 09:47:14 2008
@@ -0,0 +1,137 @@
+/*
+ * $HeadURL:$
+ * $Revision:$
+ * $Date:$
+ * ====================================================================
+ *
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ */
+
+package org.apache.http.examples.client;
+
+import java.io.IOException;
+
+import org.apache.http.HttpEntity;
+import org.apache.http.HttpException;
+import org.apache.http.HttpHost;
+import org.apache.http.HttpRequest;
+import org.apache.http.HttpRequestInterceptor;
+import org.apache.http.HttpResponse;
+import org.apache.http.auth.AuthScheme;
+import org.apache.http.auth.AuthScope;
+import org.apache.http.auth.Credentials;
+import org.apache.http.auth.UsernamePasswordCredentials;
+import org.apache.http.client.AuthState;
+import org.apache.http.client.CredentialsProvider;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.client.protocol.ClientContext;
+import org.apache.http.impl.auth.BasicScheme;
+import org.apache.http.impl.client.DefaultHttpClient;
+import org.apache.http.protocol.BasicHttpContext;
+import org.apache.http.protocol.ExecutionContext;
+import org.apache.http.protocol.HttpContext;
+
+/**
+ * An example of HttpClient can be customized to authenticate 
+ * preemptively using BASIC scheme.
+ * <b/>
+ * Generally, preemptive authentication can be considered less
+ * secure than a response to an authentication challenge
+ * and therefore discouraged.
+ * <b/>
+ * This code is NOT officially supported! Use at your risk.
+ */
+public class ClientPreemptiveBasicAuthentication {
+
+    public static void main(String[] args) throws Exception {
+
+        DefaultHttpClient httpclient = new DefaultHttpClient();
+
+        httpclient.getCredentialsProvider().setCredentials(
+                new AuthScope("localhost", 80), 
+                new UsernamePasswordCredentials("username", "password"));
+
+        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);
+        
+        // Add as the first request interceptor
+        httpclient.addRequestInterceptor(new PreemptiveAuth(), 0);
+        
+        HttpHost targetHost = new HttpHost("localhost", 80, "http"); 
+
+        HttpGet httpget = new HttpGet("/");
+
+        System.out.println("executing request: " + httpget.getRequestLine());
+        System.out.println("to target: " + targetHost);
+        
+        for (int i = 0; i < 3; i++) {
+            HttpResponse response = httpclient.execute(targetHost, httpget, localcontext);
+            HttpEntity entity = response.getEntity();
+
+            System.out.println("----------------------------------------");
+            System.out.println(response.getStatusLine());
+            if (entity != null) {
+                System.out.println("Response content length: " + entity.getContentLength());
+                System.out.println("Chunked?: " + entity.isChunked());
+                entity.consumeContent();
+            }
+        }
+    }
+    
+    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);
+                }
+            }
+            
+        }
+        
+    }
+}

Propchange: httpcomponents/httpclient/trunk/module-client/src/examples/org/apache/http/examples/client/ClientPreemptiveBasicAuthentication.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: httpcomponents/httpclient/trunk/module-client/src/examples/org/apache/http/examples/client/ClientPreemptiveBasicAuthentication.java
------------------------------------------------------------------------------
    svn:keywords = Date Author Id Revision HeadURL

Propchange: httpcomponents/httpclient/trunk/module-client/src/examples/org/apache/http/examples/client/ClientPreemptiveBasicAuthentication.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: httpcomponents/httpclient/trunk/module-client/src/examples/org/apache/http/examples/client/ClientPreemptiveDigestAuthentication.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/trunk/module-client/src/examples/org/apache/http/examples/client/ClientPreemptiveDigestAuthentication.java?rev=659595&view=auto
==============================================================================
--- httpcomponents/httpclient/trunk/module-client/src/examples/org/apache/http/examples/client/ClientPreemptiveDigestAuthentication.java (added)
+++ httpcomponents/httpclient/trunk/module-client/src/examples/org/apache/http/examples/client/ClientPreemptiveDigestAuthentication.java Fri May 23 09:47:14 2008
@@ -0,0 +1,164 @@
+/*
+ * $HeadURL:$
+ * $Revision:$
+ * $Date:$
+ * ====================================================================
+ *
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ */
+
+package org.apache.http.examples.client;
+
+import java.io.IOException;
+
+import org.apache.http.HttpEntity;
+import org.apache.http.HttpException;
+import org.apache.http.HttpHost;
+import org.apache.http.HttpRequest;
+import org.apache.http.HttpRequestInterceptor;
+import org.apache.http.HttpResponse;
+import org.apache.http.HttpResponseInterceptor;
+import org.apache.http.auth.AuthScheme;
+import org.apache.http.auth.AuthScope;
+import org.apache.http.auth.Credentials;
+import org.apache.http.auth.UsernamePasswordCredentials;
+import org.apache.http.client.AuthState;
+import org.apache.http.client.CredentialsProvider;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.client.protocol.ClientContext;
+import org.apache.http.impl.auth.DigestScheme;
+import org.apache.http.impl.client.DefaultHttpClient;
+import org.apache.http.protocol.BasicHttpContext;
+import org.apache.http.protocol.ExecutionContext;
+import org.apache.http.protocol.HttpContext;
+
+/**
+ * An example of HttpClient can be customized to authenticate 
+ * preemptively using DIGEST scheme.
+ * <b/>
+ * Generally, preemptive authentication can be considered less
+ * secure than a response to an authentication challenge
+ * and therefore discouraged.
+ * <b/>
+ * This code is NOT officially supported! Use at your risk.
+ */
+public class ClientPreemptiveDigestAuthentication {
+
+    public static void main(String[] args) throws Exception {
+
+        DefaultHttpClient httpclient = new DefaultHttpClient();
+
+        httpclient.getCredentialsProvider().setCredentials(
+                new AuthScope("localhost", 80), 
+                new UsernamePasswordCredentials("username", "password"));
+
+        BasicHttpContext localcontext = new BasicHttpContext();
+        // Generate DIGEST scheme object, initialize it and stick it to 
+        // the local execution context
+        DigestScheme digestAuth = new DigestScheme();
+        // Suppose we already know the realm name
+        digestAuth.overrideParamter("realm", "some realm");        
+        // Suppose we already know the expected nonce value 
+        digestAuth.overrideParamter("nonce", "whatever");        
+        localcontext.setAttribute("preemptive-auth", digestAuth);
+        
+        // Add as the first request interceptor
+        httpclient.addRequestInterceptor(new PreemptiveAuth(), 0);
+        // Add as the last response interceptor
+        httpclient.addResponseInterceptor(new PersistentDigest());
+        
+        HttpHost targetHost = new HttpHost("localhost", 80, "http"); 
+
+        HttpGet httpget = new HttpGet("/");
+
+        System.out.println("executing request: " + httpget.getRequestLine());
+        System.out.println("to target: " + targetHost);
+        
+        for (int i = 0; i < 3; i++) {
+            HttpResponse response = httpclient.execute(targetHost, httpget, localcontext);
+            HttpEntity entity = response.getEntity();
+
+            System.out.println("----------------------------------------");
+            System.out.println(response.getStatusLine());
+            if (entity != null) {
+                System.out.println("Response content length: " + entity.getContentLength());
+                System.out.println("Chunked?: " + entity.isChunked());
+                entity.consumeContent();
+            }
+        }
+    }
+    
+    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);
+                }
+            }
+            
+        }
+        
+    }
+
+    static class PersistentDigest implements HttpResponseInterceptor {
+
+        public void process(
+                final HttpResponse response, 
+                final HttpContext context) throws HttpException, IOException {
+            AuthState authState = (AuthState) context.getAttribute(
+                    ClientContext.TARGET_AUTH_STATE);
+            if (authState != null) {
+                AuthScheme authScheme = authState.getAuthScheme();
+                // Stick the auth scheme to the local context, so
+                // we could try to authenticate subsequent requests
+                // preemptively
+                if (authScheme instanceof DigestScheme) {
+                    context.setAttribute("preemptive-auth", authScheme);
+                }
+            }
+        }
+        
+    }
+    
+}

Propchange: httpcomponents/httpclient/trunk/module-client/src/examples/org/apache/http/examples/client/ClientPreemptiveDigestAuthentication.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: httpcomponents/httpclient/trunk/module-client/src/examples/org/apache/http/examples/client/ClientPreemptiveDigestAuthentication.java
------------------------------------------------------------------------------
    svn:keywords = Date Author Id Revision HeadURL

Propchange: httpcomponents/httpclient/trunk/module-client/src/examples/org/apache/http/examples/client/ClientPreemptiveDigestAuthentication.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: httpcomponents/httpclient/trunk/module-client/src/main/java/org/apache/http/client/params/ClientPNames.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/trunk/module-client/src/main/java/org/apache/http/client/params/ClientPNames.java?rev=659595&r1=659594&r2=659595&view=diff
==============================================================================
--- httpcomponents/httpclient/trunk/module-client/src/main/java/org/apache/http/client/params/ClientPNames.java (original)
+++ httpcomponents/httpclient/trunk/module-client/src/main/java/org/apache/http/client/params/ClientPNames.java Fri May 23 09:47:14 2008
@@ -102,14 +102,6 @@
     public static final String HANDLE_AUTHENTICATION = "http.protocol.handle-authentication";
 
     /**
-     * Defines whether authentication should be attempted preemptively.
-     * <p>
-     * This parameter expects a value of type {@link Boolean}.
-     * </p>
-     */
-    public static final String PREEMPTIVE_AUTHENTICATION = "http.protocol.authentication-preemptive";
-
-    /**
      * Defines the name of the cookie specification to be used for HTTP state management.
      * <p>
      * This parameter expects a value of type {@link String}.

Modified: httpcomponents/httpclient/trunk/module-client/src/main/java/org/apache/http/client/params/ClientParamBean.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/trunk/module-client/src/main/java/org/apache/http/client/params/ClientParamBean.java?rev=659595&r1=659594&r2=659595&view=diff
==============================================================================
--- httpcomponents/httpclient/trunk/module-client/src/main/java/org/apache/http/client/params/ClientParamBean.java (original)
+++ httpcomponents/httpclient/trunk/module-client/src/main/java/org/apache/http/client/params/ClientParamBean.java Fri May 23 09:47:14 2008
@@ -73,10 +73,6 @@
         params.setBooleanParameter(ClientPNames.HANDLE_AUTHENTICATION, handle);
     }
 
-    public void setPreemptiveAuthentication (final boolean preemptive) {
-        params.setBooleanParameter(ClientPNames.PREEMPTIVE_AUTHENTICATION, preemptive);
-    }
-
     public void setCookiePolicy (final String policy) {
         params.setParameter(ClientPNames.COOKIE_POLICY, policy);
     }

Modified: httpcomponents/httpclient/trunk/module-client/src/main/java/org/apache/http/client/params/HttpClientParams.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/trunk/module-client/src/main/java/org/apache/http/client/params/HttpClientParams.java?rev=659595&r1=659594&r2=659595&view=diff
==============================================================================
--- httpcomponents/httpclient/trunk/module-client/src/main/java/org/apache/http/client/params/HttpClientParams.java (original)
+++ httpcomponents/httpclient/trunk/module-client/src/main/java/org/apache/http/client/params/HttpClientParams.java Fri May 23 09:47:14 2008
@@ -79,35 +79,6 @@
             (ClientPNames.HANDLE_AUTHENTICATION, value); 
     }
     
-    /**
-     * Returns <tt>true</tt> if authentication should be attempted preemptively, 
-     * <tt>false</tt> otherwise.
-     * 
-     * @return <tt>true</tt> if authentication should be attempted preemptively,
-     *   <tt>false</tt> otherwise.
-     */
-    public static boolean isAuthenticationPreemptive(final HttpParams params) {
-        if (params == null) {
-            throw new IllegalArgumentException("HTTP parameters may not be null");
-        }
-        return params.getBooleanParameter
-            (ClientPNames.PREEMPTIVE_AUTHENTICATION, false); 
-    }
-
-    /**
-     * Sets whether authentication should be attempted preemptively.
-     * 
-     * @param value <tt>true</tt> if authentication should be attempted preemptively,
-     *   <tt>false</tt> otherwise.
-     */
-    public static void setAuthenticationPreemptive(final HttpParams params, boolean value) {
-        if (params == null) {
-            throw new IllegalArgumentException("HTTP parameters may not be null");
-        }
-        params.setBooleanParameter
-            (ClientPNames.PREEMPTIVE_AUTHENTICATION, value); 
-    }
-    
     public static String getCookiePolicy(final HttpParams params) { 
         if (params == null) {
             throw new IllegalArgumentException("HTTP parameters may not be null");

Modified: httpcomponents/httpclient/trunk/module-client/src/main/java/org/apache/http/impl/auth/DigestScheme.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/trunk/module-client/src/main/java/org/apache/http/impl/auth/DigestScheme.java?rev=659595&r1=659594&r2=659595&view=diff
==============================================================================
--- httpcomponents/httpclient/trunk/module-client/src/main/java/org/apache/http/impl/auth/DigestScheme.java (original)
+++ httpcomponents/httpclient/trunk/module-client/src/main/java/org/apache/http/impl/auth/DigestScheme.java Fri May 23 09:47:14 2008
@@ -153,8 +153,8 @@
         if (unsupportedQop && (qopVariant == QOP_MISSING)) {
             throw new MalformedChallengeException("None of the qop methods is supported");   
         }
-        
-        cnonce = createCnonce();   
+        // Reset cnonce
+        this.cnonce = null;
         this.complete = true;
     }
 
@@ -191,6 +191,17 @@
         return false;    
     }
 
+    public void overrideParamter(final String name, final String value) {
+        getParameters().put(name, value);
+    }
+    
+    private String getCnonce() {
+        if (this.cnonce == null) {
+            this.cnonce = createCnonce();
+        }
+        return this.cnonce; 
+    }
+    
     /**
      * Produces a digest authorization string for the given set of 
      * {@link Credentials}, method name and URI.
@@ -253,6 +264,15 @@
         String nonce = getParameter("nonce");
         String method = getParameter("methodname");
         String algorithm = getParameter("algorithm");
+        if (uri == null) {
+            throw new IllegalStateException("URI may not be null");
+        }
+        if (realm == null) {
+            throw new IllegalStateException("Realm may not be null");
+        }
+        if (nonce == null) {
+            throw new IllegalStateException("Nonce may not be null");
+        }
         // If an algorithm is not specified, default to MD5.
         if (algorithm == null) {
             algorithm = "MD5";
@@ -282,12 +302,15 @@
         tmp.append(pwd);
         // unq(username-value) ":" unq(realm-value) ":" passwd
         String a1 = tmp.toString();
+        
         //a1 is suitable for MD5 algorithm
         if(algorithm.equals("MD5-sess")) {
             // H( unq(username-value) ":" unq(realm-value) ":" passwd )
             //      ":" unq(nonce-value)
             //      ":" unq(cnonce-value)
 
+            String cnonce = getCnonce();
+            
             String tmp2=encode(md5Helper.digest(EncodingUtils.getBytes(a1, charset)));
             StringBuilder tmp3 = new StringBuilder(tmp2.length() + nonce.length() + cnonce.length() + 2);
             tmp3.append(tmp2);
@@ -323,6 +346,8 @@
             serverDigestValue = tmp2.toString();
         } else {
             String qopOption = getQopVariantString();
+            String cnonce = getCnonce();
+            
             StringBuilder tmp2 = new StringBuilder(md5a1.length() + nonce.length()
                 + NC.length() + cnonce.length() + qopOption.length() + md5a2.length() + 5);
             tmp2.append(md5a1);
@@ -384,7 +409,7 @@
         if (qopVariant != QOP_MISSING) {
             params.add(new BasicNameValuePair("qop", getQopVariantString()));
             params.add(new BasicNameValuePair("nc", NC));
-            params.add(new BasicNameValuePair("cnonce", this.cnonce));
+            params.add(new BasicNameValuePair("cnonce", getCnonce()));
         }
         if (algorithm != null) {
             params.add(new BasicNameValuePair("algorithm", algorithm));

Modified: httpcomponents/httpclient/trunk/module-client/src/main/java/org/apache/http/impl/auth/RFC2617Scheme.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/trunk/module-client/src/main/java/org/apache/http/impl/auth/RFC2617Scheme.java?rev=659595&r1=659594&r2=659595&view=diff
==============================================================================
--- httpcomponents/httpclient/trunk/module-client/src/main/java/org/apache/http/impl/auth/RFC2617Scheme.java (original)
+++ httpcomponents/httpclient/trunk/module-client/src/main/java/org/apache/http/impl/auth/RFC2617Scheme.java Fri May 23 09:47:14 2008
@@ -84,6 +84,9 @@
      * @return the map of authentication parameters
      */
     protected Map<String, String> getParameters() {
+        if (this.params == null) {
+            this.params = new HashMap<String, String>();
+        }
         return this.params;
     }