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) {
|
||||
throw new IllegalArgumentException("Header may not be null");
|
||||
}
|
||||
if (!header.getName().equalsIgnoreCase(HTTPAuth.WWW_AUTH)) {
|
||||
throw new MalformedChallengeException("Unexpected header name: " + header.getName());
|
||||
String authheader = header.getName();
|
||||
if (!authheader.equalsIgnoreCase(HTTPAuth.WWW_AUTH)
|
||||
&& !authheader.equalsIgnoreCase(HTTPAuth.PROXY_AUTH)) {
|
||||
throw new MalformedChallengeException("Unexpected header name: " + authheader);
|
||||
}
|
||||
CharArrayBuffer buffer;
|
||||
int pos;
|
||||
|
@ -114,6 +116,10 @@ public abstract class RFC2617Scheme implements AuthScheme {
|
|||
throw new MalformedChallengeException("Invalid scheme identifier: " + s);
|
||||
}
|
||||
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);
|
||||
for (int i = 0; i < elements.length; i++) {
|
||||
HeaderElement element = elements[i];
|
||||
|
|
|
@ -44,6 +44,7 @@ public class TestAllAuthImpl extends TestCase {
|
|||
TestSuite suite = new TestSuite();
|
||||
|
||||
suite.addTest(TestRFC2617Scheme.suite());
|
||||
suite.addTest(TestBasicAuth.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.MalformedChallengeException;
|
||||
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.TestCase;
|
||||
|
@ -97,7 +99,9 @@ public class TestRFC2617Scheme extends TestCase {
|
|||
|
||||
public void testProcessChallengeWithLotsOfBlanks() throws Exception {
|
||||
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);
|
||||
|
||||
|
@ -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 {
|
||||
TestAuthScheme authscheme = new TestAuthScheme();
|
||||
Header header = new BasicHeader("whatever", "whatever");
|
||||
|
|
Loading…
Reference in New Issue