Ported UsernamePasswordCredentials, BasicScheme and related test cases from Commons HttpClient
git-svn-id: https://svn.apache.org/repos/asf/jakarta/httpcomponents/httpclient/trunk@527146 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
f9ff925e2d
commit
ab199c3513
|
@ -0,0 +1,180 @@
|
||||||
|
/*
|
||||||
|
* $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.auth;
|
||||||
|
|
||||||
|
import org.apache.http.util.LangUtils;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>Username and password {@link Credentials}.</p>
|
||||||
|
*
|
||||||
|
* @author <a href="mailto:remm@apache.org">Remy Maucherat</a>
|
||||||
|
* @author Sean C. Sullivan
|
||||||
|
* @author <a href="mailto:mbowler@GargoyleSoftware.com">Mike Bowler</a>
|
||||||
|
* @author <a href="mailto:oleg@ural.ru">Oleg Kalnichevski</a>
|
||||||
|
*
|
||||||
|
* @version $Revision$ $Date$
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class UsernamePasswordCredentials implements Credentials {
|
||||||
|
|
||||||
|
// ----------------------------------------------------------- Constructors
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The constructor with the username and password combined string argument.
|
||||||
|
*
|
||||||
|
* @param usernamePassword the username:password formed string
|
||||||
|
* @see #toString
|
||||||
|
*/
|
||||||
|
public UsernamePasswordCredentials(String usernamePassword) {
|
||||||
|
super();
|
||||||
|
if (usernamePassword == null) {
|
||||||
|
throw new IllegalArgumentException("Username:password string may not be null");
|
||||||
|
}
|
||||||
|
int atColon = usernamePassword.indexOf(':');
|
||||||
|
if (atColon >= 0) {
|
||||||
|
this.userName = usernamePassword.substring(0, atColon);
|
||||||
|
this.password = usernamePassword.substring(atColon + 1);
|
||||||
|
} else {
|
||||||
|
this.userName = usernamePassword;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The constructor with the username and password arguments.
|
||||||
|
*
|
||||||
|
* @param userName the user name
|
||||||
|
* @param password the password
|
||||||
|
*/
|
||||||
|
public UsernamePasswordCredentials(String userName, String password) {
|
||||||
|
super();
|
||||||
|
if (userName == null) {
|
||||||
|
throw new IllegalArgumentException("Username may not be null");
|
||||||
|
}
|
||||||
|
this.userName = userName;
|
||||||
|
this.password = password;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------- Instance Variables
|
||||||
|
|
||||||
|
/**
|
||||||
|
* User name.
|
||||||
|
*/
|
||||||
|
private String userName;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Password.
|
||||||
|
*/
|
||||||
|
private String password;
|
||||||
|
|
||||||
|
|
||||||
|
// ------------------------------------------------------------- Properties
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* User name property getter.
|
||||||
|
*
|
||||||
|
* @return the userName
|
||||||
|
* @see #setUserName(String)
|
||||||
|
*/
|
||||||
|
public String getUserName() {
|
||||||
|
return userName;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Password property getter.
|
||||||
|
*
|
||||||
|
* @return the password
|
||||||
|
* @see #setPassword(String)
|
||||||
|
*/
|
||||||
|
public String getPassword() {
|
||||||
|
return password;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public String toText() {
|
||||||
|
return toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get this object string.
|
||||||
|
*
|
||||||
|
* @return the username:password formed string
|
||||||
|
*/
|
||||||
|
public String toString() {
|
||||||
|
StringBuffer result = new StringBuffer();
|
||||||
|
result.append(this.userName);
|
||||||
|
result.append(":");
|
||||||
|
result.append((this.password == null) ? "null" : this.password);
|
||||||
|
return result.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Does a hash of both user name and password.
|
||||||
|
*
|
||||||
|
* @return The hash code including user name and password.
|
||||||
|
*/
|
||||||
|
public int hashCode() {
|
||||||
|
int hash = LangUtils.HASH_SEED;
|
||||||
|
hash = LangUtils.hashCode(hash, this.userName);
|
||||||
|
hash = LangUtils.hashCode(hash, this.password);
|
||||||
|
return hash;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* These credentials are assumed equal if the username and password are the
|
||||||
|
* same.
|
||||||
|
*
|
||||||
|
* @param o The other object to compare with.
|
||||||
|
*
|
||||||
|
* @return <code>true</code> if the object is equivalent.
|
||||||
|
*/
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (o == null) return false;
|
||||||
|
if (this == o) return true;
|
||||||
|
// note - to allow for sub-classing, this checks that class is the same
|
||||||
|
// rather than do "instanceof".
|
||||||
|
if (this.getClass().equals(o.getClass())) {
|
||||||
|
UsernamePasswordCredentials that = (UsernamePasswordCredentials) o;
|
||||||
|
|
||||||
|
if (LangUtils.equals(this.userName, that.userName)
|
||||||
|
&& LangUtils.equals(this.password, that.password) ) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -84,8 +84,10 @@ public abstract class RFC2617Scheme implements AuthScheme {
|
||||||
if (header == null) {
|
if (header == null) {
|
||||||
throw new IllegalArgumentException("Header may not be null");
|
throw new IllegalArgumentException("Header may not be null");
|
||||||
}
|
}
|
||||||
if (!header.getName().equalsIgnoreCase(HTTPAuth.WWW_AUTH)) {
|
String authheader = header.getName();
|
||||||
throw new MalformedChallengeException("Unexpected header name: " + header.getName());
|
if (!authheader.equalsIgnoreCase(HTTPAuth.WWW_AUTH)
|
||||||
|
&& !authheader.equalsIgnoreCase(HTTPAuth.PROXY_AUTH)) {
|
||||||
|
throw new MalformedChallengeException("Unexpected header name: " + authheader);
|
||||||
}
|
}
|
||||||
CharArrayBuffer buffer;
|
CharArrayBuffer buffer;
|
||||||
int pos;
|
int pos;
|
||||||
|
@ -114,6 +116,10 @@ public abstract class RFC2617Scheme implements AuthScheme {
|
||||||
throw new MalformedChallengeException("Invalid scheme identifier: " + s);
|
throw new MalformedChallengeException("Invalid scheme identifier: " + s);
|
||||||
}
|
}
|
||||||
HeaderElement[] elements = BasicHeaderElement.parseAll(buffer, pos, buffer.length());
|
HeaderElement[] elements = BasicHeaderElement.parseAll(buffer, pos, buffer.length());
|
||||||
|
if (elements.length == 0) {
|
||||||
|
throw new MalformedChallengeException("Authentication challenge is empty");
|
||||||
|
}
|
||||||
|
|
||||||
this.params = new HashMap(elements.length);
|
this.params = new HashMap(elements.length);
|
||||||
for (int i = 0; i < elements.length; i++) {
|
for (int i = 0; i < elements.length; i++) {
|
||||||
HeaderElement element = elements[i];
|
HeaderElement element = elements[i];
|
||||||
|
|
|
@ -44,6 +44,7 @@ public class TestAllAuthImpl extends TestCase {
|
||||||
TestSuite suite = new TestSuite();
|
TestSuite suite = new TestSuite();
|
||||||
|
|
||||||
suite.addTest(TestRFC2617Scheme.suite());
|
suite.addTest(TestRFC2617Scheme.suite());
|
||||||
|
suite.addTest(TestBasicAuth.suite());
|
||||||
|
|
||||||
return suite;
|
return suite;
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,121 @@
|
||||||
|
/*
|
||||||
|
* $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.impl.auth;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import junit.framework.Test;
|
||||||
|
import junit.framework.TestCase;
|
||||||
|
import junit.framework.TestSuite;
|
||||||
|
|
||||||
|
import org.apache.commons.codec.binary.Base64;
|
||||||
|
import org.apache.http.Header;
|
||||||
|
import org.apache.http.HttpMessage;
|
||||||
|
import org.apache.http.HttpVersion;
|
||||||
|
import org.apache.http.auth.AuthScheme;
|
||||||
|
import org.apache.http.auth.HTTPAuth;
|
||||||
|
import org.apache.http.auth.MalformedChallengeException;
|
||||||
|
import org.apache.http.auth.UsernamePasswordCredentials;
|
||||||
|
import org.apache.http.message.BasicHeader;
|
||||||
|
import org.apache.http.message.BasicHttpResponse;
|
||||||
|
import org.apache.http.util.EncodingUtils;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Basic authentication test cases.
|
||||||
|
*
|
||||||
|
* @author Oleg Kalnichevski
|
||||||
|
*
|
||||||
|
* @version $Id$
|
||||||
|
*/
|
||||||
|
public class TestBasicAuth extends TestCase {
|
||||||
|
|
||||||
|
// ------------------------------------------------------------ Constructor
|
||||||
|
public TestBasicAuth(final String testName) throws IOException {
|
||||||
|
super(testName);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------- Main
|
||||||
|
public static void main(String args[]) {
|
||||||
|
String[] testCaseName = { TestBasicAuth.class.getName() };
|
||||||
|
junit.textui.TestRunner.main(testCaseName);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------- TestCase Methods
|
||||||
|
|
||||||
|
public static Test suite() {
|
||||||
|
TestSuite suite = new TestSuite(TestBasicAuth.class);
|
||||||
|
return suite;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testBasicAuthenticationWithNoRealm() {
|
||||||
|
String challenge = "Basic";
|
||||||
|
Header header = new BasicHeader(HTTPAuth.WWW_AUTH, challenge);
|
||||||
|
try {
|
||||||
|
AuthScheme authscheme = new BasicScheme();
|
||||||
|
authscheme.processChallenge(header);
|
||||||
|
fail("Should have thrown MalformedChallengeException");
|
||||||
|
} catch(MalformedChallengeException e) {
|
||||||
|
// expected
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testBasicAuthenticationWith88591Chars() throws Exception {
|
||||||
|
int[] germanChars = { 0xE4, 0x2D, 0xF6, 0x2D, 0xFc };
|
||||||
|
StringBuffer buffer = new StringBuffer();
|
||||||
|
for (int i = 0; i < germanChars.length; i++) {
|
||||||
|
buffer.append((char)germanChars[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
UsernamePasswordCredentials credentials = new UsernamePasswordCredentials("dh", buffer.toString());
|
||||||
|
Header header = BasicScheme.authenticate(credentials, "ISO-8859-1");
|
||||||
|
assertEquals("Basic ZGg65C32Lfw=", header.getValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testBasicAuthentication() throws Exception {
|
||||||
|
UsernamePasswordCredentials creds =
|
||||||
|
new UsernamePasswordCredentials("testuser", "testpass");
|
||||||
|
|
||||||
|
Header challenge = new BasicHeader(HTTPAuth.WWW_AUTH, "Basic realm=\"test\"");
|
||||||
|
|
||||||
|
BasicScheme authscheme = new BasicScheme();
|
||||||
|
authscheme.processChallenge(challenge);
|
||||||
|
|
||||||
|
HttpMessage message = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK");
|
||||||
|
Header authResponse = authscheme.authenticate(creds, message);
|
||||||
|
|
||||||
|
String expected = "Basic " + EncodingUtils.getAsciiString(
|
||||||
|
Base64.encodeBase64(EncodingUtils.getAsciiBytes("testuser:testpass")));
|
||||||
|
assertEquals(expected, authResponse.getValue());
|
||||||
|
assertEquals("test", authscheme.getRealm());
|
||||||
|
assertTrue(authscheme.isComplete());
|
||||||
|
assertFalse(authscheme.isConnectionBased());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -37,6 +37,8 @@ import org.apache.http.auth.Credentials;
|
||||||
import org.apache.http.auth.HTTPAuth;
|
import org.apache.http.auth.HTTPAuth;
|
||||||
import org.apache.http.auth.MalformedChallengeException;
|
import org.apache.http.auth.MalformedChallengeException;
|
||||||
import org.apache.http.message.BasicHeader;
|
import org.apache.http.message.BasicHeader;
|
||||||
|
import org.apache.http.message.BufferedHeader;
|
||||||
|
import org.apache.http.util.CharArrayBuffer;
|
||||||
|
|
||||||
import junit.framework.Test;
|
import junit.framework.Test;
|
||||||
import junit.framework.TestCase;
|
import junit.framework.TestCase;
|
||||||
|
@ -97,7 +99,9 @@ public class TestRFC2617Scheme extends TestCase {
|
||||||
|
|
||||||
public void testProcessChallengeWithLotsOfBlanks() throws Exception {
|
public void testProcessChallengeWithLotsOfBlanks() throws Exception {
|
||||||
TestAuthScheme authscheme = new TestAuthScheme();
|
TestAuthScheme authscheme = new TestAuthScheme();
|
||||||
Header header = new BasicHeader(HTTPAuth.WWW_AUTH, " Test realm=\"realm1\"");
|
CharArrayBuffer buffer = new CharArrayBuffer(32);
|
||||||
|
buffer.append(" WWW-Authenticate: Test realm=\"realm1\"");
|
||||||
|
Header header = new BufferedHeader(buffer);
|
||||||
|
|
||||||
authscheme.processChallenge(header);
|
authscheme.processChallenge(header);
|
||||||
|
|
||||||
|
@ -116,6 +120,17 @@ public class TestRFC2617Scheme extends TestCase {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testEmptyHeader() throws Exception {
|
||||||
|
TestAuthScheme authscheme = new TestAuthScheme();
|
||||||
|
Header header = new BasicHeader(HTTPAuth.WWW_AUTH, "Test ");
|
||||||
|
try {
|
||||||
|
authscheme.processChallenge(header);
|
||||||
|
fail("MalformedChallengeException should have been thrown");
|
||||||
|
} catch (MalformedChallengeException ex) {
|
||||||
|
//expected
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void testInvalidHeaderValue() throws Exception {
|
public void testInvalidHeaderValue() throws Exception {
|
||||||
TestAuthScheme authscheme = new TestAuthScheme();
|
TestAuthScheme authscheme = new TestAuthScheme();
|
||||||
Header header = new BasicHeader("whatever", "whatever");
|
Header header = new BasicHeader("whatever", "whatever");
|
||||||
|
|
Loading…
Reference in New Issue