RFC 7231: redesign of HTTP authenticator and related classes
git-svn-id: https://svn.apache.org/repos/asf/httpcomponents/httpclient/trunk@1689155 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
11612ab974
commit
2f66271de9
|
@ -29,13 +29,16 @@ package org.apache.http.client.fluent;
|
|||
import java.io.IOException;
|
||||
import java.security.KeyManagementException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.util.Collections;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import javax.net.ssl.SSLContext;
|
||||
|
||||
import org.apache.http.HttpHost;
|
||||
import org.apache.http.auth.AUTH;
|
||||
import org.apache.http.NameValuePair;
|
||||
import org.apache.http.auth.AuthChallenge;
|
||||
import org.apache.http.auth.AuthScope;
|
||||
import org.apache.http.auth.ChallengeType;
|
||||
import org.apache.http.auth.Credentials;
|
||||
import org.apache.http.auth.MalformedChallengeException;
|
||||
import org.apache.http.auth.NTCredentials;
|
||||
|
@ -58,7 +61,6 @@ import org.apache.http.impl.client.BasicAuthCache;
|
|||
import org.apache.http.impl.client.BasicCredentialsProvider;
|
||||
import org.apache.http.impl.client.HttpClientBuilder;
|
||||
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
|
||||
import org.apache.http.message.BasicHeader;
|
||||
|
||||
/**
|
||||
* An Executor for fluent requests.
|
||||
|
@ -151,7 +153,7 @@ public class Executor {
|
|||
public Executor authPreemptive(final HttpHost host) {
|
||||
final BasicScheme basicScheme = new BasicScheme();
|
||||
try {
|
||||
basicScheme.processChallenge(new BasicHeader(AUTH.WWW_AUTH, "BASIC "));
|
||||
basicScheme.processChallenge(ChallengeType.TARGET, new AuthChallenge("basic", null, Collections.<NameValuePair>emptyList()));
|
||||
} catch (final MalformedChallengeException ignore) {
|
||||
}
|
||||
this.authCache.put(host, basicScheme);
|
||||
|
@ -168,7 +170,7 @@ public class Executor {
|
|||
public Executor authPreemptiveProxy(final HttpHost proxy) {
|
||||
final BasicScheme basicScheme = new BasicScheme();
|
||||
try {
|
||||
basicScheme.processChallenge(new BasicHeader(AUTH.PROXY_AUTH, "BASIC "));
|
||||
basicScheme.processChallenge(ChallengeType.PROXY, new AuthChallenge("basic", null, Collections.<NameValuePair>emptyList()));
|
||||
} catch (final MalformedChallengeException ignore) {
|
||||
}
|
||||
this.authCache.put(proxy, basicScheme);
|
||||
|
|
|
@ -34,14 +34,16 @@ import org.apache.http.HttpHost;
|
|||
import org.apache.http.HttpRequest;
|
||||
import org.apache.http.annotation.NotThreadSafe;
|
||||
import org.apache.http.auth.AUTH;
|
||||
import org.apache.http.auth.AuthChallenge;
|
||||
import org.apache.http.auth.AuthenticationException;
|
||||
import org.apache.http.auth.ChallengeType;
|
||||
import org.apache.http.auth.Credentials;
|
||||
import org.apache.http.auth.InvalidCredentialsException;
|
||||
import org.apache.http.auth.MalformedChallengeException;
|
||||
import org.apache.http.client.config.AuthSchemes;
|
||||
import org.apache.http.client.protocol.HttpClientContext;
|
||||
import org.apache.http.conn.routing.RouteInfo;
|
||||
import org.apache.http.impl.auth.AuthSchemeBase;
|
||||
import org.apache.http.impl.auth.NonStandardAuthScheme;
|
||||
import org.apache.http.message.BufferedHeader;
|
||||
import org.apache.http.protocol.HttpContext;
|
||||
import org.apache.http.util.CharArrayBuffer;
|
||||
|
@ -68,7 +70,7 @@ import com.sun.jna.ptr.IntByReference;
|
|||
* @since 4.4
|
||||
*/
|
||||
@NotThreadSafe
|
||||
public class WindowsNegotiateScheme extends AuthSchemeBase {
|
||||
public class WindowsNegotiateScheme extends NonStandardAuthScheme {
|
||||
|
||||
private final Log log = LogFactory.getLog(getClass());
|
||||
|
||||
|
@ -79,13 +81,11 @@ public class WindowsNegotiateScheme extends AuthSchemeBase {
|
|||
private CredHandle clientCred;
|
||||
private CtxtHandle sspiContext;
|
||||
private boolean continueNeeded;
|
||||
private String challenge;
|
||||
|
||||
public WindowsNegotiateScheme(final String scheme, final String servicePrincipalName) {
|
||||
super();
|
||||
|
||||
this.scheme = (scheme == null) ? AuthSchemes.SPNEGO : scheme;
|
||||
this.challenge = null;
|
||||
this.continueNeeded = true;
|
||||
this.servicePrincipalName = servicePrincipalName;
|
||||
|
||||
|
@ -123,35 +123,21 @@ public class WindowsNegotiateScheme extends AuthSchemeBase {
|
|||
return scheme;
|
||||
}
|
||||
|
||||
// String parameters not supported
|
||||
@Override
|
||||
public String getParameter(final String name) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// NTLM/Negotiate do not support authentication realms
|
||||
@Override
|
||||
public String getRealm() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isConnectionBased() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void parseChallenge(
|
||||
final CharArrayBuffer buffer,
|
||||
final int beginIndex,
|
||||
final int endIndex) throws MalformedChallengeException {
|
||||
this.challenge = buffer.substringTrimmed(beginIndex, endIndex);
|
||||
|
||||
if (this.challenge.isEmpty()) {
|
||||
public void processChallenge(
|
||||
final ChallengeType challengeType, final AuthChallenge authChallenge) throws MalformedChallengeException {
|
||||
update(challengeType, authChallenge);
|
||||
final String challenge = getChallenge();
|
||||
if (challenge.isEmpty()) {
|
||||
if (clientCred != null) {
|
||||
dispose(); // run cleanup first before throwing an exception otherwise can leak OS resources
|
||||
if (continueNeeded) {
|
||||
throw new RuntimeException("Unexpected token");
|
||||
throw new IllegalStateException("Unexpected token");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -163,6 +149,7 @@ public class WindowsNegotiateScheme extends AuthSchemeBase {
|
|||
final HttpRequest request,
|
||||
final HttpContext context) throws AuthenticationException {
|
||||
|
||||
final String challenge = getChallenge();
|
||||
final String response;
|
||||
if (clientCred == null) {
|
||||
// ?? We don't use the credentials, should we allow anything?
|
||||
|
@ -196,12 +183,12 @@ public class WindowsNegotiateScheme extends AuthSchemeBase {
|
|||
throw ex;
|
||||
}
|
||||
}
|
||||
} else if (this.challenge == null || this.challenge.isEmpty()) {
|
||||
} else if (challenge == null || challenge.isEmpty()) {
|
||||
failAuthCleanup();
|
||||
throw new AuthenticationException("Authentication Failed");
|
||||
} else {
|
||||
try {
|
||||
final byte[] continueTokenBytes = Base64.decodeBase64(this.challenge);
|
||||
final byte[] continueTokenBytes = Base64.decodeBase64(challenge);
|
||||
final SecBufferDesc continueTokenBuffer = new SecBufferDesc(
|
||||
Sspi.SECBUFFER_TOKEN, continueTokenBytes);
|
||||
final String targetName = getServicePrincipalName(context);
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
package org.apache.http.auth;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
|
@ -55,6 +56,10 @@ public final class AuthChallenge {
|
|||
this.params = params != null ? Collections.unmodifiableList(new ArrayList<>(params)) : null;
|
||||
}
|
||||
|
||||
public AuthChallenge(final String scheme, final NameValuePair... params) {
|
||||
this(scheme, null, Arrays.asList(params));
|
||||
}
|
||||
|
||||
public String getScheme() {
|
||||
return scheme;
|
||||
}
|
||||
|
|
|
@ -60,9 +60,32 @@ public interface AuthScheme {
|
|||
* may involve multiple challenge-response exchanges. Such schemes must be able
|
||||
* to maintain the state information when dealing with sequential challenges
|
||||
*
|
||||
* @param header the challenge header
|
||||
* @param challengeType the challenge type
|
||||
* @param authChallenge the auth challenge
|
||||
*
|
||||
* @since 5.0
|
||||
*/
|
||||
void processChallenge(final Header header) throws MalformedChallengeException;
|
||||
void processChallenge(
|
||||
ChallengeType challengeType,
|
||||
AuthChallenge authChallenge) throws MalformedChallengeException;
|
||||
|
||||
/**
|
||||
* Produces an authorization string for the given set of {@link Credentials}.
|
||||
*
|
||||
* @param credentials The credentials to be used for authentication
|
||||
* @param request The request being authenticated
|
||||
* @param context HTTP context
|
||||
* @throws AuthenticationException if authorization string cannot
|
||||
* be generated due to an authentication failure
|
||||
*
|
||||
* @return authorization header
|
||||
*
|
||||
* @since 5.0
|
||||
*/
|
||||
Header authenticate(
|
||||
Credentials credentials,
|
||||
HttpRequest request,
|
||||
HttpContext context) throws AuthenticationException;
|
||||
|
||||
/**
|
||||
* Returns textual designation of the given authentication scheme.
|
||||
|
@ -109,23 +132,4 @@ public interface AuthScheme {
|
|||
*/
|
||||
boolean isComplete();
|
||||
|
||||
/**
|
||||
* Produces an authorization string for the given set of
|
||||
* {@link Credentials}.
|
||||
*
|
||||
* @param credentials The set of credentials to be used for athentication
|
||||
* @param request The request being authenticated
|
||||
* @param context HTTP context
|
||||
* @throws AuthenticationException if authorization string cannot
|
||||
* be generated due to an authentication failure
|
||||
*
|
||||
* @return the authorization string
|
||||
*
|
||||
* @since 5.0
|
||||
*/
|
||||
Header authenticate(
|
||||
Credentials credentials,
|
||||
HttpRequest request,
|
||||
HttpContext context) throws AuthenticationException;
|
||||
|
||||
}
|
||||
|
|
|
@ -27,11 +27,11 @@
|
|||
package org.apache.http.auth;
|
||||
|
||||
/**
|
||||
* Challenge mode (TARGET or PROXY)
|
||||
* Challenge type (TARGET or PROXY)
|
||||
*
|
||||
* @since 4.2
|
||||
*/
|
||||
public enum ChallengeState {
|
||||
public enum ChallengeType {
|
||||
|
||||
TARGET, PROXY
|
||||
|
|
@ -30,18 +30,16 @@ package org.apache.http.client;
|
|||
import java.util.Map;
|
||||
import java.util.Queue;
|
||||
|
||||
import org.apache.http.Header;
|
||||
import org.apache.http.HttpHost;
|
||||
import org.apache.http.HttpResponse;
|
||||
import org.apache.http.auth.AuthChallenge;
|
||||
import org.apache.http.auth.AuthOption;
|
||||
import org.apache.http.auth.AuthScheme;
|
||||
import org.apache.http.auth.ChallengeType;
|
||||
import org.apache.http.auth.MalformedChallengeException;
|
||||
import org.apache.http.protocol.HttpContext;
|
||||
|
||||
/**
|
||||
/**
|
||||
* A handler for determining if an HTTP response represents an authentication challenge that was
|
||||
* sent back to the client as a result of authentication failure.
|
||||
* Strategy to select auth schemes in order of preference based on auth challenges
|
||||
* presented by the opposite endpoint (target server or a proxy).
|
||||
* <p>
|
||||
* Implementations of this interface must be thread-safe. Access to shared data must be
|
||||
* synchronized as methods of this interface may be executed from multiple threads.
|
||||
|
@ -50,81 +48,25 @@ import org.apache.http.protocol.HttpContext;
|
|||
*/
|
||||
public interface AuthenticationStrategy {
|
||||
|
||||
/**
|
||||
* Determines if the given HTTP response response represents
|
||||
* an authentication challenge that was sent back as a result
|
||||
* of authentication failure.
|
||||
*
|
||||
* @param authhost authentication host.
|
||||
* @param response HTTP response.
|
||||
* @param context HTTP context.
|
||||
* @return {@code true} if user authentication is required,
|
||||
* {@code false} otherwise.
|
||||
*/
|
||||
boolean isAuthenticationRequested(
|
||||
HttpHost authhost,
|
||||
HttpResponse response,
|
||||
HttpContext context);
|
||||
|
||||
/**
|
||||
* Extracts from the given HTTP response a collection of authentication
|
||||
* challenges, each of which represents an authentication scheme supported
|
||||
* by the authentication host.
|
||||
*
|
||||
* @param authhost authentication host.
|
||||
* @param response HTTP response.
|
||||
* @param context HTTP context.
|
||||
* @return a collection of challenges keyed by names of corresponding
|
||||
* authentication schemes.
|
||||
* @throws MalformedChallengeException if one of the authentication
|
||||
* challenges is not valid or malformed.
|
||||
*/
|
||||
Map<String, Header> getChallenges(
|
||||
HttpHost authhost,
|
||||
HttpResponse response,
|
||||
HttpContext context) throws MalformedChallengeException;
|
||||
|
||||
/**
|
||||
* Selects one authentication challenge out of all available and
|
||||
* creates and generates {@link AuthOption} instance capable of
|
||||
* processing that challenge.
|
||||
*
|
||||
* @param challengeType challenge type.
|
||||
* @param host authentication host.
|
||||
* @param challenges collection of challenges.
|
||||
* @param authhost authentication host.
|
||||
* @param response HTTP response.
|
||||
* @param context HTTP context.
|
||||
* @return authentication auth schemes that can be used for authentication. Can be empty.
|
||||
* @throws MalformedChallengeException if one of the authentication
|
||||
* challenges is not valid or malformed.
|
||||
*
|
||||
* @since 5.0
|
||||
*/
|
||||
Queue<AuthOption> select(
|
||||
Map<String, Header> challenges,
|
||||
HttpHost authhost,
|
||||
HttpResponse response,
|
||||
ChallengeType challengeType,
|
||||
HttpHost host,
|
||||
Map<String, AuthChallenge> challenges,
|
||||
HttpContext context) throws MalformedChallengeException;
|
||||
|
||||
/**
|
||||
* Callback invoked in case of successful authentication.
|
||||
*
|
||||
* @param authhost authentication host.
|
||||
* @param authScheme authentication scheme used.
|
||||
* @param context HTTP context.
|
||||
*/
|
||||
void authSucceeded(
|
||||
HttpHost authhost,
|
||||
AuthScheme authScheme,
|
||||
HttpContext context);
|
||||
|
||||
/**
|
||||
* Callback invoked in case of unsuccessful authentication.
|
||||
*
|
||||
* @param authhost authentication host.
|
||||
* @param authScheme authentication scheme used.
|
||||
* @param context HTTP context.
|
||||
*/
|
||||
void authFailed(
|
||||
HttpHost authhost,
|
||||
AuthScheme authScheme,
|
||||
HttpContext context);
|
||||
|
||||
}
|
||||
|
|
|
@ -41,6 +41,8 @@ import org.apache.http.util.CharArrayBuffer;
|
|||
|
||||
public class AuthChallengeParser {
|
||||
|
||||
public static final AuthChallengeParser INSTANCE = new AuthChallengeParser();
|
||||
|
||||
private final TokenParser tokenParser = TokenParser.INSTANCE;
|
||||
|
||||
private final static char BLANK = ' ';
|
||||
|
@ -60,7 +62,7 @@ public class AuthChallengeParser {
|
|||
if (buffer.charAt(cursor.getPos()) == BLANK) {
|
||||
tokenParser.skipWhiteSpace(buffer, cursor);
|
||||
}
|
||||
if (buffer.charAt(cursor.getPos()) == EQUAL_CHAR) {
|
||||
if (!cursor.atEnd() && buffer.charAt(cursor.getPos()) == EQUAL_CHAR) {
|
||||
cursor.updatePos(cursor.getPos() + 1);
|
||||
final String value = tokenParser.parseValue(buffer, cursor, DELIMITER);
|
||||
return new BasicNameValuePair(token, value);
|
||||
|
|
|
@ -1,143 +0,0 @@
|
|||
/*
|
||||
* ====================================================================
|
||||
* 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.util.Locale;
|
||||
|
||||
import org.apache.http.FormattedHeader;
|
||||
import org.apache.http.Header;
|
||||
import org.apache.http.annotation.NotThreadSafe;
|
||||
import org.apache.http.auth.AUTH;
|
||||
import org.apache.http.auth.AuthScheme;
|
||||
import org.apache.http.auth.ChallengeState;
|
||||
import org.apache.http.auth.MalformedChallengeException;
|
||||
import org.apache.http.protocol.HTTP;
|
||||
import org.apache.http.util.Args;
|
||||
import org.apache.http.util.CharArrayBuffer;
|
||||
|
||||
/**
|
||||
* Abstract authentication scheme class that serves as a basis
|
||||
* for all authentication schemes supported by HttpClient. This class
|
||||
* defines the generic way of parsing an authentication challenge. It
|
||||
* does not make any assumptions regarding the format of the challenge
|
||||
* nor does it impose any specific way of responding to that challenge.
|
||||
*
|
||||
*
|
||||
* @since 4.0
|
||||
*/
|
||||
@NotThreadSafe
|
||||
public abstract class AuthSchemeBase implements AuthScheme {
|
||||
|
||||
protected ChallengeState challengeState;
|
||||
|
||||
public AuthSchemeBase() {
|
||||
super();
|
||||
}
|
||||
|
||||
/**
|
||||
* Processes the given challenge token. Some authentication schemes
|
||||
* may involve multiple challenge-response exchanges. Such schemes must be able
|
||||
* to maintain the state information when dealing with sequential challenges
|
||||
*
|
||||
* @param header the challenge header
|
||||
*
|
||||
* @throws MalformedChallengeException is thrown if the authentication challenge
|
||||
* is malformed
|
||||
*/
|
||||
@Override
|
||||
public void processChallenge(final Header header) throws MalformedChallengeException {
|
||||
Args.notNull(header, "Header");
|
||||
final String authheader = header.getName();
|
||||
if (authheader.equalsIgnoreCase(AUTH.WWW_AUTH)) {
|
||||
this.challengeState = ChallengeState.TARGET;
|
||||
} else if (authheader.equalsIgnoreCase(AUTH.PROXY_AUTH)) {
|
||||
this.challengeState = ChallengeState.PROXY;
|
||||
} else {
|
||||
throw new MalformedChallengeException("Unexpected header name: " + authheader);
|
||||
}
|
||||
|
||||
final CharArrayBuffer buffer;
|
||||
int pos;
|
||||
if (header instanceof FormattedHeader) {
|
||||
buffer = ((FormattedHeader) header).getBuffer();
|
||||
pos = ((FormattedHeader) header).getValuePos();
|
||||
} else {
|
||||
final String s = header.getValue();
|
||||
if (s == null) {
|
||||
throw new MalformedChallengeException("Header value is null");
|
||||
}
|
||||
buffer = new CharArrayBuffer(s.length());
|
||||
buffer.append(s);
|
||||
pos = 0;
|
||||
}
|
||||
while (pos < buffer.length() && HTTP.isWhitespace(buffer.charAt(pos))) {
|
||||
pos++;
|
||||
}
|
||||
final int beginIndex = pos;
|
||||
while (pos < buffer.length() && !HTTP.isWhitespace(buffer.charAt(pos))) {
|
||||
pos++;
|
||||
}
|
||||
final int endIndex = pos;
|
||||
final String s = buffer.substring(beginIndex, endIndex);
|
||||
if (!s.equalsIgnoreCase(getSchemeName())) {
|
||||
throw new MalformedChallengeException("Invalid scheme identifier: " + s);
|
||||
}
|
||||
|
||||
parseChallenge(buffer, pos, buffer.length());
|
||||
}
|
||||
|
||||
protected abstract void parseChallenge(
|
||||
CharArrayBuffer buffer, int beginIndex, int endIndex) throws MalformedChallengeException;
|
||||
|
||||
/**
|
||||
* Returns {@code true} if authenticating against a proxy, {@code false}
|
||||
* otherwise.
|
||||
*/
|
||||
public boolean isProxy() {
|
||||
return this.challengeState != null && this.challengeState == ChallengeState.PROXY;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns {@link ChallengeState} value or {@code null} if unchallenged.
|
||||
*
|
||||
* @since 4.2
|
||||
*/
|
||||
public ChallengeState getChallengeState() {
|
||||
return this.challengeState;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
final String name = getSchemeName();
|
||||
if (name != null) {
|
||||
return name.toUpperCase(Locale.ROOT);
|
||||
} else {
|
||||
return super.toString();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -26,6 +26,10 @@
|
|||
*/
|
||||
package org.apache.http.impl.auth;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.io.ObjectOutputStream;
|
||||
import java.io.ObjectStreamException;
|
||||
import java.nio.charset.Charset;
|
||||
|
||||
import org.apache.commons.codec.binary.Base64;
|
||||
|
@ -34,13 +38,16 @@ import org.apache.http.Header;
|
|||
import org.apache.http.HttpRequest;
|
||||
import org.apache.http.annotation.NotThreadSafe;
|
||||
import org.apache.http.auth.AUTH;
|
||||
import org.apache.http.auth.AuthChallenge;
|
||||
import org.apache.http.auth.AuthenticationException;
|
||||
import org.apache.http.auth.ChallengeType;
|
||||
import org.apache.http.auth.Credentials;
|
||||
import org.apache.http.auth.MalformedChallengeException;
|
||||
import org.apache.http.message.BufferedHeader;
|
||||
import org.apache.http.protocol.HttpContext;
|
||||
import org.apache.http.util.Args;
|
||||
import org.apache.http.util.CharArrayBuffer;
|
||||
import org.apache.http.util.CharsetUtils;
|
||||
import org.apache.http.util.EncodingUtils;
|
||||
|
||||
/**
|
||||
|
@ -49,18 +56,18 @@ import org.apache.http.util.EncodingUtils;
|
|||
* @since 4.0
|
||||
*/
|
||||
@NotThreadSafe
|
||||
public class BasicScheme extends RFC2617Scheme {
|
||||
public class BasicScheme extends StandardAuthScheme {
|
||||
|
||||
private static final long serialVersionUID = -1931571557597830536L;
|
||||
|
||||
/** Whether the basic authentication process is complete */
|
||||
private transient Charset charset;
|
||||
private boolean complete;
|
||||
|
||||
/**
|
||||
* @since 4.3
|
||||
*/
|
||||
public BasicScheme(final Charset credentialsCharset) {
|
||||
super(credentialsCharset);
|
||||
public BasicScheme(final Charset charset) {
|
||||
this.charset = charset != null ? charset : Consts.ASCII;
|
||||
this.complete = false;
|
||||
}
|
||||
|
||||
|
@ -68,64 +75,28 @@ public class BasicScheme extends RFC2617Scheme {
|
|||
this(Consts.ASCII);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns textual designation of the basic authentication scheme.
|
||||
*
|
||||
* @return {@code basic}
|
||||
*/
|
||||
@Override
|
||||
public String getSchemeName() {
|
||||
return "basic";
|
||||
}
|
||||
|
||||
/**
|
||||
* Processes the Basic challenge.
|
||||
*
|
||||
* @param header the challenge header
|
||||
*
|
||||
* @throws MalformedChallengeException is thrown if the authentication challenge
|
||||
* is malformed
|
||||
*/
|
||||
@Override
|
||||
public void processChallenge(
|
||||
final Header header) throws MalformedChallengeException {
|
||||
super.processChallenge(header);
|
||||
final ChallengeType challengeType,
|
||||
final AuthChallenge authChallenge) throws MalformedChallengeException {
|
||||
update(challengeType, authChallenge);
|
||||
this.complete = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests if the Basic authentication process has been completed.
|
||||
*
|
||||
* @return {@code true} if Basic authorization has been processed,
|
||||
* {@code false} otherwise.
|
||||
*/
|
||||
@Override
|
||||
public boolean isComplete() {
|
||||
return this.complete;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns {@code false}. Basic authentication scheme is request based.
|
||||
*
|
||||
* @return {@code false}.
|
||||
*/
|
||||
@Override
|
||||
public boolean isConnectionBased() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Produces basic authorization header for the given set of {@link Credentials}.
|
||||
*
|
||||
* @param credentials The set of credentials to be used for authentication
|
||||
* @param request The request being authenticated
|
||||
* @throws org.apache.http.auth.InvalidCredentialsException if authentication
|
||||
* credentials are not valid or not applicable for this authentication scheme
|
||||
* @throws AuthenticationException if authorization string cannot
|
||||
* be generated due to an authentication failure
|
||||
*
|
||||
* @return a basic authorization string
|
||||
*/
|
||||
@Override
|
||||
public Header authenticate(
|
||||
final Credentials credentials,
|
||||
|
@ -134,15 +105,6 @@ public class BasicScheme extends RFC2617Scheme {
|
|||
|
||||
Args.notNull(credentials, "Credentials");
|
||||
Args.notNull(request, "HTTP request");
|
||||
final StringBuilder tmp = new StringBuilder();
|
||||
tmp.append(credentials.getUserPrincipal().getName());
|
||||
tmp.append(":");
|
||||
tmp.append((credentials.getPassword() == null) ? "null" : credentials.getPassword());
|
||||
|
||||
final Base64 base64codec = new Base64(0);
|
||||
final byte[] base64password = base64codec.encode(
|
||||
EncodingUtils.getBytes(tmp.toString(), getCredentialsCharset(request)));
|
||||
|
||||
final CharArrayBuffer buffer = new CharArrayBuffer(32);
|
||||
if (isProxy()) {
|
||||
buffer.append(AUTH.PROXY_AUTH_RESP);
|
||||
|
@ -150,16 +112,34 @@ public class BasicScheme extends RFC2617Scheme {
|
|||
buffer.append(AUTH.WWW_AUTH_RESP);
|
||||
}
|
||||
buffer.append(": Basic ");
|
||||
buffer.append(base64password, 0, base64password.length);
|
||||
|
||||
final StringBuilder tmp = new StringBuilder();
|
||||
tmp.append(credentials.getUserPrincipal().getName());
|
||||
tmp.append(":");
|
||||
tmp.append((credentials.getPassword() == null) ? "null" : credentials.getPassword());
|
||||
|
||||
final Base64 base64codec = new Base64(0);
|
||||
final byte[] base64password = base64codec.encode(EncodingUtils.getBytes(tmp.toString(), charset.name()));
|
||||
|
||||
buffer.append(base64password, 0, base64password.length);
|
||||
return new BufferedHeader(buffer);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
final StringBuilder builder = new StringBuilder();
|
||||
builder.append("BASIC [complete=").append(complete)
|
||||
.append("]");
|
||||
return builder.toString();
|
||||
private void writeObject(final ObjectOutputStream out) throws IOException {
|
||||
out.defaultWriteObject();
|
||||
out.writeUTF(this.charset.name());
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private void readObject(final ObjectInputStream in) throws IOException, ClassNotFoundException {
|
||||
in.defaultReadObject();
|
||||
this.charset = CharsetUtils.get(in.readUTF());
|
||||
if (this.charset == null) {
|
||||
this.charset = Consts.ASCII;
|
||||
}
|
||||
}
|
||||
|
||||
private void readObjectNoData() throws ObjectStreamException {
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -27,7 +27,6 @@
|
|||
package org.apache.http.impl.auth;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.Charset;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.SecureRandom;
|
||||
import java.util.ArrayList;
|
||||
|
@ -38,14 +37,15 @@ import java.util.Locale;
|
|||
import java.util.Set;
|
||||
import java.util.StringTokenizer;
|
||||
|
||||
import org.apache.http.Consts;
|
||||
import org.apache.http.Header;
|
||||
import org.apache.http.HttpEntity;
|
||||
import org.apache.http.HttpEntityEnclosingRequest;
|
||||
import org.apache.http.HttpRequest;
|
||||
import org.apache.http.annotation.NotThreadSafe;
|
||||
import org.apache.http.auth.AUTH;
|
||||
import org.apache.http.auth.AuthChallenge;
|
||||
import org.apache.http.auth.AuthenticationException;
|
||||
import org.apache.http.auth.ChallengeType;
|
||||
import org.apache.http.auth.Credentials;
|
||||
import org.apache.http.auth.MalformedChallengeException;
|
||||
import org.apache.http.message.BasicHeaderValueFormatter;
|
||||
|
@ -71,7 +71,7 @@ import org.apache.http.util.EncodingUtils;
|
|||
* @since 4.0
|
||||
*/
|
||||
@NotThreadSafe
|
||||
public class DigestScheme extends RFC2617Scheme {
|
||||
public class DigestScheme extends StandardAuthScheme {
|
||||
|
||||
private static final long serialVersionUID = 3883908186234566916L;
|
||||
|
||||
|
@ -100,42 +100,23 @@ public class DigestScheme extends RFC2617Scheme {
|
|||
private String a1;
|
||||
private String a2;
|
||||
|
||||
/**
|
||||
* @since 4.3
|
||||
*/
|
||||
public DigestScheme(final Charset credentialsCharset) {
|
||||
super(credentialsCharset);
|
||||
public DigestScheme() {
|
||||
this.complete = false;
|
||||
}
|
||||
|
||||
public DigestScheme() {
|
||||
this(Consts.ASCII);
|
||||
}
|
||||
|
||||
/**
|
||||
* Processes the Digest challenge.
|
||||
*
|
||||
* @param header the challenge header
|
||||
*
|
||||
* @throws MalformedChallengeException is thrown if the authentication challenge
|
||||
* is malformed
|
||||
*/
|
||||
@Override
|
||||
public void processChallenge(
|
||||
final Header header) throws MalformedChallengeException {
|
||||
super.processChallenge(header);
|
||||
this.complete = true;
|
||||
final ChallengeType challengeType,
|
||||
final AuthChallenge authChallenge) throws MalformedChallengeException {
|
||||
Args.notNull(challengeType, "ChallengeType");
|
||||
Args.notNull(authChallenge, "AuthChallenge");
|
||||
update(challengeType, authChallenge);
|
||||
if (getParameters().isEmpty()) {
|
||||
throw new MalformedChallengeException("Authentication challenge is empty");
|
||||
throw new MalformedChallengeException("Missing digest auth parameters");
|
||||
}
|
||||
this.complete = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests if the Digest authentication process has been completed.
|
||||
*
|
||||
* @return {@code true} if Digest authorization has been processed,
|
||||
* {@code false} otherwise.
|
||||
*/
|
||||
@Override
|
||||
public boolean isComplete() {
|
||||
final String s = getParameter("stale");
|
||||
|
@ -146,21 +127,11 @@ public class DigestScheme extends RFC2617Scheme {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns textual designation of the digest authentication scheme.
|
||||
*
|
||||
* @return {@code digest}
|
||||
*/
|
||||
@Override
|
||||
public String getSchemeName() {
|
||||
return "digest";
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns {@code false}. Digest authentication scheme is request based.
|
||||
*
|
||||
* @return {@code false}.
|
||||
*/
|
||||
@Override
|
||||
public boolean isConnectionBased() {
|
||||
return false;
|
||||
|
@ -170,20 +141,6 @@ public class DigestScheme extends RFC2617Scheme {
|
|||
getParameters().put(name, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Produces a digest authorization string for the given set of
|
||||
* {@link Credentials}, method name and URI.
|
||||
*
|
||||
* @param credentials A set of credentials to be used for athentication
|
||||
* @param request The request being authenticated
|
||||
*
|
||||
* @throws org.apache.http.auth.InvalidCredentialsException if authentication credentials
|
||||
* are not valid or not applicable for this authentication scheme
|
||||
* @throws AuthenticationException if authorization string cannot
|
||||
* be generated due to an authentication failure
|
||||
*
|
||||
* @return a digest authorization string
|
||||
*/
|
||||
@Override
|
||||
public Header authenticate(
|
||||
final Credentials credentials,
|
||||
|
@ -201,10 +158,6 @@ public class DigestScheme extends RFC2617Scheme {
|
|||
// Add method name and request-URI to the parameter map
|
||||
getParameters().put("methodname", request.getRequestLine().getMethod());
|
||||
getParameters().put("uri", request.getRequestLine().getUri());
|
||||
final String charset = getParameter("charset");
|
||||
if (charset == null) {
|
||||
getParameters().put("charset", getCredentialsCharset(request));
|
||||
}
|
||||
return createDigestHeader(credentials, request);
|
||||
}
|
||||
|
||||
|
@ -219,13 +172,6 @@ public class DigestScheme extends RFC2617Scheme {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates digest-response header as defined in RFC2617.
|
||||
*
|
||||
* @param credentials User credentials
|
||||
*
|
||||
* @return The digest-response as String.
|
||||
*/
|
||||
private Header createDigestHeader(
|
||||
final Credentials credentials,
|
||||
final HttpRequest request) throws AuthenticationException {
|
||||
|
@ -447,7 +393,6 @@ public class DigestScheme extends RFC2617Scheme {
|
|||
return new String(buffer);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Creates a random cnonce value based on the current time.
|
||||
*
|
||||
|
@ -460,14 +405,4 @@ public class DigestScheme extends RFC2617Scheme {
|
|||
return encode(tmp);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
final StringBuilder builder = new StringBuilder();
|
||||
builder.append("DIGEST [complete=").append(complete)
|
||||
.append(", nonce=").append(lastNonce)
|
||||
.append(", nc=").append(nounceCount)
|
||||
.append("]");
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -27,8 +27,6 @@
|
|||
|
||||
package org.apache.http.impl.auth;
|
||||
|
||||
import java.nio.charset.Charset;
|
||||
|
||||
import org.apache.http.annotation.Immutable;
|
||||
import org.apache.http.auth.AuthScheme;
|
||||
import org.apache.http.auth.AuthSchemeProvider;
|
||||
|
@ -43,23 +41,9 @@ import org.apache.http.protocol.HttpContext;
|
|||
@Immutable
|
||||
public class DigestSchemeFactory implements AuthSchemeProvider {
|
||||
|
||||
private final Charset charset;
|
||||
|
||||
/**
|
||||
* @since 4.3
|
||||
*/
|
||||
public DigestSchemeFactory(final Charset charset) {
|
||||
super();
|
||||
this.charset = charset;
|
||||
}
|
||||
|
||||
public DigestSchemeFactory() {
|
||||
this(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AuthScheme create(final HttpContext context) {
|
||||
return new DigestScheme(this.charset);
|
||||
return new DigestScheme();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -37,7 +37,9 @@ import org.apache.http.HttpHost;
|
|||
import org.apache.http.HttpRequest;
|
||||
import org.apache.http.annotation.NotThreadSafe;
|
||||
import org.apache.http.auth.AUTH;
|
||||
import org.apache.http.auth.AuthChallenge;
|
||||
import org.apache.http.auth.AuthenticationException;
|
||||
import org.apache.http.auth.ChallengeType;
|
||||
import org.apache.http.auth.Credentials;
|
||||
import org.apache.http.auth.InvalidCredentialsException;
|
||||
import org.apache.http.auth.KerberosCredentials;
|
||||
|
@ -59,7 +61,7 @@ import org.ietf.jgss.Oid;
|
|||
* @since 4.2
|
||||
*/
|
||||
@NotThreadSafe
|
||||
public abstract class GGSSchemeBase extends AuthSchemeBase {
|
||||
public abstract class GGSSchemeBase extends NonStandardAuthScheme {
|
||||
|
||||
enum State {
|
||||
UNINITIATED,
|
||||
|
@ -70,7 +72,6 @@ public abstract class GGSSchemeBase extends AuthSchemeBase {
|
|||
|
||||
private final Log log = LogFactory.getLog(getClass());
|
||||
|
||||
private final Base64 base64codec;
|
||||
private final boolean stripPort;
|
||||
private final boolean useCanonicalHostname;
|
||||
|
||||
|
@ -82,7 +83,6 @@ public abstract class GGSSchemeBase extends AuthSchemeBase {
|
|||
|
||||
GGSSchemeBase(final boolean stripPort, final boolean useCanonicalHostname) {
|
||||
super();
|
||||
this.base64codec = new Base64(0);
|
||||
this.stripPort = stripPort;
|
||||
this.useCanonicalHostname = useCanonicalHostname;
|
||||
this.state = State.UNINITIATED;
|
||||
|
@ -96,6 +96,23 @@ public abstract class GGSSchemeBase extends AuthSchemeBase {
|
|||
this(true,true);
|
||||
}
|
||||
|
||||
public void processChallenge(
|
||||
final ChallengeType challengeType,
|
||||
final AuthChallenge authChallenge) throws MalformedChallengeException {
|
||||
update(challengeType, authChallenge);
|
||||
if (state == State.UNINITIATED) {
|
||||
final String challenge = getChallenge();
|
||||
token = Base64.decodeBase64(challenge.getBytes());
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("Received token '" + token + "' from the auth server");
|
||||
}
|
||||
state = State.CHALLENGE_RECEIVED;
|
||||
} else {
|
||||
log.debug("Authentication already attempted");
|
||||
state = State.FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
protected GSSManager getManager() {
|
||||
return GSSManager.getInstance();
|
||||
}
|
||||
|
@ -211,7 +228,8 @@ public abstract class GGSSchemeBase extends AuthSchemeBase {
|
|||
throw new AuthenticationException(gsse.getMessage());
|
||||
}
|
||||
case TOKEN_GENERATED:
|
||||
final String tokenstr = new String(base64codec.encode(token));
|
||||
final Base64 codec = new Base64(0);
|
||||
final String tokenstr = new String(codec.encode(token));
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("Sending response '" + tokenstr + "' back to the auth server");
|
||||
}
|
||||
|
@ -229,23 +247,6 @@ public abstract class GGSSchemeBase extends AuthSchemeBase {
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void parseChallenge(
|
||||
final CharArrayBuffer buffer,
|
||||
final int beginIndex, final int endIndex) throws MalformedChallengeException {
|
||||
final String challenge = buffer.substringTrimmed(beginIndex, endIndex);
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("Received challenge '" + challenge + "' from the auth server");
|
||||
}
|
||||
if (state == State.UNINITIATED) {
|
||||
token = Base64.decodeBase64(challenge.getBytes());
|
||||
state = State.CHALLENGE_RECEIVED;
|
||||
} else {
|
||||
log.debug("Authentication already attempted");
|
||||
state = State.FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
private String resolveCanonicalHostname(final String host) throws UnknownHostException {
|
||||
final InetAddress in = InetAddress.getByName(host);
|
||||
final String canonicalServer = in.getCanonicalHostName();
|
||||
|
|
|
@ -28,27 +28,40 @@
|
|||
package org.apache.http.impl.auth;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Queue;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.apache.http.FormattedHeader;
|
||||
import org.apache.http.Header;
|
||||
import org.apache.http.HttpException;
|
||||
import org.apache.http.HttpHeaders;
|
||||
import org.apache.http.HttpHost;
|
||||
import org.apache.http.HttpRequest;
|
||||
import org.apache.http.HttpResponse;
|
||||
import org.apache.http.HttpStatus;
|
||||
import org.apache.http.ParseException;
|
||||
import org.apache.http.auth.AuthChallenge;
|
||||
import org.apache.http.auth.AuthOption;
|
||||
import org.apache.http.auth.AuthProtocolState;
|
||||
import org.apache.http.auth.AuthScheme;
|
||||
import org.apache.http.auth.AuthState;
|
||||
import org.apache.http.auth.AuthenticationException;
|
||||
import org.apache.http.auth.ChallengeType;
|
||||
import org.apache.http.auth.Credentials;
|
||||
import org.apache.http.auth.MalformedChallengeException;
|
||||
import org.apache.http.client.AuthCache;
|
||||
import org.apache.http.client.AuthenticationStrategy;
|
||||
import org.apache.http.client.config.AuthSchemes;
|
||||
import org.apache.http.client.protocol.HttpClientContext;
|
||||
import org.apache.http.message.ParserCursor;
|
||||
import org.apache.http.protocol.HttpContext;
|
||||
import org.apache.http.util.Asserts;
|
||||
import org.apache.http.util.CharArrayBuffer;
|
||||
|
||||
/**
|
||||
* @since 4.3
|
||||
|
@ -56,26 +69,39 @@ import org.apache.http.util.Asserts;
|
|||
public class HttpAuthenticator {
|
||||
|
||||
private final Log log;
|
||||
private final AuthChallengeParser parser;
|
||||
|
||||
public HttpAuthenticator(final Log log) {
|
||||
super();
|
||||
this.log = log != null ? log : LogFactory.getLog(getClass());
|
||||
this.parser = new AuthChallengeParser();
|
||||
}
|
||||
|
||||
public HttpAuthenticator() {
|
||||
this(null);
|
||||
}
|
||||
|
||||
public boolean isAuthenticationRequested(
|
||||
public boolean updateAuthState(
|
||||
final HttpHost host,
|
||||
final ChallengeType challengeType,
|
||||
final HttpResponse response,
|
||||
final AuthenticationStrategy authStrategy,
|
||||
final AuthState authState,
|
||||
final HttpContext context) {
|
||||
if (authStrategy.isAuthenticationRequested(host, response, context)) {
|
||||
final int challengeCode;
|
||||
switch (challengeType) {
|
||||
case TARGET:
|
||||
challengeCode = HttpStatus.SC_UNAUTHORIZED;
|
||||
break;
|
||||
case PROXY:
|
||||
challengeCode = HttpStatus.SC_PROXY_AUTHENTICATION_REQUIRED;
|
||||
break;
|
||||
default:
|
||||
throw new IllegalStateException("Unexpected challenge type: " + challengeType);
|
||||
}
|
||||
if (response.getStatusLine().getStatusCode() == challengeCode) {
|
||||
this.log.debug("Authentication required");
|
||||
if (authState.getState() == AuthProtocolState.SUCCESS) {
|
||||
authStrategy.authFailed(host, authState.getAuthScheme(), context);
|
||||
clearCache(host, context);
|
||||
}
|
||||
return true;
|
||||
} else {
|
||||
|
@ -84,7 +110,7 @@ public class HttpAuthenticator {
|
|||
case HANDSHAKE:
|
||||
this.log.debug("Authentication succeeded");
|
||||
authState.setState(AuthProtocolState.SUCCESS);
|
||||
authStrategy.authSucceeded(host, authState.getAuthScheme(), context);
|
||||
updateCache(host, authState.getAuthScheme(), context);
|
||||
break;
|
||||
case SUCCESS:
|
||||
break;
|
||||
|
@ -97,17 +123,55 @@ public class HttpAuthenticator {
|
|||
|
||||
public boolean handleAuthChallenge(
|
||||
final HttpHost host,
|
||||
final ChallengeType challengeType,
|
||||
final HttpResponse response,
|
||||
final AuthenticationStrategy authStrategy,
|
||||
final AuthState authState,
|
||||
final HttpContext context) {
|
||||
|
||||
if (this.log.isDebugEnabled()) {
|
||||
this.log.debug(host.toHostString() + " requested authentication");
|
||||
}
|
||||
try {
|
||||
if (this.log.isDebugEnabled()) {
|
||||
this.log.debug(host.toHostString() + " requested authentication");
|
||||
final Header[] headers = response.getHeaders(
|
||||
challengeType == ChallengeType.PROXY ? HttpHeaders.PROXY_AUTHENTICATE : HttpHeaders.WWW_AUTHENTICATE);
|
||||
final Map<String, AuthChallenge> challengeMap = new HashMap<>();
|
||||
for (Header header: headers) {
|
||||
final CharArrayBuffer buffer;
|
||||
final int pos;
|
||||
if (header instanceof FormattedHeader) {
|
||||
buffer = ((FormattedHeader) header).getBuffer();
|
||||
pos = ((FormattedHeader) header).getValuePos();
|
||||
} else {
|
||||
final String s = header.getValue();
|
||||
if (s == null) {
|
||||
continue;
|
||||
}
|
||||
buffer = new CharArrayBuffer(s.length());
|
||||
buffer.append(s);
|
||||
pos = 0;
|
||||
}
|
||||
final ParserCursor cursor = new ParserCursor(pos, buffer.length());
|
||||
final List<AuthChallenge> authChallenges;
|
||||
try {
|
||||
authChallenges = parser.parse(buffer, cursor);
|
||||
} catch (ParseException ex) {
|
||||
if (this.log.isWarnEnabled()) {
|
||||
this.log.warn("Malformed challenge: " + header.getValue());
|
||||
}
|
||||
continue;
|
||||
}
|
||||
for (AuthChallenge authChallenge: authChallenges) {
|
||||
final String scheme = authChallenge.getScheme().toLowerCase(Locale.ROOT);
|
||||
if (!challengeMap.containsKey(scheme)) {
|
||||
challengeMap.put(scheme, authChallenge);
|
||||
}
|
||||
}
|
||||
}
|
||||
final Map<String, Header> challenges = authStrategy.getChallenges(host, response, context);
|
||||
if (challenges.isEmpty()) {
|
||||
this.log.debug("Response contains no authentication challenges");
|
||||
if (challengeMap.isEmpty()) {
|
||||
this.log.debug("Response contains no valid authentication challenges");
|
||||
clearCache(host, context);
|
||||
authState.reset();
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -122,7 +186,7 @@ public class HttpAuthenticator {
|
|||
case HANDSHAKE:
|
||||
if (authScheme == null) {
|
||||
this.log.debug("Auth scheme is null");
|
||||
authStrategy.authFailed(host, null, context);
|
||||
clearCache(host, context);
|
||||
authState.reset();
|
||||
authState.setState(AuthProtocolState.FAILURE);
|
||||
return false;
|
||||
|
@ -130,13 +194,13 @@ public class HttpAuthenticator {
|
|||
case UNCHALLENGED:
|
||||
if (authScheme != null) {
|
||||
final String id = authScheme.getSchemeName();
|
||||
final Header challenge = challenges.get(id.toLowerCase(Locale.ROOT));
|
||||
final AuthChallenge challenge = challengeMap.get(id.toLowerCase(Locale.ROOT));
|
||||
if (challenge != null) {
|
||||
this.log.debug("Authorization challenge processed");
|
||||
authScheme.processChallenge(challenge);
|
||||
authScheme.processChallenge(challengeType, challenge);
|
||||
if (authScheme.isComplete()) {
|
||||
this.log.debug("Authentication failed");
|
||||
authStrategy.authFailed(host, authState.getAuthScheme(), context);
|
||||
clearCache(host, context);
|
||||
authState.reset();
|
||||
authState.setState(AuthProtocolState.FAILURE);
|
||||
return false;
|
||||
|
@ -150,7 +214,7 @@ public class HttpAuthenticator {
|
|||
}
|
||||
}
|
||||
}
|
||||
final Queue<AuthOption> authOptions = authStrategy.select(challenges, host, response, context);
|
||||
final Queue<AuthOption> authOptions = authStrategy.select(challengeType, host, challengeMap, context);
|
||||
if (authOptions != null && !authOptions.isEmpty()) {
|
||||
if (this.log.isDebugEnabled()) {
|
||||
this.log.debug("Selected authentication options: " + authOptions);
|
||||
|
@ -180,7 +244,7 @@ public class HttpAuthenticator {
|
|||
case FAILURE:
|
||||
return;
|
||||
case SUCCESS:
|
||||
ensureAuthScheme(authScheme);
|
||||
Asserts.notNull(authScheme, "AuthScheme");
|
||||
if (authScheme.isConnectionBased()) {
|
||||
return;
|
||||
}
|
||||
|
@ -209,7 +273,7 @@ public class HttpAuthenticator {
|
|||
}
|
||||
return;
|
||||
} else {
|
||||
ensureAuthScheme(authScheme);
|
||||
Asserts.notNull(authScheme, "AuthScheme");
|
||||
}
|
||||
}
|
||||
if (authScheme != null) {
|
||||
|
@ -224,8 +288,35 @@ public class HttpAuthenticator {
|
|||
}
|
||||
}
|
||||
|
||||
private void ensureAuthScheme(final AuthScheme authScheme) {
|
||||
Asserts.notNull(authScheme, "Auth scheme");
|
||||
private boolean isCachable(final AuthScheme authScheme) {
|
||||
final String schemeName = authScheme.getSchemeName();
|
||||
return schemeName.equalsIgnoreCase(AuthSchemes.BASIC) ||
|
||||
schemeName.equalsIgnoreCase(AuthSchemes.DIGEST);
|
||||
}
|
||||
|
||||
private void updateCache(final HttpHost host, final AuthScheme authScheme, final HttpContext context) {
|
||||
if (isCachable(authScheme)) {
|
||||
final HttpClientContext clientContext = HttpClientContext.adapt(context);
|
||||
final AuthCache authCache = clientContext.getAuthCache();
|
||||
if (authCache != null) {
|
||||
if (this.log.isDebugEnabled()) {
|
||||
this.log.debug("Caching '" + authScheme.getSchemeName() + "' auth scheme for " + host);
|
||||
}
|
||||
authCache.put(host, authScheme);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void clearCache(final HttpHost host, final HttpContext context) {
|
||||
|
||||
final HttpClientContext clientContext = HttpClientContext.adapt(context);
|
||||
final AuthCache authCache = clientContext.getAuthCache();
|
||||
if (authCache != null) {
|
||||
if (this.log.isDebugEnabled()) {
|
||||
this.log.debug("Clearing cached auth scheme for " + host);
|
||||
}
|
||||
authCache.remove(host);
|
||||
}
|
||||
}
|
||||
|
||||
private Header doAuth(
|
||||
|
|
|
@ -26,13 +26,8 @@
|
|||
*/
|
||||
package org.apache.http.impl.auth;
|
||||
|
||||
import org.apache.http.Header;
|
||||
import org.apache.http.HttpRequest;
|
||||
import org.apache.http.annotation.NotThreadSafe;
|
||||
import org.apache.http.auth.AuthenticationException;
|
||||
import org.apache.http.auth.Credentials;
|
||||
import org.apache.http.protocol.HttpContext;
|
||||
import org.apache.http.util.Args;
|
||||
import org.ietf.jgss.GSSException;
|
||||
import org.ietf.jgss.Oid;
|
||||
|
||||
|
@ -66,59 +61,11 @@ public class KerberosScheme extends GGSSchemeBase {
|
|||
return "Kerberos";
|
||||
}
|
||||
|
||||
/**
|
||||
* Produces KERBEROS authorization Header based on token created by
|
||||
* processChallenge.
|
||||
*
|
||||
* @param credentials not used by the KERBEROS scheme.
|
||||
* @param request The request being authenticated
|
||||
*
|
||||
* @throws AuthenticationException if authentication string cannot
|
||||
* be generated due to an authentication failure
|
||||
*
|
||||
* @return KERBEROS authentication Header
|
||||
*/
|
||||
@Override
|
||||
public Header authenticate(
|
||||
final Credentials credentials,
|
||||
final HttpRequest request,
|
||||
final HttpContext context) throws AuthenticationException {
|
||||
return super.authenticate(credentials, request, context);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected byte[] generateToken(final byte[] input, final String authServer, final Credentials credentials) throws GSSException {
|
||||
return generateGSSToken(input, new Oid(KERBEROS_OID), authServer, credentials);
|
||||
}
|
||||
|
||||
/**
|
||||
* There are no valid parameters for KERBEROS authentication so this
|
||||
* method always returns {@code null}.
|
||||
*
|
||||
* @return {@code null}
|
||||
*/
|
||||
@Override
|
||||
public String getParameter(final String name) {
|
||||
Args.notNull(name, "Parameter name");
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* The concept of an authentication realm is not supported by the Negotiate
|
||||
* authentication scheme. Always returns {@code null}.
|
||||
*
|
||||
* @return {@code null}
|
||||
*/
|
||||
@Override
|
||||
public String getRealm() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns {@code true}. KERBEROS authentication scheme is connection based.
|
||||
*
|
||||
* @return {@code true}.
|
||||
*/
|
||||
@Override
|
||||
public boolean isConnectionBased() {
|
||||
return true;
|
||||
|
|
|
@ -30,7 +30,9 @@ import org.apache.http.Header;
|
|||
import org.apache.http.HttpRequest;
|
||||
import org.apache.http.annotation.NotThreadSafe;
|
||||
import org.apache.http.auth.AUTH;
|
||||
import org.apache.http.auth.AuthChallenge;
|
||||
import org.apache.http.auth.AuthenticationException;
|
||||
import org.apache.http.auth.ChallengeType;
|
||||
import org.apache.http.auth.Credentials;
|
||||
import org.apache.http.auth.InvalidCredentialsException;
|
||||
import org.apache.http.auth.MalformedChallengeException;
|
||||
|
@ -47,7 +49,7 @@ import org.apache.http.util.CharArrayBuffer;
|
|||
* @since 4.0
|
||||
*/
|
||||
@NotThreadSafe
|
||||
public class NTLMScheme extends AuthSchemeBase {
|
||||
public class NTLMScheme extends NonStandardAuthScheme {
|
||||
|
||||
enum State {
|
||||
UNINITIATED,
|
||||
|
@ -61,14 +63,12 @@ public class NTLMScheme extends AuthSchemeBase {
|
|||
private final NTLMEngine engine;
|
||||
|
||||
private State state;
|
||||
private String challenge;
|
||||
|
||||
public NTLMScheme(final NTLMEngine engine) {
|
||||
super();
|
||||
Args.notNull(engine, "NTLM engine");
|
||||
this.engine = engine;
|
||||
this.state = State.UNINITIATED;
|
||||
this.challenge = null;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -83,29 +83,18 @@ public class NTLMScheme extends AuthSchemeBase {
|
|||
return "ntlm";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getParameter(final String name) {
|
||||
// String parameters not supported
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getRealm() {
|
||||
// NTLM does not support the concept of an authentication realm
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isConnectionBased() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void parseChallenge(
|
||||
final CharArrayBuffer buffer,
|
||||
final int beginIndex, final int endIndex) throws MalformedChallengeException {
|
||||
this.challenge = buffer.substringTrimmed(beginIndex, endIndex);
|
||||
if (this.challenge.isEmpty()) {
|
||||
public void processChallenge(
|
||||
final ChallengeType challengeType, final AuthChallenge authChallenge) throws MalformedChallengeException {
|
||||
Args.notNull(challengeType, "ChallengeType");
|
||||
Args.notNull(authChallenge, "AuthChallenge");
|
||||
final String value = authChallenge.getValue();
|
||||
if (value == null || value.isEmpty()) {
|
||||
if (this.state == State.UNINITIATED) {
|
||||
this.state = State.CHALLENGE_RECEIVED;
|
||||
} else {
|
||||
|
@ -126,7 +115,7 @@ public class NTLMScheme extends AuthSchemeBase {
|
|||
final Credentials credentials,
|
||||
final HttpRequest request,
|
||||
final HttpContext context) throws AuthenticationException {
|
||||
NTCredentials ntcredentials = null;
|
||||
final NTCredentials ntcredentials;
|
||||
try {
|
||||
ntcredentials = (NTCredentials) credentials;
|
||||
} catch (final ClassCastException e) {
|
||||
|
@ -134,7 +123,7 @@ public class NTLMScheme extends AuthSchemeBase {
|
|||
"Credentials cannot be used for NTLM authentication: "
|
||||
+ credentials.getClass().getName());
|
||||
}
|
||||
String response = null;
|
||||
final String response;
|
||||
if (this.state == State.FAILED) {
|
||||
throw new AuthenticationException("NTLM authentication failed");
|
||||
} else if (this.state == State.CHALLENGE_RECEIVED) {
|
||||
|
@ -148,7 +137,7 @@ public class NTLMScheme extends AuthSchemeBase {
|
|||
ntcredentials.getPassword(),
|
||||
ntcredentials.getNetbiosDomain(),
|
||||
ntcredentials.getWorkstation(),
|
||||
this.challenge);
|
||||
getChallenge());
|
||||
this.state = State.MSG_TYPE3_GENERATED;
|
||||
} else {
|
||||
throw new AuthenticationException("Unexpected state: " + this.state);
|
||||
|
|
|
@ -24,34 +24,47 @@
|
|||
* <http://www.apache.org/>.
|
||||
*
|
||||
*/
|
||||
package org.apache.http.impl.auth;
|
||||
|
||||
package org.apache.http.impl.client;
|
||||
import org.apache.http.auth.AuthChallenge;
|
||||
import org.apache.http.auth.AuthScheme;
|
||||
import org.apache.http.auth.ChallengeType;
|
||||
import org.apache.http.auth.MalformedChallengeException;
|
||||
|
||||
import java.util.Collection;
|
||||
public abstract class NonStandardAuthScheme implements AuthScheme {
|
||||
|
||||
import org.apache.http.HttpStatus;
|
||||
import org.apache.http.annotation.Immutable;
|
||||
import org.apache.http.auth.AUTH;
|
||||
import org.apache.http.client.config.RequestConfig;
|
||||
private ChallengeType challengeType;
|
||||
private String challenge;
|
||||
|
||||
/**
|
||||
* Default {@link org.apache.http.client.AuthenticationStrategy} implementation
|
||||
* for proxy host authentication.
|
||||
*
|
||||
* @since 4.2
|
||||
*/
|
||||
@Immutable
|
||||
public class ProxyAuthenticationStrategy extends AuthenticationStrategyImpl {
|
||||
public boolean isProxy() {
|
||||
return this.challengeType != null && this.challengeType == ChallengeType.PROXY;
|
||||
}
|
||||
|
||||
public static final ProxyAuthenticationStrategy INSTANCE = new ProxyAuthenticationStrategy();
|
||||
protected void update(final ChallengeType challengeType, final AuthChallenge authChallenge) throws MalformedChallengeException{
|
||||
if (authChallenge.getValue() == null) {
|
||||
throw new MalformedChallengeException("Missing auth challenge");
|
||||
}
|
||||
this.challengeType = challengeType;
|
||||
this.challenge = authChallenge.getValue();
|
||||
}
|
||||
|
||||
public ProxyAuthenticationStrategy() {
|
||||
super(HttpStatus.SC_PROXY_AUTHENTICATION_REQUIRED, AUTH.PROXY_AUTH);
|
||||
protected String getChallenge() {
|
||||
return this.challenge;
|
||||
}
|
||||
|
||||
@Override
|
||||
Collection<String> getPreferredAuthSchemes(final RequestConfig config) {
|
||||
return config.getProxyPreferredAuthSchemes();
|
||||
public String getParameter(final String name) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getRealm() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return getSchemeName() + "(" + this.challengeType + ") " + this.challenge;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,156 +0,0 @@
|
|||
/*
|
||||
* ====================================================================
|
||||
* 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 java.io.ObjectInputStream;
|
||||
import java.io.ObjectOutputStream;
|
||||
import java.io.ObjectStreamException;
|
||||
import java.io.Serializable;
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.HashMap;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.http.Consts;
|
||||
import org.apache.http.HeaderElement;
|
||||
import org.apache.http.HttpRequest;
|
||||
import org.apache.http.annotation.NotThreadSafe;
|
||||
import org.apache.http.auth.ChallengeState;
|
||||
import org.apache.http.auth.MalformedChallengeException;
|
||||
import org.apache.http.message.BasicHeaderValueParser;
|
||||
import org.apache.http.message.HeaderValueParser;
|
||||
import org.apache.http.message.ParserCursor;
|
||||
import org.apache.http.util.CharArrayBuffer;
|
||||
import org.apache.http.util.CharsetUtils;
|
||||
|
||||
/**
|
||||
* Abstract authentication scheme class that lays foundation for all
|
||||
* RFC 2617 compliant authentication schemes and provides capabilities common
|
||||
* to all authentication schemes defined in RFC 2617.
|
||||
*
|
||||
* @since 4.0
|
||||
*/
|
||||
@NotThreadSafe // AuthSchemeBase, params
|
||||
public abstract class RFC2617Scheme extends AuthSchemeBase implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = -2845454858205884623L;
|
||||
|
||||
private final Map<String, String> params;
|
||||
private transient Charset credentialsCharset;
|
||||
|
||||
/**
|
||||
* @since 4.3
|
||||
*/
|
||||
public RFC2617Scheme(final Charset credentialsCharset) {
|
||||
super();
|
||||
this.params = new HashMap<>();
|
||||
this.credentialsCharset = credentialsCharset != null ? credentialsCharset : Consts.ASCII;
|
||||
}
|
||||
|
||||
public RFC2617Scheme() {
|
||||
this(Consts.ASCII);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @since 4.3
|
||||
*/
|
||||
public Charset getCredentialsCharset() {
|
||||
return credentialsCharset != null ? credentialsCharset : Consts.ASCII;
|
||||
}
|
||||
|
||||
String getCredentialsCharset(final HttpRequest request) {
|
||||
return getCredentialsCharset().name();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void parseChallenge(
|
||||
final CharArrayBuffer buffer, final int pos, final int len) throws MalformedChallengeException {
|
||||
final HeaderValueParser parser = BasicHeaderValueParser.INSTANCE;
|
||||
final ParserCursor cursor = new ParserCursor(pos, buffer.length());
|
||||
final HeaderElement[] elements = parser.parseElements(buffer, cursor);
|
||||
this.params.clear();
|
||||
for (final HeaderElement element : elements) {
|
||||
this.params.put(element.getName().toLowerCase(Locale.ROOT), element.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns authentication parameters map. Keys in the map are lower-cased.
|
||||
*
|
||||
* @return the map of authentication parameters
|
||||
*/
|
||||
protected Map<String, String> getParameters() {
|
||||
return this.params;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns authentication parameter with the given name, if available.
|
||||
*
|
||||
* @param name The name of the parameter to be returned
|
||||
*
|
||||
* @return the parameter with the given name
|
||||
*/
|
||||
@Override
|
||||
public String getParameter(final String name) {
|
||||
if (name == null) {
|
||||
return null;
|
||||
}
|
||||
return this.params.get(name.toLowerCase(Locale.ROOT));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns authentication realm. The realm may not be null.
|
||||
*
|
||||
* @return the authentication realm
|
||||
*/
|
||||
@Override
|
||||
public String getRealm() {
|
||||
return getParameter("realm");
|
||||
}
|
||||
|
||||
private void writeObject(final ObjectOutputStream out) throws IOException {
|
||||
out.defaultWriteObject();
|
||||
out.writeUTF(this.credentialsCharset.name());
|
||||
out.writeObject(this.challengeState);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private void readObject(final ObjectInputStream in) throws IOException, ClassNotFoundException {
|
||||
in.defaultReadObject();
|
||||
this.credentialsCharset = CharsetUtils.get(in.readUTF());
|
||||
if (this.credentialsCharset == null) {
|
||||
this.credentialsCharset = Consts.ASCII;
|
||||
}
|
||||
this.challengeState = (ChallengeState) in.readObject();
|
||||
}
|
||||
|
||||
private void readObjectNoData() throws ObjectStreamException {
|
||||
}
|
||||
|
||||
}
|
|
@ -26,13 +26,8 @@
|
|||
*/
|
||||
package org.apache.http.impl.auth;
|
||||
|
||||
import org.apache.http.Header;
|
||||
import org.apache.http.HttpRequest;
|
||||
import org.apache.http.annotation.NotThreadSafe;
|
||||
import org.apache.http.auth.AuthenticationException;
|
||||
import org.apache.http.auth.Credentials;
|
||||
import org.apache.http.protocol.HttpContext;
|
||||
import org.apache.http.util.Args;
|
||||
import org.ietf.jgss.GSSException;
|
||||
import org.ietf.jgss.Oid;
|
||||
|
||||
|
@ -67,59 +62,11 @@ public class SPNegoScheme extends GGSSchemeBase {
|
|||
return "Negotiate";
|
||||
}
|
||||
|
||||
/**
|
||||
* Produces SPNEGO authorization Header based on token created by
|
||||
* processChallenge.
|
||||
*
|
||||
* @param credentials not used by the SPNEGO scheme.
|
||||
* @param request The request being authenticated
|
||||
*
|
||||
* @throws AuthenticationException if authentication string cannot
|
||||
* be generated due to an authentication failure
|
||||
*
|
||||
* @return SPNEGO authentication Header
|
||||
*/
|
||||
@Override
|
||||
public Header authenticate(
|
||||
final Credentials credentials,
|
||||
final HttpRequest request,
|
||||
final HttpContext context) throws AuthenticationException {
|
||||
return super.authenticate(credentials, request, context);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected byte[] generateToken(final byte[] input, final String authServer, final Credentials credentials) throws GSSException {
|
||||
return generateGSSToken(input, new Oid(SPNEGO_OID), authServer, credentials);
|
||||
}
|
||||
|
||||
/**
|
||||
* There are no valid parameters for SPNEGO authentication so this
|
||||
* method always returns {@code null}.
|
||||
*
|
||||
* @return {@code null}
|
||||
*/
|
||||
@Override
|
||||
public String getParameter(final String name) {
|
||||
Args.notNull(name, "Parameter name");
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* The concept of an authentication realm is not supported by the Negotiate
|
||||
* authentication scheme. Always returns {@code null}.
|
||||
*
|
||||
* @return {@code null}
|
||||
*/
|
||||
@Override
|
||||
public String getRealm() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns {@code true}. SPNEGO authentication scheme is connection based.
|
||||
*
|
||||
* @return {@code true}.
|
||||
*/
|
||||
@Override
|
||||
public boolean isConnectionBased() {
|
||||
return true;
|
||||
|
|
|
@ -0,0 +1,111 @@
|
|||
/*
|
||||
* ====================================================================
|
||||
* 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.Serializable;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.http.NameValuePair;
|
||||
import org.apache.http.annotation.NotThreadSafe;
|
||||
import org.apache.http.auth.AuthChallenge;
|
||||
import org.apache.http.auth.AuthScheme;
|
||||
import org.apache.http.auth.ChallengeType;
|
||||
import org.apache.http.auth.MalformedChallengeException;
|
||||
|
||||
/**
|
||||
* Abstract authentication scheme class that lays foundation for standard HTTP authentication schemes and
|
||||
* provides capabilities common to all authentication schemes defined in the HTTP specification.
|
||||
*
|
||||
* @since 4.0
|
||||
*/
|
||||
@NotThreadSafe
|
||||
public abstract class StandardAuthScheme implements AuthScheme, Serializable {
|
||||
|
||||
private static final long serialVersionUID = -2845454858205884623L;
|
||||
|
||||
private final Map<String, String> paramMap;
|
||||
private ChallengeType challengeType;
|
||||
|
||||
/**
|
||||
* @since 4.3
|
||||
*/
|
||||
public StandardAuthScheme() {
|
||||
super();
|
||||
this.paramMap = new LinkedHashMap<>();
|
||||
}
|
||||
|
||||
protected void update(final ChallengeType challengeType, final AuthChallenge authChallenge) throws MalformedChallengeException {
|
||||
final List<NameValuePair> params = authChallenge.getParams();
|
||||
this.challengeType = challengeType;
|
||||
if (params != null) {
|
||||
for (NameValuePair param: params) {
|
||||
this.paramMap.put(param.getName().toLowerCase(Locale.ROOT), param.getValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getRealm() {
|
||||
return getParameter("realm");
|
||||
}
|
||||
|
||||
protected Map<String, String> getParameters() {
|
||||
return this.paramMap;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns authentication parameter with the given name, if available.
|
||||
*
|
||||
* @param name The name of the parameter to be returned
|
||||
*
|
||||
* @return the parameter with the given name
|
||||
*/
|
||||
@Override
|
||||
public String getParameter(final String name) {
|
||||
if (name == null) {
|
||||
return null;
|
||||
}
|
||||
return this.paramMap.get(name.toLowerCase(Locale.ROOT));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns {@code true} if authenticating against a proxy, {@code false}
|
||||
* otherwise.
|
||||
*/
|
||||
public boolean isProxy() {
|
||||
return this.challengeType != null && this.challengeType == ChallengeType.PROXY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return getSchemeName() + "(" + this.challengeType + ") " + this.paramMap;
|
||||
}
|
||||
|
||||
}
|
|
@ -30,7 +30,6 @@ package org.apache.http.impl.client;
|
|||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
@ -39,34 +38,37 @@ import java.util.Queue;
|
|||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.apache.http.FormattedHeader;
|
||||
import org.apache.http.Header;
|
||||
import org.apache.http.HttpHost;
|
||||
import org.apache.http.HttpResponse;
|
||||
import org.apache.http.annotation.Immutable;
|
||||
import org.apache.http.auth.AuthChallenge;
|
||||
import org.apache.http.auth.AuthOption;
|
||||
import org.apache.http.auth.AuthScheme;
|
||||
import org.apache.http.auth.AuthSchemeProvider;
|
||||
import org.apache.http.auth.AuthScope;
|
||||
import org.apache.http.auth.ChallengeType;
|
||||
import org.apache.http.auth.Credentials;
|
||||
import org.apache.http.auth.CredentialsProvider;
|
||||
import org.apache.http.auth.MalformedChallengeException;
|
||||
import org.apache.http.client.AuthCache;
|
||||
import org.apache.http.client.AuthenticationStrategy;
|
||||
import org.apache.http.client.config.AuthSchemes;
|
||||
import org.apache.http.client.config.RequestConfig;
|
||||
import org.apache.http.client.protocol.HttpClientContext;
|
||||
import org.apache.http.config.Lookup;
|
||||
import org.apache.http.protocol.HTTP;
|
||||
import org.apache.http.protocol.HttpContext;
|
||||
import org.apache.http.util.Args;
|
||||
import org.apache.http.util.CharArrayBuffer;
|
||||
|
||||
/**
|
||||
* Default implementation of {@link AuthenticationStrategy}
|
||||
*
|
||||
* @since 5.0
|
||||
*/
|
||||
@Immutable
|
||||
abstract class AuthenticationStrategyImpl implements AuthenticationStrategy {
|
||||
public class DefaultAuthenticationStrategy implements AuthenticationStrategy {
|
||||
|
||||
private final Log log = LogFactory.getLog(getClass());
|
||||
|
||||
public static final DefaultAuthenticationStrategy INSTANCE = new DefaultAuthenticationStrategy();
|
||||
|
||||
private static final List<String> DEFAULT_SCHEME_PRIORITY =
|
||||
Collections.unmodifiableList(Arrays.asList(
|
||||
AuthSchemes.SPNEGO,
|
||||
|
@ -75,82 +77,15 @@ abstract class AuthenticationStrategyImpl implements AuthenticationStrategy {
|
|||
AuthSchemes.DIGEST,
|
||||
AuthSchemes.BASIC));
|
||||
|
||||
private final int challengeCode;
|
||||
private final String headerName;
|
||||
|
||||
/**
|
||||
* @param challengeCode for example SC_PROXY_AUTHENTICATION_REQUIRED or SC_UNAUTHORIZED
|
||||
* @param headerName for example "Proxy-Authenticate" or "WWW-Authenticate"
|
||||
*/
|
||||
AuthenticationStrategyImpl(final int challengeCode, final String headerName) {
|
||||
super();
|
||||
this.challengeCode = challengeCode;
|
||||
this.headerName = headerName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAuthenticationRequested(
|
||||
final HttpHost authhost,
|
||||
final HttpResponse response,
|
||||
final HttpContext context) {
|
||||
Args.notNull(response, "HTTP response");
|
||||
final int status = response.getStatusLine().getStatusCode();
|
||||
return status == this.challengeCode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a map of challenge auth-scheme => Header entries.
|
||||
*
|
||||
* @return map: key=lower-cased auth-scheme name, value=Header that contains the challenge
|
||||
*/
|
||||
@Override
|
||||
public Map<String, Header> getChallenges(
|
||||
final HttpHost authhost,
|
||||
final HttpResponse response,
|
||||
final HttpContext context) throws MalformedChallengeException {
|
||||
Args.notNull(response, "HTTP response");
|
||||
final Header[] headers = response.getHeaders(this.headerName);
|
||||
final Map<String, Header> map = new HashMap<>(headers.length);
|
||||
for (final Header header : headers) {
|
||||
final CharArrayBuffer buffer;
|
||||
int pos;
|
||||
if (header instanceof FormattedHeader) {
|
||||
buffer = ((FormattedHeader) header).getBuffer();
|
||||
pos = ((FormattedHeader) header).getValuePos();
|
||||
} else {
|
||||
final String s = header.getValue();
|
||||
if (s == null) {
|
||||
throw new MalformedChallengeException("Header value is null");
|
||||
}
|
||||
buffer = new CharArrayBuffer(s.length());
|
||||
buffer.append(s);
|
||||
pos = 0;
|
||||
}
|
||||
while (pos < buffer.length() && HTTP.isWhitespace(buffer.charAt(pos))) {
|
||||
pos++;
|
||||
}
|
||||
final int beginIndex = pos;
|
||||
while (pos < buffer.length() && !HTTP.isWhitespace(buffer.charAt(pos))) {
|
||||
pos++;
|
||||
}
|
||||
final int endIndex = pos;
|
||||
final String s = buffer.substring(beginIndex, endIndex);
|
||||
map.put(s.toLowerCase(Locale.ROOT), header);
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
abstract Collection<String> getPreferredAuthSchemes(RequestConfig config);
|
||||
|
||||
@Override
|
||||
public Queue<AuthOption> select(
|
||||
final Map<String, Header> challenges,
|
||||
final ChallengeType challengeType,
|
||||
final HttpHost authhost,
|
||||
final HttpResponse response,
|
||||
final Map<String, AuthChallenge> challenges,
|
||||
final HttpContext context) throws MalformedChallengeException {
|
||||
Args.notNull(challengeType, "ChallengeType");
|
||||
Args.notNull(challenges, "Map of auth challenges");
|
||||
Args.notNull(authhost, "Host");
|
||||
Args.notNull(response, "HTTP response");
|
||||
Args.notNull(context, "HTTP context");
|
||||
final HttpClientContext clientContext = HttpClientContext.adapt(context);
|
||||
|
||||
|
@ -166,7 +101,8 @@ abstract class AuthenticationStrategyImpl implements AuthenticationStrategy {
|
|||
return options;
|
||||
}
|
||||
final RequestConfig config = clientContext.getRequestConfig();
|
||||
Collection<String> authPrefs = getPreferredAuthSchemes(config);
|
||||
Collection<String> authPrefs = challengeType == ChallengeType.TARGET ?
|
||||
config.getTargetPreferredAuthSchemes() : config.getProxyPreferredAuthSchemes();
|
||||
if (authPrefs == null) {
|
||||
authPrefs = DEFAULT_SCHEME_PRIORITY;
|
||||
}
|
||||
|
@ -175,7 +111,7 @@ abstract class AuthenticationStrategyImpl implements AuthenticationStrategy {
|
|||
}
|
||||
|
||||
for (final String id: authPrefs) {
|
||||
final Header challenge = challenges.get(id.toLowerCase(Locale.ROOT));
|
||||
final AuthChallenge challenge = challenges.get(id.toLowerCase(Locale.ROOT));
|
||||
if (challenge != null) {
|
||||
final AuthSchemeProvider authSchemeProvider = registry.lookup(id);
|
||||
if (authSchemeProvider == null) {
|
||||
|
@ -186,7 +122,7 @@ abstract class AuthenticationStrategyImpl implements AuthenticationStrategy {
|
|||
continue;
|
||||
}
|
||||
final AuthScheme authScheme = authSchemeProvider.create(context);
|
||||
authScheme.processChallenge(challenge);
|
||||
authScheme.processChallenge(challengeType, challenge);
|
||||
|
||||
final AuthScope authScope = new AuthScope(
|
||||
authhost.getHostName(),
|
||||
|
@ -208,53 +144,4 @@ abstract class AuthenticationStrategyImpl implements AuthenticationStrategy {
|
|||
return options;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void authSucceeded(
|
||||
final HttpHost authhost, final AuthScheme authScheme, final HttpContext context) {
|
||||
Args.notNull(authhost, "Host");
|
||||
Args.notNull(authScheme, "Auth scheme");
|
||||
Args.notNull(context, "HTTP context");
|
||||
|
||||
final HttpClientContext clientContext = HttpClientContext.adapt(context);
|
||||
|
||||
if (isCachable(authScheme)) {
|
||||
AuthCache authCache = clientContext.getAuthCache();
|
||||
if (authCache == null) {
|
||||
authCache = new BasicAuthCache();
|
||||
clientContext.setAuthCache(authCache);
|
||||
}
|
||||
if (this.log.isDebugEnabled()) {
|
||||
this.log.debug("Caching '" + authScheme.getSchemeName() +
|
||||
"' auth scheme for " + authhost);
|
||||
}
|
||||
authCache.put(authhost, authScheme);
|
||||
}
|
||||
}
|
||||
|
||||
protected boolean isCachable(final AuthScheme authScheme) {
|
||||
if (authScheme == null || !authScheme.isComplete()) {
|
||||
return false;
|
||||
}
|
||||
final String schemeName = authScheme.getSchemeName();
|
||||
return schemeName.equalsIgnoreCase(AuthSchemes.BASIC) ||
|
||||
schemeName.equalsIgnoreCase(AuthSchemes.DIGEST);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void authFailed(
|
||||
final HttpHost authhost, final AuthScheme authScheme, final HttpContext context) {
|
||||
Args.notNull(authhost, "Host");
|
||||
Args.notNull(context, "HTTP context");
|
||||
|
||||
final HttpClientContext clientContext = HttpClientContext.adapt(context);
|
||||
|
||||
final AuthCache authCache = clientContext.getAuthCache();
|
||||
if (authCache != null) {
|
||||
if (this.log.isDebugEnabled()) {
|
||||
this.log.debug("Clearing cached auth scheme for " + authhost);
|
||||
}
|
||||
authCache.remove(authhost);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -949,11 +949,11 @@ public class HttpClientBuilder {
|
|||
}
|
||||
AuthenticationStrategy targetAuthStrategyCopy = this.targetAuthStrategy;
|
||||
if (targetAuthStrategyCopy == null) {
|
||||
targetAuthStrategyCopy = TargetAuthenticationStrategy.INSTANCE;
|
||||
targetAuthStrategyCopy = DefaultAuthenticationStrategy.INSTANCE;
|
||||
}
|
||||
AuthenticationStrategy proxyAuthStrategyCopy = this.proxyAuthStrategy;
|
||||
if (proxyAuthStrategyCopy == null) {
|
||||
proxyAuthStrategyCopy = ProxyAuthenticationStrategy.INSTANCE;
|
||||
proxyAuthStrategyCopy = DefaultAuthenticationStrategy.INSTANCE;
|
||||
}
|
||||
UserTokenHandler userTokenHandlerCopy = this.userTokenHandler;
|
||||
if (userTokenHandlerCopy == null) {
|
||||
|
|
|
@ -41,7 +41,9 @@ import org.apache.http.auth.AUTH;
|
|||
import org.apache.http.auth.AuthSchemeProvider;
|
||||
import org.apache.http.auth.AuthScope;
|
||||
import org.apache.http.auth.AuthState;
|
||||
import org.apache.http.auth.ChallengeType;
|
||||
import org.apache.http.auth.Credentials;
|
||||
import org.apache.http.client.AuthenticationStrategy;
|
||||
import org.apache.http.client.config.AuthSchemes;
|
||||
import org.apache.http.client.config.RequestConfig;
|
||||
import org.apache.http.client.protocol.HttpClientContext;
|
||||
|
@ -86,7 +88,7 @@ public class ProxyClient {
|
|||
private final RequestConfig requestConfig;
|
||||
private final HttpProcessor httpProcessor;
|
||||
private final HttpRequestExecutor requestExec;
|
||||
private final ProxyAuthenticationStrategy proxyAuthStrategy;
|
||||
private final AuthenticationStrategy proxyAuthStrategy;
|
||||
private final HttpAuthenticator authenticator;
|
||||
private final AuthState proxyAuthState;
|
||||
private final Lookup<AuthSchemeProvider> authSchemeRegistry;
|
||||
|
@ -106,7 +108,7 @@ public class ProxyClient {
|
|||
this.httpProcessor = new ImmutableHttpProcessor(
|
||||
new RequestTargetHost(), new RequestClientConnControl(), new RequestUserAgent());
|
||||
this.requestExec = new HttpRequestExecutor();
|
||||
this.proxyAuthStrategy = new ProxyAuthenticationStrategy();
|
||||
this.proxyAuthStrategy = new DefaultAuthenticationStrategy();
|
||||
this.authenticator = new HttpAuthenticator();
|
||||
this.proxyAuthState = new AuthState();
|
||||
this.authSchemeRegistry = RegistryBuilder.<AuthSchemeProvider>create()
|
||||
|
@ -184,9 +186,8 @@ public class ProxyClient {
|
|||
throw new HttpException("Unexpected response to CONNECT request: " +
|
||||
response.getStatusLine());
|
||||
}
|
||||
if (this.authenticator.isAuthenticationRequested(proxy, response,
|
||||
this.proxyAuthStrategy, this.proxyAuthState, context)) {
|
||||
if (this.authenticator.handleAuthChallenge(proxy, response,
|
||||
if (this.authenticator.updateAuthState(proxy, ChallengeType.PROXY, response, this.proxyAuthState, context)) {
|
||||
if (this.authenticator.handleAuthChallenge(proxy, ChallengeType.PROXY, response,
|
||||
this.proxyAuthStrategy, this.proxyAuthState, context)) {
|
||||
// Retry request
|
||||
if (this.reuseStrategy.keepAlive(response, context)) {
|
||||
|
|
|
@ -1,57 +0,0 @@
|
|||
/*
|
||||
* ====================================================================
|
||||
* 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.client;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import org.apache.http.HttpStatus;
|
||||
import org.apache.http.annotation.Immutable;
|
||||
import org.apache.http.auth.AUTH;
|
||||
import org.apache.http.client.config.RequestConfig;
|
||||
|
||||
/**
|
||||
* Default {@link org.apache.http.client.AuthenticationStrategy} implementation
|
||||
* for proxy host authentication.
|
||||
*
|
||||
* @since 4.2
|
||||
*/
|
||||
@Immutable
|
||||
public class TargetAuthenticationStrategy extends AuthenticationStrategyImpl {
|
||||
|
||||
public static final TargetAuthenticationStrategy INSTANCE = new TargetAuthenticationStrategy();
|
||||
|
||||
public TargetAuthenticationStrategy() {
|
||||
super(HttpStatus.SC_UNAUTHORIZED, AUTH.WWW_AUTH);
|
||||
}
|
||||
|
||||
@Override
|
||||
Collection<String> getPreferredAuthSchemes(final RequestConfig config) {
|
||||
return config.getTargetPreferredAuthSchemes();
|
||||
}
|
||||
|
||||
}
|
|
@ -46,6 +46,7 @@ import org.apache.http.annotation.Immutable;
|
|||
import org.apache.http.auth.AUTH;
|
||||
import org.apache.http.auth.AuthProtocolState;
|
||||
import org.apache.http.auth.AuthState;
|
||||
import org.apache.http.auth.ChallengeType;
|
||||
import org.apache.http.client.AuthenticationStrategy;
|
||||
import org.apache.http.client.NonRepeatableRequestException;
|
||||
import org.apache.http.client.UserTokenHandler;
|
||||
|
@ -465,9 +466,9 @@ public class MainClientExec implements ClientExecChain {
|
|||
}
|
||||
|
||||
if (config.isAuthenticationEnabled()) {
|
||||
if (this.authenticator.isAuthenticationRequested(proxy, response,
|
||||
this.proxyAuthStrategy, proxyAuthState, context)) {
|
||||
if (this.authenticator.handleAuthChallenge(proxy, response,
|
||||
if (this.authenticator.updateAuthState(proxy, ChallengeType.PROXY, response,
|
||||
proxyAuthState, context)) {
|
||||
if (this.authenticator.handleAuthChallenge(proxy, ChallengeType.PROXY, response,
|
||||
this.proxyAuthStrategy, proxyAuthState, context)) {
|
||||
// Retry request
|
||||
if (this.reuseStrategy.keepAlive(response, context)) {
|
||||
|
@ -546,23 +547,23 @@ public class MainClientExec implements ClientExecChain {
|
|||
route.getTargetHost().getPort(),
|
||||
target.getSchemeName());
|
||||
}
|
||||
final boolean targetAuthRequested = this.authenticator.isAuthenticationRequested(
|
||||
target, response, this.targetAuthStrategy, targetAuthState, context);
|
||||
final boolean targetAuthRequested = this.authenticator.updateAuthState(
|
||||
target, ChallengeType.TARGET, response, targetAuthState, context);
|
||||
|
||||
HttpHost proxy = route.getProxyHost();
|
||||
// if proxy is not set use target host instead
|
||||
if (proxy == null) {
|
||||
proxy = route.getTargetHost();
|
||||
}
|
||||
final boolean proxyAuthRequested = this.authenticator.isAuthenticationRequested(
|
||||
proxy, response, this.proxyAuthStrategy, proxyAuthState, context);
|
||||
final boolean proxyAuthRequested = this.authenticator.updateAuthState(
|
||||
proxy, ChallengeType.PROXY, response, proxyAuthState, context);
|
||||
|
||||
if (targetAuthRequested) {
|
||||
return this.authenticator.handleAuthChallenge(target, response,
|
||||
return this.authenticator.handleAuthChallenge(target, ChallengeType.TARGET, response,
|
||||
this.targetAuthStrategy, targetAuthState, context);
|
||||
}
|
||||
if (proxyAuthRequested) {
|
||||
return this.authenticator.handleAuthChallenge(proxy, response,
|
||||
return this.authenticator.handleAuthChallenge(proxy, ChallengeType.PROXY, response,
|
||||
this.proxyAuthStrategy, proxyAuthState, context);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -58,6 +58,17 @@ public class TestAuthChallengeParser {
|
|||
Assert.assertEquals(null, nvp.getValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testParseTokenWithBlank() throws Exception {
|
||||
final CharArrayBuffer buffer = new CharArrayBuffer(64);
|
||||
buffer.append("blah ");
|
||||
final ParserCursor cursor = new ParserCursor(0, buffer.length());
|
||||
final NameValuePair nvp = parser.parseTokenOrParameter(buffer, cursor);
|
||||
Assert.assertNotNull(nvp);
|
||||
Assert.assertEquals("blah", nvp.getName());
|
||||
Assert.assertEquals(null, nvp.getValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testParseTokenWithBlanks() throws Exception {
|
||||
final CharArrayBuffer buffer = new CharArrayBuffer(64);
|
||||
|
|
|
@ -30,18 +30,22 @@ import java.io.ByteArrayInputStream;
|
|||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.io.ObjectOutputStream;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.commons.codec.binary.Base64;
|
||||
import org.apache.http.Consts;
|
||||
import org.apache.http.Header;
|
||||
import org.apache.http.HttpRequest;
|
||||
import org.apache.http.auth.AUTH;
|
||||
import org.apache.http.auth.AuthChallenge;
|
||||
import org.apache.http.auth.AuthScheme;
|
||||
import org.apache.http.auth.ChallengeType;
|
||||
import org.apache.http.auth.UsernamePasswordCredentials;
|
||||
import org.apache.http.message.BasicHeader;
|
||||
import org.apache.http.message.BasicHttpRequest;
|
||||
import org.apache.http.message.ParserCursor;
|
||||
import org.apache.http.protocol.BasicHttpContext;
|
||||
import org.apache.http.protocol.HttpContext;
|
||||
import org.apache.http.util.CharArrayBuffer;
|
||||
import org.apache.http.util.EncodingUtils;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
@ -51,12 +55,21 @@ import org.junit.Test;
|
|||
*/
|
||||
public class TestBasicScheme {
|
||||
|
||||
private static AuthChallenge parse(final String s) {
|
||||
final CharArrayBuffer buffer = new CharArrayBuffer(s.length());
|
||||
buffer.append(s);
|
||||
final ParserCursor cursor = new ParserCursor(0, buffer.length());
|
||||
final List<AuthChallenge> authChallenges = AuthChallengeParser.INSTANCE.parse(buffer, cursor);
|
||||
Assert.assertEquals(1, authChallenges.size());
|
||||
return authChallenges.get(0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBasicAuthenticationEmptyChallenge() throws Exception {
|
||||
final String challenge = "Basic";
|
||||
final Header header = new BasicHeader(AUTH.WWW_AUTH, challenge);
|
||||
final AuthChallenge authChallenge = parse(challenge);
|
||||
final AuthScheme authscheme = new BasicScheme();
|
||||
authscheme.processChallenge(header);
|
||||
authscheme.processChallenge(ChallengeType.TARGET, authChallenge);
|
||||
Assert.assertNull(authscheme.getRealm());
|
||||
}
|
||||
|
||||
|
@ -79,13 +92,12 @@ public class TestBasicScheme {
|
|||
|
||||
@Test
|
||||
public void testBasicAuthentication() throws Exception {
|
||||
final UsernamePasswordCredentials creds =
|
||||
new UsernamePasswordCredentials("testuser", "testpass");
|
||||
final UsernamePasswordCredentials creds = new UsernamePasswordCredentials("testuser", "testpass");
|
||||
|
||||
final Header challenge = new BasicHeader(AUTH.WWW_AUTH, "Basic realm=\"test\"");
|
||||
final AuthChallenge authChallenge = parse("Basic realm=\"test\"");
|
||||
|
||||
final BasicScheme authscheme = new BasicScheme();
|
||||
authscheme.processChallenge(challenge);
|
||||
authscheme.processChallenge(ChallengeType.TARGET, authChallenge);
|
||||
|
||||
final HttpRequest request = new BasicHttpRequest("GET", "/");
|
||||
final HttpContext context = new BasicHttpContext();
|
||||
|
@ -102,13 +114,12 @@ public class TestBasicScheme {
|
|||
|
||||
@Test
|
||||
public void testBasicProxyAuthentication() throws Exception {
|
||||
final UsernamePasswordCredentials creds =
|
||||
new UsernamePasswordCredentials("testuser", "testpass");
|
||||
final UsernamePasswordCredentials creds = new UsernamePasswordCredentials("testuser", "testpass");
|
||||
|
||||
final Header challenge = new BasicHeader(AUTH.PROXY_AUTH, "Basic realm=\"test\"");
|
||||
final AuthChallenge authChallenge = parse("Basic realm=\"test\"");
|
||||
|
||||
final BasicScheme authscheme = new BasicScheme();
|
||||
authscheme.processChallenge(challenge);
|
||||
authscheme.processChallenge(ChallengeType.PROXY, authChallenge);
|
||||
|
||||
final HttpRequest request = new BasicHttpRequest("GET", "/");
|
||||
final HttpContext context = new BasicHttpContext();
|
||||
|
@ -125,10 +136,10 @@ public class TestBasicScheme {
|
|||
|
||||
@Test
|
||||
public void testSerialization() throws Exception {
|
||||
final Header challenge = new BasicHeader(AUTH.PROXY_AUTH, "Basic realm=\"test\"");
|
||||
final AuthChallenge authChallenge = parse("Basic realm=\"test\"");
|
||||
|
||||
final BasicScheme basicScheme = new BasicScheme();
|
||||
basicScheme.processChallenge(challenge);
|
||||
basicScheme.processChallenge(ChallengeType.PROXY, authChallenge);
|
||||
|
||||
final ByteArrayOutputStream buffer = new ByteArrayOutputStream();
|
||||
final ObjectOutputStream out = new ObjectOutputStream(buffer);
|
||||
|
|
|
@ -33,27 +33,30 @@ import java.io.ObjectInputStream;
|
|||
import java.io.ObjectOutputStream;
|
||||
import java.security.MessageDigest;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.http.Header;
|
||||
import org.apache.http.HeaderElement;
|
||||
import org.apache.http.HttpEntityEnclosingRequest;
|
||||
import org.apache.http.HttpRequest;
|
||||
import org.apache.http.auth.AUTH;
|
||||
import org.apache.http.auth.AuthChallenge;
|
||||
import org.apache.http.auth.AuthScheme;
|
||||
import org.apache.http.auth.AuthenticationException;
|
||||
import org.apache.http.auth.ChallengeType;
|
||||
import org.apache.http.auth.Credentials;
|
||||
import org.apache.http.auth.MalformedChallengeException;
|
||||
import org.apache.http.auth.UsernamePasswordCredentials;
|
||||
import org.apache.http.entity.InputStreamEntity;
|
||||
import org.apache.http.entity.StringEntity;
|
||||
import org.apache.http.message.BasicHeader;
|
||||
import org.apache.http.message.BasicHeaderValueParser;
|
||||
import org.apache.http.message.BasicHttpEntityEnclosingRequest;
|
||||
import org.apache.http.message.BasicHttpRequest;
|
||||
import org.apache.http.message.ParserCursor;
|
||||
import org.apache.http.protocol.BasicHttpContext;
|
||||
import org.apache.http.protocol.HTTP;
|
||||
import org.apache.http.protocol.HttpContext;
|
||||
import org.apache.http.util.CharArrayBuffer;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
|
@ -62,29 +65,38 @@ import org.junit.Test;
|
|||
*/
|
||||
public class TestDigestScheme {
|
||||
|
||||
private static AuthChallenge parse(final String s) {
|
||||
final CharArrayBuffer buffer = new CharArrayBuffer(s.length());
|
||||
buffer.append(s);
|
||||
final ParserCursor cursor = new ParserCursor(0, buffer.length());
|
||||
final List<AuthChallenge> authChallenges = AuthChallengeParser.INSTANCE.parse(buffer, cursor);
|
||||
Assert.assertEquals(1, authChallenges.size());
|
||||
return authChallenges.get(0);
|
||||
}
|
||||
|
||||
@Test(expected=MalformedChallengeException.class)
|
||||
public void testDigestAuthenticationEmptyChallenge1() throws Exception {
|
||||
final Header authChallenge = new BasicHeader(AUTH.WWW_AUTH, "Digest");
|
||||
final AuthChallenge authChallenge = parse("Digest");
|
||||
final AuthScheme authscheme = new DigestScheme();
|
||||
authscheme.processChallenge(authChallenge);
|
||||
authscheme.processChallenge(ChallengeType.TARGET, authChallenge);
|
||||
}
|
||||
|
||||
@Test(expected=MalformedChallengeException.class)
|
||||
public void testDigestAuthenticationEmptyChallenge2() throws Exception {
|
||||
final Header authChallenge = new BasicHeader(AUTH.WWW_AUTH, "Digest ");
|
||||
final AuthChallenge authChallenge = parse("Digest ");
|
||||
final AuthScheme authscheme = new DigestScheme();
|
||||
authscheme.processChallenge(authChallenge);
|
||||
authscheme.processChallenge(ChallengeType.TARGET, authChallenge);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDigestAuthenticationWithDefaultCreds() throws Exception {
|
||||
final String challenge = "Digest realm=\"realm1\", nonce=\"f2a3f18799759d4f1a1c068b92b573cb\"";
|
||||
final Header authChallenge = new BasicHeader(AUTH.WWW_AUTH, challenge);
|
||||
final AuthChallenge authChallenge = parse(challenge);
|
||||
final HttpRequest request = new BasicHttpRequest("Simple", "/");
|
||||
final Credentials cred = new UsernamePasswordCredentials("username","password");
|
||||
final DigestScheme authscheme = new DigestScheme();
|
||||
final HttpContext context = new BasicHttpContext();
|
||||
authscheme.processChallenge(authChallenge);
|
||||
authscheme.processChallenge(ChallengeType.TARGET, authChallenge);
|
||||
final Header authResponse = authscheme.authenticate(cred, request, context);
|
||||
Assert.assertTrue(authscheme.isComplete());
|
||||
Assert.assertFalse(authscheme.isConnectionBased());
|
||||
|
@ -100,12 +112,12 @@ public class TestDigestScheme {
|
|||
@Test
|
||||
public void testDigestAuthentication() throws Exception {
|
||||
final String challenge = "Digest realm=\"realm1\", nonce=\"f2a3f18799759d4f1a1c068b92b573cb\"";
|
||||
final Header authChallenge = new BasicHeader(AUTH.WWW_AUTH, challenge);
|
||||
final AuthChallenge authChallenge = parse(challenge);
|
||||
final HttpRequest request = new BasicHttpRequest("Simple", "/");
|
||||
final Credentials cred = new UsernamePasswordCredentials("username","password");
|
||||
final DigestScheme authscheme = new DigestScheme();
|
||||
final HttpContext context = new BasicHttpContext();
|
||||
authscheme.processChallenge(authChallenge);
|
||||
authscheme.processChallenge(ChallengeType.TARGET, authChallenge);
|
||||
final Header authResponse = authscheme.authenticate(cred, request, context);
|
||||
|
||||
final Map<String, String> table = parseAuthResponse(authResponse);
|
||||
|
@ -119,12 +131,12 @@ public class TestDigestScheme {
|
|||
@Test
|
||||
public void testDigestAuthenticationInvalidInput() throws Exception {
|
||||
final String challenge = "Digest realm=\"realm1\", nonce=\"f2a3f18799759d4f1a1c068b92b573cb\"";
|
||||
final Header authChallenge = new BasicHeader(AUTH.WWW_AUTH, challenge);
|
||||
final AuthChallenge authChallenge = parse(challenge);
|
||||
final HttpRequest request = new BasicHttpRequest("Simple", "/");
|
||||
final Credentials cred = new UsernamePasswordCredentials("username","password");
|
||||
final DigestScheme authscheme = new DigestScheme();
|
||||
final HttpContext context = new BasicHttpContext();
|
||||
authscheme.processChallenge(authChallenge);
|
||||
authscheme.processChallenge(ChallengeType.TARGET, authChallenge);
|
||||
try {
|
||||
authscheme.authenticate(null, request, context);
|
||||
Assert.fail("IllegalArgumentException should have been thrown");
|
||||
|
@ -137,37 +149,17 @@ public class TestDigestScheme {
|
|||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDigestAuthenticationOverrideParameter() throws Exception {
|
||||
final String challenge = "Digest realm=\"realm1\", nonce=\"f2a3f18799759d4f1a1c068b92b573cb\"";
|
||||
final Header authChallenge = new BasicHeader(AUTH.WWW_AUTH, challenge);
|
||||
final HttpRequest request = new BasicHttpRequest("Simple", "/");
|
||||
final Credentials cred = new UsernamePasswordCredentials("username","password");
|
||||
final DigestScheme authscheme = new DigestScheme();
|
||||
final HttpContext context = new BasicHttpContext();
|
||||
authscheme.processChallenge(authChallenge);
|
||||
authscheme.overrideParamter("realm", "other realm");
|
||||
final Header authResponse = authscheme.authenticate(cred, request, context);
|
||||
|
||||
final Map<String, String> table = parseAuthResponse(authResponse);
|
||||
Assert.assertEquals("username", table.get("username"));
|
||||
Assert.assertEquals("other realm", table.get("realm"));
|
||||
Assert.assertEquals("/", table.get("uri"));
|
||||
Assert.assertEquals("f2a3f18799759d4f1a1c068b92b573cb", table.get("nonce"));
|
||||
Assert.assertEquals("3f211de10463cbd055ab4cd9c5158eac", table.get("response"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDigestAuthenticationWithSHA() throws Exception {
|
||||
final String challenge = "Digest realm=\"realm1\", " +
|
||||
"nonce=\"f2a3f18799759d4f1a1c068b92b573cb\", " +
|
||||
"algorithm=SHA";
|
||||
final Header authChallenge = new BasicHeader(AUTH.WWW_AUTH, challenge);
|
||||
final AuthChallenge authChallenge = parse(challenge);
|
||||
final HttpRequest request = new BasicHttpRequest("Simple", "/");
|
||||
final Credentials cred = new UsernamePasswordCredentials("username","password");
|
||||
final HttpContext context = new BasicHttpContext();
|
||||
final DigestScheme authscheme = new DigestScheme();
|
||||
authscheme.processChallenge(authChallenge);
|
||||
authscheme.processChallenge(ChallengeType.TARGET, authChallenge);
|
||||
final Header authResponse = authscheme.authenticate(cred, request, context);
|
||||
|
||||
final Map<String, String> table = parseAuthResponse(authResponse);
|
||||
|
@ -181,12 +173,12 @@ public class TestDigestScheme {
|
|||
@Test
|
||||
public void testDigestAuthenticationWithQueryStringInDigestURI() throws Exception {
|
||||
final String challenge = "Digest realm=\"realm1\", nonce=\"f2a3f18799759d4f1a1c068b92b573cb\"";
|
||||
final Header authChallenge = new BasicHeader(AUTH.WWW_AUTH, challenge);
|
||||
final AuthChallenge authChallenge = parse(challenge);
|
||||
final HttpRequest request = new BasicHttpRequest("Simple", "/?param=value");
|
||||
final Credentials cred = new UsernamePasswordCredentials("username","password");
|
||||
final HttpContext context = new BasicHttpContext();
|
||||
final DigestScheme authscheme = new DigestScheme();
|
||||
authscheme.processChallenge(authChallenge);
|
||||
authscheme.processChallenge(ChallengeType.TARGET, authChallenge);
|
||||
final Header authResponse = authscheme.authenticate(cred, request, context);
|
||||
|
||||
final Map<String, String> table = parseAuthResponse(authResponse);
|
||||
|
@ -204,11 +196,11 @@ public class TestDigestScheme {
|
|||
final Credentials cred = new UsernamePasswordCredentials("username","password");
|
||||
final Credentials cred2 = new UsernamePasswordCredentials("uname2","password2");
|
||||
|
||||
Header authChallenge = new BasicHeader(AUTH.WWW_AUTH, challenge1);
|
||||
final AuthChallenge authChallenge1 = parse(challenge1);
|
||||
final HttpRequest request = new BasicHttpRequest("Simple", "/");
|
||||
final HttpContext context = new BasicHttpContext();
|
||||
final DigestScheme authscheme = new DigestScheme();
|
||||
authscheme.processChallenge(authChallenge);
|
||||
authscheme.processChallenge(ChallengeType.TARGET, authChallenge1);
|
||||
Header authResponse = authscheme.authenticate(cred, request, context);
|
||||
|
||||
Map<String, String> table = parseAuthResponse(authResponse);
|
||||
|
@ -218,9 +210,9 @@ public class TestDigestScheme {
|
|||
Assert.assertEquals("abcde", table.get("nonce"));
|
||||
Assert.assertEquals("786f500303eac1478f3c2865e676ed68", table.get("response"));
|
||||
|
||||
authChallenge = new BasicHeader(AUTH.WWW_AUTH, challenge2);
|
||||
final AuthChallenge authChallenge2 = parse(challenge2);
|
||||
final DigestScheme authscheme2 = new DigestScheme();
|
||||
authscheme2.processChallenge(authChallenge);
|
||||
authscheme2.processChallenge(ChallengeType.TARGET, authChallenge2);
|
||||
authResponse = authscheme2.authenticate(cred2, request, context);
|
||||
|
||||
table = parseAuthResponse(authResponse);
|
||||
|
@ -234,10 +226,10 @@ public class TestDigestScheme {
|
|||
@Test(expected=AuthenticationException.class)
|
||||
public void testDigestAuthenticationNoRealm() throws Exception {
|
||||
final String challenge = "Digest no-realm=\"realm1\", nonce=\"f2a3f18799759d4f1a1c068b92b573cb\"";
|
||||
final Header authChallenge = new BasicHeader(AUTH.WWW_AUTH, challenge);
|
||||
final AuthChallenge authChallenge = parse(challenge);
|
||||
final HttpContext context = new BasicHttpContext();
|
||||
final DigestScheme authscheme = new DigestScheme();
|
||||
authscheme.processChallenge(authChallenge);
|
||||
authscheme.processChallenge(ChallengeType.TARGET, authChallenge);
|
||||
|
||||
final Credentials cred = new UsernamePasswordCredentials("username","password");
|
||||
final HttpRequest request = new BasicHttpRequest("Simple", "/");
|
||||
|
@ -247,10 +239,10 @@ public class TestDigestScheme {
|
|||
@Test(expected=AuthenticationException.class)
|
||||
public void testDigestAuthenticationNoNonce() throws Exception {
|
||||
final String challenge = "Digest realm=\"realm1\", no-nonce=\"f2a3f18799759d4f1a1c068b92b573cb\"";
|
||||
final Header authChallenge = new BasicHeader(AUTH.WWW_AUTH, challenge);
|
||||
final AuthChallenge authChallenge = parse(challenge);
|
||||
final HttpContext context = new BasicHttpContext();
|
||||
final DigestScheme authscheme = new DigestScheme();
|
||||
authscheme.processChallenge(authChallenge);
|
||||
authscheme.processChallenge(ChallengeType.TARGET, authChallenge);
|
||||
|
||||
final Credentials cred = new UsernamePasswordCredentials("username","password");
|
||||
final HttpRequest request = new BasicHttpRequest("Simple", "/");
|
||||
|
@ -276,14 +268,14 @@ public class TestDigestScheme {
|
|||
+ "algorithm=MD5-sess, "
|
||||
+ "qop=\"auth,auth-int\""; // we pass both but expect auth to be used
|
||||
|
||||
final Header authChallenge = new BasicHeader(AUTH.WWW_AUTH, challenge);
|
||||
final AuthChallenge authChallenge = parse(challenge);
|
||||
|
||||
final Credentials cred = new UsernamePasswordCredentials(username, password);
|
||||
final HttpRequest request = new BasicHttpRequest("Simple", "/");
|
||||
final HttpContext context = new BasicHttpContext();
|
||||
|
||||
final DigestScheme authscheme = new DigestScheme();
|
||||
authscheme.processChallenge(authChallenge);
|
||||
authscheme.processChallenge(ChallengeType.TARGET, authChallenge);
|
||||
final Header authResponse = authscheme.authenticate(cred, request, context);
|
||||
final String response = authResponse.getValue();
|
||||
|
||||
|
@ -322,7 +314,7 @@ public class TestDigestScheme {
|
|||
+ "stale=false, "
|
||||
+ "algorithm=MD5-sess";
|
||||
|
||||
final Header authChallenge = new BasicHeader(AUTH.WWW_AUTH, challenge);
|
||||
final AuthChallenge authChallenge = parse(challenge);
|
||||
|
||||
final Credentials cred = new UsernamePasswordCredentials(username, password);
|
||||
|
||||
|
@ -330,7 +322,7 @@ public class TestDigestScheme {
|
|||
final HttpContext context = new BasicHttpContext();
|
||||
|
||||
final DigestScheme authscheme = new DigestScheme();
|
||||
authscheme.processChallenge(authChallenge);
|
||||
authscheme.processChallenge(ChallengeType.TARGET, authChallenge);
|
||||
final Header authResponse = authscheme.authenticate(cred, request, context);
|
||||
|
||||
final Map<String, String> table = parseAuthResponse(authResponse);
|
||||
|
@ -365,10 +357,10 @@ public class TestDigestScheme {
|
|||
+ "algorithm=MD5-sess, "
|
||||
+ "qop=\"stuff\"";
|
||||
|
||||
final Header authChallenge = new BasicHeader(AUTH.WWW_AUTH, challenge);
|
||||
final AuthChallenge authChallenge = parse(challenge);
|
||||
|
||||
final DigestScheme authscheme = new DigestScheme();
|
||||
authscheme.processChallenge(authChallenge);
|
||||
authscheme.processChallenge(ChallengeType.TARGET, authChallenge);
|
||||
|
||||
final Credentials cred = new UsernamePasswordCredentials(username, password);
|
||||
final HttpRequest request = new BasicHttpRequest("Simple", "/");
|
||||
|
@ -395,10 +387,10 @@ public class TestDigestScheme {
|
|||
+ "algorithm=stuff, "
|
||||
+ "qop=\"auth\"";
|
||||
|
||||
final Header authChallenge = new BasicHeader(AUTH.WWW_AUTH, challenge);
|
||||
final AuthChallenge authChallenge = parse(challenge);
|
||||
|
||||
final DigestScheme authscheme = new DigestScheme();
|
||||
authscheme.processChallenge(authChallenge);
|
||||
authscheme.processChallenge(ChallengeType.TARGET, authChallenge);
|
||||
|
||||
final Credentials cred = new UsernamePasswordCredentials(username, password);
|
||||
final HttpRequest request = new BasicHttpRequest("Simple", "/");
|
||||
|
@ -410,9 +402,9 @@ public class TestDigestScheme {
|
|||
public void testDigestAuthenticationWithStaleNonce() throws Exception {
|
||||
final String challenge = "Digest realm=\"realm1\", " +
|
||||
"nonce=\"f2a3f18799759d4f1a1c068b92b573cb\", stale=\"true\"";
|
||||
final Header authChallenge = new BasicHeader(AUTH.WWW_AUTH, challenge);
|
||||
final AuthChallenge authChallenge = parse(challenge);
|
||||
final AuthScheme authscheme = new DigestScheme();
|
||||
authscheme.processChallenge(authChallenge);
|
||||
authscheme.processChallenge(ChallengeType.TARGET, authChallenge);
|
||||
|
||||
Assert.assertFalse(authscheme.isComplete());
|
||||
}
|
||||
|
@ -433,12 +425,12 @@ public class TestDigestScheme {
|
|||
@Test
|
||||
public void testDigestNouceCount() throws Exception {
|
||||
final String challenge1 = "Digest realm=\"realm1\", nonce=\"f2a3f18799759d4f1a1c068b92b573cb\", qop=auth";
|
||||
final Header authChallenge1 = new BasicHeader(AUTH.WWW_AUTH, challenge1);
|
||||
final AuthChallenge authChallenge1 = parse(challenge1);
|
||||
final HttpRequest request = new BasicHttpRequest("GET", "/");
|
||||
final Credentials cred = new UsernamePasswordCredentials("username","password");
|
||||
final HttpContext context = new BasicHttpContext();
|
||||
final DigestScheme authscheme = new DigestScheme();
|
||||
authscheme.processChallenge(authChallenge1);
|
||||
authscheme.processChallenge(ChallengeType.TARGET, authChallenge1);
|
||||
final Header authResponse1 = authscheme.authenticate(cred, request, context);
|
||||
final Map<String, String> table1 = parseAuthResponse(authResponse1);
|
||||
Assert.assertEquals("00000001", table1.get("nc"));
|
||||
|
@ -446,14 +438,14 @@ public class TestDigestScheme {
|
|||
final Map<String, String> table2 = parseAuthResponse(authResponse2);
|
||||
Assert.assertEquals("00000002", table2.get("nc"));
|
||||
final String challenge2 = "Digest realm=\"realm1\", nonce=\"f2a3f18799759d4f1a1c068b92b573cb\", qop=auth";
|
||||
final Header authChallenge2 = new BasicHeader(AUTH.WWW_AUTH, challenge2);
|
||||
authscheme.processChallenge(authChallenge2);
|
||||
final AuthChallenge authChallenge2 = parse(challenge2);
|
||||
authscheme.processChallenge(ChallengeType.TARGET, authChallenge2);
|
||||
final Header authResponse3 = authscheme.authenticate(cred, request, context);
|
||||
final Map<String, String> table3 = parseAuthResponse(authResponse3);
|
||||
Assert.assertEquals("00000003", table3.get("nc"));
|
||||
final String challenge3 = "Digest realm=\"realm1\", nonce=\"e273f1776275974f1a120d8b92c5b3cb\", qop=auth";
|
||||
final Header authChallenge3 = new BasicHeader(AUTH.WWW_AUTH, challenge3);
|
||||
authscheme.processChallenge(authChallenge3);
|
||||
final AuthChallenge authChallenge3 = parse(challenge3);
|
||||
authscheme.processChallenge(ChallengeType.TARGET, authChallenge3);
|
||||
final Header authResponse4 = authscheme.authenticate(cred, request, context);
|
||||
final Map<String, String> table4 = parseAuthResponse(authResponse4);
|
||||
Assert.assertEquals("00000001", table4.get("nc"));
|
||||
|
@ -463,12 +455,12 @@ public class TestDigestScheme {
|
|||
public void testDigestMD5SessA1AndCnonceConsistency() throws Exception {
|
||||
final String challenge1 = "Digest qop=\"auth\", algorithm=MD5-sess, nonce=\"1234567890abcdef\", " +
|
||||
"charset=utf-8, realm=\"subnet.domain.com\"";
|
||||
final Header authChallenge1 = new BasicHeader(AUTH.WWW_AUTH, challenge1);
|
||||
final AuthChallenge authChallenge1 = parse(challenge1);
|
||||
final HttpRequest request = new BasicHttpRequest("GET", "/");
|
||||
final Credentials cred = new UsernamePasswordCredentials("username","password");
|
||||
final HttpContext context = new BasicHttpContext();
|
||||
final DigestScheme authscheme = new DigestScheme();
|
||||
authscheme.processChallenge(authChallenge1);
|
||||
authscheme.processChallenge(ChallengeType.TARGET, authChallenge1);
|
||||
final Header authResponse1 = authscheme.authenticate(cred, request, context);
|
||||
final Map<String, String> table1 = parseAuthResponse(authResponse1);
|
||||
Assert.assertEquals("00000001", table1.get("nc"));
|
||||
|
@ -486,8 +478,8 @@ public class TestDigestScheme {
|
|||
|
||||
final String challenge2 = "Digest qop=\"auth\", algorithm=MD5-sess, nonce=\"1234567890abcdef\", " +
|
||||
"charset=utf-8, realm=\"subnet.domain.com\"";
|
||||
final Header authChallenge2 = new BasicHeader(AUTH.WWW_AUTH, challenge2);
|
||||
authscheme.processChallenge(authChallenge2);
|
||||
final AuthChallenge authChallenge2 = parse(challenge2);
|
||||
authscheme.processChallenge(ChallengeType.TARGET, authChallenge2);
|
||||
final Header authResponse3 = authscheme.authenticate(cred, request, context);
|
||||
final Map<String, String> table3 = parseAuthResponse(authResponse3);
|
||||
Assert.assertEquals("00000003", table3.get("nc"));
|
||||
|
@ -500,8 +492,8 @@ public class TestDigestScheme {
|
|||
|
||||
final String challenge3 = "Digest qop=\"auth\", algorithm=MD5-sess, nonce=\"fedcba0987654321\", " +
|
||||
"charset=utf-8, realm=\"subnet.domain.com\"";
|
||||
final Header authChallenge3 = new BasicHeader(AUTH.WWW_AUTH, challenge3);
|
||||
authscheme.processChallenge(authChallenge3);
|
||||
final AuthChallenge authChallenge3 = parse(challenge3);
|
||||
authscheme.processChallenge(ChallengeType.TARGET, authChallenge3);
|
||||
final Header authResponse4 = authscheme.authenticate(cred, request, context);
|
||||
final Map<String, String> table4 = parseAuthResponse(authResponse4);
|
||||
Assert.assertEquals("00000001", table4.get("nc"));
|
||||
|
@ -543,13 +535,13 @@ public class TestDigestScheme {
|
|||
public void testDigestAuthenticationQopAuthInt() throws Exception {
|
||||
final String challenge = "Digest realm=\"realm1\", nonce=\"f2a3f18799759d4f1a1c068b92b573cb\", " +
|
||||
"qop=\"auth,auth-int\"";
|
||||
final Header authChallenge = new BasicHeader(AUTH.WWW_AUTH, challenge);
|
||||
final AuthChallenge authChallenge = parse(challenge);
|
||||
final HttpEntityEnclosingRequest request = new BasicHttpEntityEnclosingRequest("Post", "/");
|
||||
request.setEntity(new StringEntity("abc\u00e4\u00f6\u00fcabc", HTTP.DEF_CONTENT_CHARSET));
|
||||
final Credentials cred = new UsernamePasswordCredentials("username","password");
|
||||
final DigestScheme authscheme = new DigestScheme();
|
||||
final HttpContext context = new BasicHttpContext();
|
||||
authscheme.processChallenge(authChallenge);
|
||||
authscheme.processChallenge(ChallengeType.TARGET, authChallenge);
|
||||
final Header authResponse = authscheme.authenticate(cred, request, context);
|
||||
|
||||
Assert.assertEquals("Post:/:acd2b59cd01c7737d8069015584c6cac", authscheme.getA2());
|
||||
|
@ -566,12 +558,12 @@ public class TestDigestScheme {
|
|||
public void testDigestAuthenticationQopAuthIntNullEntity() throws Exception {
|
||||
final String challenge = "Digest realm=\"realm1\", nonce=\"f2a3f18799759d4f1a1c068b92b573cb\", " +
|
||||
"qop=\"auth,auth-int\"";
|
||||
final Header authChallenge = new BasicHeader(AUTH.WWW_AUTH, challenge);
|
||||
final AuthChallenge authChallenge = parse(challenge);
|
||||
final HttpRequest request = new BasicHttpEntityEnclosingRequest("Post", "/");
|
||||
final Credentials cred = new UsernamePasswordCredentials("username","password");
|
||||
final DigestScheme authscheme = new DigestScheme();
|
||||
final HttpContext context = new BasicHttpContext();
|
||||
authscheme.processChallenge(authChallenge);
|
||||
authscheme.processChallenge(ChallengeType.TARGET, authChallenge);
|
||||
final Header authResponse = authscheme.authenticate(cred, request, context);
|
||||
|
||||
Assert.assertEquals("Post:/:d41d8cd98f00b204e9800998ecf8427e", authscheme.getA2());
|
||||
|
@ -588,13 +580,13 @@ public class TestDigestScheme {
|
|||
public void testDigestAuthenticationQopAuthOrAuthIntNonRepeatableEntity() throws Exception {
|
||||
final String challenge = "Digest realm=\"realm1\", nonce=\"f2a3f18799759d4f1a1c068b92b573cb\", " +
|
||||
"qop=\"auth,auth-int\"";
|
||||
final Header authChallenge = new BasicHeader(AUTH.WWW_AUTH, challenge);
|
||||
final AuthChallenge authChallenge = parse(challenge);
|
||||
final HttpEntityEnclosingRequest request = new BasicHttpEntityEnclosingRequest("Post", "/");
|
||||
request.setEntity(new InputStreamEntity(new ByteArrayInputStream(new byte[] {'a'}), -1));
|
||||
final Credentials cred = new UsernamePasswordCredentials("username","password");
|
||||
final DigestScheme authscheme = new DigestScheme();
|
||||
final HttpContext context = new BasicHttpContext();
|
||||
authscheme.processChallenge(authChallenge);
|
||||
authscheme.processChallenge(ChallengeType.TARGET, authChallenge);
|
||||
final Header authResponse = authscheme.authenticate(cred, request, context);
|
||||
|
||||
Assert.assertEquals("Post:/", authscheme.getA2());
|
||||
|
@ -612,12 +604,12 @@ public class TestDigestScheme {
|
|||
final String challenge = "Digest Realm=\"-\", " +
|
||||
"nonce=\"YjYuNGYyYmJhMzUuY2I5ZDhlZDE5M2ZlZDM 1Mjk3NGJkNTIyYjgyNTcwMjQ=\", " +
|
||||
"opaque=\"98700A3D9CE17065E2246B41035C6609\", qop=\"auth\"";
|
||||
final Header authChallenge = new BasicHeader(AUTH.PROXY_AUTH, challenge);
|
||||
final AuthChallenge authChallenge = parse(challenge);
|
||||
final HttpRequest request = new BasicHttpRequest("GET", "/");
|
||||
final Credentials cred = new UsernamePasswordCredentials("username","password");
|
||||
final DigestScheme authscheme = new DigestScheme();
|
||||
final HttpContext context = new BasicHttpContext();
|
||||
authscheme.processChallenge(authChallenge);
|
||||
authscheme.processChallenge(ChallengeType.TARGET, authChallenge);
|
||||
Assert.assertEquals("-", authscheme.getRealm());
|
||||
|
||||
authscheme.authenticate(cred, request, context);
|
||||
|
@ -627,13 +619,13 @@ public class TestDigestScheme {
|
|||
public void testDigestAuthenticationQopIntOnlyNonRepeatableEntity() throws Exception {
|
||||
final String challenge = "Digest realm=\"realm1\", nonce=\"f2a3f18799759d4f1a1c068b92b573cb\", " +
|
||||
"qop=\"auth-int\"";
|
||||
final Header authChallenge = new BasicHeader(AUTH.WWW_AUTH, challenge);
|
||||
final AuthChallenge authChallenge = parse(challenge);
|
||||
final HttpEntityEnclosingRequest request = new BasicHttpEntityEnclosingRequest("Post", "/");
|
||||
request.setEntity(new InputStreamEntity(new ByteArrayInputStream(new byte[] {'a'}), -1));
|
||||
final Credentials cred = new UsernamePasswordCredentials("username","password");
|
||||
final DigestScheme authscheme = new DigestScheme();
|
||||
final HttpContext context = new BasicHttpContext();
|
||||
authscheme.processChallenge(authChallenge);
|
||||
authscheme.processChallenge(ChallengeType.TARGET, authChallenge);
|
||||
authscheme.authenticate(cred, request, context);
|
||||
}
|
||||
|
||||
|
@ -641,9 +633,9 @@ public class TestDigestScheme {
|
|||
public void testSerialization() throws Exception {
|
||||
final String challenge = "Digest realm=\"realm1\", nonce=\"f2a3f18799759d4f1a1c068b92b573cb\", " +
|
||||
"qop=\"auth,auth-int\"";
|
||||
final Header authChallenge = new BasicHeader(AUTH.WWW_AUTH, challenge);
|
||||
final AuthChallenge authChallenge = parse(challenge);
|
||||
final DigestScheme digestScheme = new DigestScheme();
|
||||
digestScheme.processChallenge(authChallenge);
|
||||
digestScheme.processChallenge(ChallengeType.TARGET, authChallenge);
|
||||
|
||||
final ByteArrayOutputStream buffer = new ByteArrayOutputStream();
|
||||
final ObjectOutputStream out = new ObjectOutputStream(buffer);
|
||||
|
|
|
@ -26,11 +26,10 @@
|
|||
*/
|
||||
package org.apache.http.impl.auth;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedList;
|
||||
import java.util.Queue;
|
||||
|
||||
import org.apache.http.Header;
|
||||
import org.apache.http.HttpHeaders;
|
||||
import org.apache.http.HttpHost;
|
||||
import org.apache.http.HttpRequest;
|
||||
import org.apache.http.HttpResponse;
|
||||
|
@ -44,15 +43,14 @@ import org.apache.http.auth.AuthSchemeProvider;
|
|||
import org.apache.http.auth.AuthScope;
|
||||
import org.apache.http.auth.AuthState;
|
||||
import org.apache.http.auth.AuthenticationException;
|
||||
import org.apache.http.auth.ChallengeType;
|
||||
import org.apache.http.auth.Credentials;
|
||||
import org.apache.http.auth.MalformedChallengeException;
|
||||
import org.apache.http.client.AuthCache;
|
||||
import org.apache.http.client.AuthenticationStrategy;
|
||||
import org.apache.http.client.protocol.HttpClientContext;
|
||||
import org.apache.http.config.Lookup;
|
||||
import org.apache.http.config.RegistryBuilder;
|
||||
import org.apache.http.impl.client.BasicCredentialsProvider;
|
||||
import org.apache.http.impl.client.TargetAuthenticationStrategy;
|
||||
import org.apache.http.impl.client.DefaultAuthenticationStrategy;
|
||||
import org.apache.http.message.BasicHeader;
|
||||
import org.apache.http.message.BasicHttpRequest;
|
||||
import org.apache.http.message.BasicHttpResponse;
|
||||
|
@ -67,7 +65,6 @@ import org.mockito.Mockito;
|
|||
@SuppressWarnings({"boxing","static-access"})
|
||||
public class TestHttpAuthenticator {
|
||||
|
||||
private AuthenticationStrategy defltAuthStrategy;
|
||||
private AuthState authState;
|
||||
private AuthScheme authScheme;
|
||||
private HttpContext context;
|
||||
|
@ -80,7 +77,6 @@ public class TestHttpAuthenticator {
|
|||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
this.defltAuthStrategy = Mockito.mock(AuthenticationStrategy.class);
|
||||
this.authState = new AuthState();
|
||||
this.authScheme = Mockito.mock(AuthScheme.class);
|
||||
Mockito.when(this.authScheme.getSchemeName()).thenReturn("Basic");
|
||||
|
@ -103,86 +99,61 @@ public class TestHttpAuthenticator {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void testAuthenticationRequested() throws Exception {
|
||||
public void testUpdateAuthState() throws Exception {
|
||||
final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_UNAUTHORIZED, "UNAUTHORIZED");
|
||||
Mockito.when(this.defltAuthStrategy.isAuthenticationRequested(
|
||||
Mockito.any(HttpHost.class),
|
||||
Mockito.any(HttpResponse.class),
|
||||
Mockito.any(HttpContext.class))).thenReturn(Boolean.TRUE);
|
||||
|
||||
Assert.assertTrue(this.httpAuthenticator.isAuthenticationRequested(
|
||||
this.defaultHost, response, this.defltAuthStrategy, this.authState, this.context));
|
||||
|
||||
Mockito.verify(this.defltAuthStrategy).isAuthenticationRequested(this.defaultHost, response, this.context);
|
||||
response.setHeader(HttpHeaders.WWW_AUTHENTICATE, "Basic realm=test");
|
||||
Assert.assertTrue(this.httpAuthenticator.updateAuthState(
|
||||
this.defaultHost, ChallengeType.TARGET, response, this.authState, this.context));
|
||||
Mockito.verifyZeroInteractions(this.authCache);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAuthenticationRequestedAfterSuccess() throws Exception {
|
||||
final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_UNAUTHORIZED, "UNAUTHORIZED");
|
||||
Mockito.when(this.defltAuthStrategy.isAuthenticationRequested(
|
||||
Mockito.any(HttpHost.class),
|
||||
Mockito.any(HttpResponse.class),
|
||||
Mockito.any(HttpContext.class))).thenReturn(Boolean.TRUE);
|
||||
response.setHeader(HttpHeaders.WWW_AUTHENTICATE, "Basic realm=test");
|
||||
|
||||
this.authState.update(this.authScheme, this.credentials);
|
||||
this.authState.setState(AuthProtocolState.SUCCESS);
|
||||
|
||||
Assert.assertTrue(this.httpAuthenticator.isAuthenticationRequested(
|
||||
this.defaultHost, response, this.defltAuthStrategy, this.authState, this.context));
|
||||
Assert.assertTrue(this.httpAuthenticator.updateAuthState(
|
||||
this.defaultHost, ChallengeType.TARGET, response, this.authState, this.context));
|
||||
|
||||
Mockito.verify(this.defltAuthStrategy).isAuthenticationRequested(this.defaultHost, response, this.context);
|
||||
Mockito.verify(this.defltAuthStrategy).authFailed(this.defaultHost, this.authScheme, this.context);
|
||||
Mockito.verify(this.authCache).remove(this.defaultHost);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAuthenticationNotRequestedUnchallenged() throws Exception {
|
||||
final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK");
|
||||
Mockito.when(this.defltAuthStrategy.isAuthenticationRequested(
|
||||
Mockito.any(HttpHost.class),
|
||||
Mockito.any(HttpResponse.class),
|
||||
Mockito.any(HttpContext.class))).thenReturn(Boolean.FALSE);
|
||||
|
||||
Assert.assertFalse(this.httpAuthenticator.isAuthenticationRequested(
|
||||
this.defaultHost, response, this.defltAuthStrategy, this.authState, this.context));
|
||||
Assert.assertFalse(this.httpAuthenticator.updateAuthState(
|
||||
this.defaultHost, ChallengeType.TARGET, response, this.authState, this.context));
|
||||
Assert.assertEquals(AuthProtocolState.UNCHALLENGED, this.authState.getState());
|
||||
|
||||
Mockito.verify(this.defltAuthStrategy).isAuthenticationRequested(this.defaultHost, response, this.context);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAuthenticationNotRequestedSuccess1() throws Exception {
|
||||
final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK");
|
||||
Mockito.when(this.defltAuthStrategy.isAuthenticationRequested(
|
||||
Mockito.any(HttpHost.class),
|
||||
Mockito.any(HttpResponse.class),
|
||||
Mockito.any(HttpContext.class))).thenReturn(Boolean.FALSE);
|
||||
this.authState.update(this.authScheme, this.credentials);
|
||||
this.authState.setState(AuthProtocolState.CHALLENGED);
|
||||
|
||||
Assert.assertFalse(this.httpAuthenticator.isAuthenticationRequested(
|
||||
this.defaultHost, response, this.defltAuthStrategy, this.authState, this.context));
|
||||
Assert.assertFalse(this.httpAuthenticator.updateAuthState(
|
||||
this.defaultHost, ChallengeType.TARGET, response, this.authState, this.context));
|
||||
Assert.assertEquals(AuthProtocolState.SUCCESS, this.authState.getState());
|
||||
|
||||
Mockito.verify(this.defltAuthStrategy).isAuthenticationRequested(this.defaultHost, response, this.context);
|
||||
Mockito.verify(this.defltAuthStrategy).authSucceeded(this.defaultHost, this.authScheme, this.context);
|
||||
Mockito.verify(this.authCache).put(this.defaultHost, this.authScheme);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAuthenticationNotRequestedSuccess2() throws Exception {
|
||||
final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK");
|
||||
Mockito.when(this.defltAuthStrategy.isAuthenticationRequested(
|
||||
Mockito.any(HttpHost.class),
|
||||
Mockito.any(HttpResponse.class),
|
||||
Mockito.any(HttpContext.class))).thenReturn(Boolean.FALSE);
|
||||
this.authState.update(this.authScheme, this.credentials);
|
||||
this.authState.setState(AuthProtocolState.HANDSHAKE);
|
||||
|
||||
Assert.assertFalse(this.httpAuthenticator.isAuthenticationRequested(
|
||||
this.defaultHost, response, this.defltAuthStrategy, this.authState, this.context));
|
||||
Assert.assertFalse(this.httpAuthenticator.updateAuthState(
|
||||
this.defaultHost, ChallengeType.TARGET, response, this.authState, this.context));
|
||||
Assert.assertEquals(AuthProtocolState.SUCCESS, this.authState.getState());
|
||||
|
||||
Mockito.verify(this.defltAuthStrategy).isAuthenticationRequested(this.defaultHost, response, this.context);
|
||||
Mockito.verify(this.defltAuthStrategy).authSucceeded(this.defaultHost, this.authScheme, this.context);
|
||||
Mockito.verify(this.authCache).put(this.defaultHost, this.authScheme);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -193,10 +164,10 @@ public class TestHttpAuthenticator {
|
|||
response.addHeader(new BasicHeader(AUTH.WWW_AUTH, "Digest realm=\"realm1\", nonce=\"1234\""));
|
||||
response.addHeader(new BasicHeader(AUTH.WWW_AUTH, "whatever realm=\"realm1\", stuff=\"1234\""));
|
||||
|
||||
final TargetAuthenticationStrategy authStrategy = new TargetAuthenticationStrategy();
|
||||
final DefaultAuthenticationStrategy authStrategy = new DefaultAuthenticationStrategy();
|
||||
|
||||
Assert.assertTrue(this.httpAuthenticator.handleAuthChallenge(host,
|
||||
response, authStrategy, this.authState, this.context));
|
||||
Assert.assertTrue(this.httpAuthenticator.handleAuthChallenge(
|
||||
host,ChallengeType.TARGET, response, authStrategy, this.authState, this.context));
|
||||
Assert.assertEquals(AuthProtocolState.CHALLENGED, this.authState.getState());
|
||||
|
||||
final Queue<AuthOption> options = this.authState.getAuthOptions();
|
||||
|
@ -215,13 +186,10 @@ public class TestHttpAuthenticator {
|
|||
final HttpHost host = new HttpHost("somehost", 80);
|
||||
final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_UNAUTHORIZED, "UNAUTHORIZED");
|
||||
|
||||
Mockito.when(this.defltAuthStrategy.getChallenges(
|
||||
Mockito.any(HttpHost.class),
|
||||
Mockito.any(HttpResponse.class),
|
||||
Mockito.any(HttpContext.class))).thenReturn(new HashMap<String, Header>());
|
||||
final DefaultAuthenticationStrategy authStrategy = new DefaultAuthenticationStrategy();
|
||||
|
||||
Assert.assertFalse(this.httpAuthenticator.handleAuthChallenge(host,
|
||||
response, this.defltAuthStrategy, this.authState, this.context));
|
||||
Assert.assertFalse(this.httpAuthenticator.handleAuthChallenge(
|
||||
host, ChallengeType.TARGET, response, authStrategy, this.authState, this.context));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -231,10 +199,10 @@ public class TestHttpAuthenticator {
|
|||
response.addHeader(new BasicHeader(AUTH.WWW_AUTH, "This realm=\"test\""));
|
||||
response.addHeader(new BasicHeader(AUTH.WWW_AUTH, "That realm=\"realm1\", nonce=\"1234\""));
|
||||
|
||||
final TargetAuthenticationStrategy authStrategy = new TargetAuthenticationStrategy();
|
||||
final DefaultAuthenticationStrategy authStrategy = new DefaultAuthenticationStrategy();
|
||||
|
||||
Assert.assertFalse(this.httpAuthenticator.handleAuthChallenge(host,
|
||||
response, authStrategy, this.authState, this.context));
|
||||
Assert.assertFalse(this.httpAuthenticator.handleAuthChallenge(
|
||||
host, ChallengeType.TARGET, response, authStrategy, this.authState, this.context));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -246,10 +214,10 @@ public class TestHttpAuthenticator {
|
|||
|
||||
this.credentialsProvider.clear();
|
||||
|
||||
final TargetAuthenticationStrategy authStrategy = new TargetAuthenticationStrategy();
|
||||
final DefaultAuthenticationStrategy authStrategy = new DefaultAuthenticationStrategy();
|
||||
|
||||
Assert.assertFalse(this.httpAuthenticator.handleAuthChallenge(host,
|
||||
response, authStrategy, this.authState, this.context));
|
||||
Assert.assertFalse(this.httpAuthenticator.handleAuthChallenge(
|
||||
host, ChallengeType.TARGET, response, authStrategy, this.authState, this.context));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -262,10 +230,10 @@ public class TestHttpAuthenticator {
|
|||
this.authState.setState(AuthProtocolState.CHALLENGED);
|
||||
this.authState.update(this.authScheme, this.credentials);
|
||||
|
||||
final TargetAuthenticationStrategy authStrategy = new TargetAuthenticationStrategy();
|
||||
final DefaultAuthenticationStrategy authStrategy = new DefaultAuthenticationStrategy();
|
||||
|
||||
Assert.assertFalse(this.httpAuthenticator.handleAuthChallenge(host,
|
||||
response, authStrategy, this.authState, this.context));
|
||||
Assert.assertFalse(this.httpAuthenticator.handleAuthChallenge(
|
||||
host, ChallengeType.TARGET, response, authStrategy, this.authState, this.context));
|
||||
|
||||
Assert.assertEquals(AuthProtocolState.FAILURE, this.authState.getState());
|
||||
|
||||
|
@ -281,10 +249,10 @@ public class TestHttpAuthenticator {
|
|||
|
||||
this.authState.setState(AuthProtocolState.FAILURE);
|
||||
|
||||
final TargetAuthenticationStrategy authStrategy = new TargetAuthenticationStrategy();
|
||||
final DefaultAuthenticationStrategy authStrategy = new DefaultAuthenticationStrategy();
|
||||
|
||||
Assert.assertFalse(this.httpAuthenticator.handleAuthChallenge(host,
|
||||
response, authStrategy, this.authState, this.context));
|
||||
Assert.assertFalse(this.httpAuthenticator.handleAuthChallenge(
|
||||
host, ChallengeType.TARGET, response, authStrategy, this.authState, this.context));
|
||||
|
||||
Assert.assertEquals(AuthProtocolState.FAILURE, this.authState.getState());
|
||||
}
|
||||
|
@ -297,13 +265,13 @@ public class TestHttpAuthenticator {
|
|||
response.addHeader(new BasicHeader(AUTH.WWW_AUTH, "Digest realm=\"realm1\", nonce=\"1234\""));
|
||||
response.addHeader(new BasicHeader(AUTH.WWW_AUTH, "whatever realm=\"realm1\", stuff=\"1234\""));
|
||||
|
||||
final TargetAuthenticationStrategy authStrategy = new TargetAuthenticationStrategy();
|
||||
final DefaultAuthenticationStrategy authStrategy = new DefaultAuthenticationStrategy();
|
||||
|
||||
this.authState.setState(AuthProtocolState.CHALLENGED);
|
||||
this.authState.update(new BasicScheme(), this.credentials);
|
||||
|
||||
Assert.assertFalse(this.httpAuthenticator.handleAuthChallenge(host,
|
||||
response, authStrategy, this.authState, this.context));
|
||||
Assert.assertFalse(this.httpAuthenticator.handleAuthChallenge(
|
||||
host, ChallengeType.TARGET, response, authStrategy, this.authState, this.context));
|
||||
Assert.assertEquals(AuthProtocolState.FAILURE, this.authState.getState());
|
||||
Assert.assertNull(this.authState.getCredentials());
|
||||
}
|
||||
|
@ -316,13 +284,13 @@ public class TestHttpAuthenticator {
|
|||
response.addHeader(new BasicHeader(AUTH.WWW_AUTH, "Digest realm=\"realm1\", stale=true, nonce=\"1234\""));
|
||||
response.addHeader(new BasicHeader(AUTH.WWW_AUTH, "whatever realm=\"realm1\", stuff=\"1234\""));
|
||||
|
||||
final TargetAuthenticationStrategy authStrategy = new TargetAuthenticationStrategy();
|
||||
final DefaultAuthenticationStrategy authStrategy = new DefaultAuthenticationStrategy();
|
||||
|
||||
this.authState.setState(AuthProtocolState.CHALLENGED);
|
||||
this.authState.update(new DigestScheme(), this.credentials);
|
||||
|
||||
Assert.assertTrue(this.httpAuthenticator.handleAuthChallenge(host,
|
||||
response, authStrategy, this.authState, this.context));
|
||||
Assert.assertTrue(this.httpAuthenticator.handleAuthChallenge(
|
||||
host, ChallengeType.TARGET, response, authStrategy, this.authState, this.context));
|
||||
|
||||
Assert.assertEquals(AuthProtocolState.HANDSHAKE, this.authState.getState());
|
||||
}
|
||||
|
@ -334,13 +302,13 @@ public class TestHttpAuthenticator {
|
|||
response.addHeader(new BasicHeader(AUTH.WWW_AUTH, "Digest realm=\"realm1\", nonce=\"1234\""));
|
||||
response.addHeader(new BasicHeader(AUTH.WWW_AUTH, "whatever realm=\"realm1\", stuff=\"1234\""));
|
||||
|
||||
final TargetAuthenticationStrategy authStrategy = new TargetAuthenticationStrategy();
|
||||
final DefaultAuthenticationStrategy authStrategy = new DefaultAuthenticationStrategy();
|
||||
|
||||
this.authState.setState(AuthProtocolState.CHALLENGED);
|
||||
this.authState.update(new BasicScheme(), this.credentials);
|
||||
|
||||
Assert.assertTrue(this.httpAuthenticator.handleAuthChallenge(host,
|
||||
response, authStrategy, this.authState, this.context));
|
||||
Assert.assertTrue(this.httpAuthenticator.handleAuthChallenge(
|
||||
host, ChallengeType.TARGET, response, authStrategy, this.authState, this.context));
|
||||
Assert.assertEquals(AuthProtocolState.CHALLENGED, this.authState.getState());
|
||||
|
||||
final Queue<AuthOption> options = this.authState.getAuthOptions();
|
||||
|
@ -355,16 +323,14 @@ public class TestHttpAuthenticator {
|
|||
public void testAuthenticationException() throws Exception {
|
||||
final HttpHost host = new HttpHost("somehost", 80);
|
||||
final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_UNAUTHORIZED, "UNAUTHORIZED");
|
||||
response.addHeader(new BasicHeader(AUTH.WWW_AUTH, "blah blah blah"));
|
||||
|
||||
this.authState.setState(AuthProtocolState.CHALLENGED);
|
||||
|
||||
Mockito.doThrow(new MalformedChallengeException()).when(this.defltAuthStrategy).getChallenges(
|
||||
Mockito.any(HttpHost.class),
|
||||
Mockito.any(HttpResponse.class),
|
||||
Mockito.any(HttpContext.class));
|
||||
final DefaultAuthenticationStrategy authStrategy = new DefaultAuthenticationStrategy();
|
||||
|
||||
Assert.assertFalse(this.httpAuthenticator.handleAuthChallenge(host,
|
||||
response, this.defltAuthStrategy, this.authState, this.context));
|
||||
Assert.assertFalse(this.httpAuthenticator.handleAuthChallenge(
|
||||
host, ChallengeType.TARGET, response, authStrategy, this.authState, this.context));
|
||||
|
||||
Assert.assertEquals(AuthProtocolState.UNCHALLENGED, this.authState.getState());
|
||||
Assert.assertNull(this.authState.getAuthScheme());
|
||||
|
|
|
@ -0,0 +1,87 @@
|
|||
/*
|
||||
* ====================================================================
|
||||
* 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 org.apache.http.Header;
|
||||
import org.apache.http.HttpRequest;
|
||||
import org.apache.http.auth.AuthChallenge;
|
||||
import org.apache.http.auth.AuthenticationException;
|
||||
import org.apache.http.auth.ChallengeType;
|
||||
import org.apache.http.auth.Credentials;
|
||||
import org.apache.http.auth.MalformedChallengeException;
|
||||
import org.apache.http.protocol.HttpContext;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
public class TestNonStandardHttpScheme {
|
||||
|
||||
static class TestAuthScheme extends NonStandardAuthScheme {
|
||||
|
||||
@Override
|
||||
public void processChallenge(
|
||||
final ChallengeType challengeType, final AuthChallenge authChallenge) throws MalformedChallengeException {
|
||||
update(challengeType, authChallenge);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Header authenticate(
|
||||
final Credentials credentials,
|
||||
final HttpRequest request,
|
||||
final HttpContext context) throws AuthenticationException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSchemeName() {
|
||||
return "test";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isComplete() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isConnectionBased() {
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testProcessChallenge() throws Exception {
|
||||
final TestAuthScheme authscheme = new TestAuthScheme();
|
||||
authscheme.processChallenge(ChallengeType.TARGET, new AuthChallenge("Test", "this_and_that", null));
|
||||
|
||||
Assert.assertEquals("test", authscheme.getSchemeName());
|
||||
Assert.assertEquals("test(TARGET) this_and_that", authscheme.toString());
|
||||
Assert.assertEquals("this_and_that", authscheme.getChallenge());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,175 +0,0 @@
|
|||
/*
|
||||
* ====================================================================
|
||||
* 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.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.io.ObjectOutputStream;
|
||||
import java.nio.charset.Charset;
|
||||
|
||||
import org.apache.http.Consts;
|
||||
import org.apache.http.Header;
|
||||
import org.apache.http.HttpRequest;
|
||||
import org.apache.http.auth.AUTH;
|
||||
import org.apache.http.auth.AuthenticationException;
|
||||
import org.apache.http.auth.Credentials;
|
||||
import org.apache.http.auth.MalformedChallengeException;
|
||||
import org.apache.http.message.BasicHeader;
|
||||
import org.apache.http.message.BufferedHeader;
|
||||
import org.apache.http.protocol.HttpContext;
|
||||
import org.apache.http.util.CharArrayBuffer;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
public class TestRFC2617Scheme {
|
||||
|
||||
static class TestAuthScheme extends RFC2617Scheme {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public TestAuthScheme() {
|
||||
super();
|
||||
}
|
||||
|
||||
public TestAuthScheme(final Charset charset) {
|
||||
super(charset);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Header authenticate(
|
||||
final Credentials credentials,
|
||||
final HttpRequest request,
|
||||
final HttpContext context) throws AuthenticationException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSchemeName() {
|
||||
return "test";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isComplete() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isConnectionBased() {
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testProcessChallenge() throws Exception {
|
||||
final TestAuthScheme authscheme = new TestAuthScheme();
|
||||
final Header header = new BasicHeader(
|
||||
AUTH.WWW_AUTH,
|
||||
"Test realm=\"realm1\", test, test1 = stuff, test2 = \"stuff, stuff\", test3=\"crap");
|
||||
|
||||
authscheme.processChallenge(header);
|
||||
|
||||
Assert.assertEquals("test", authscheme.getSchemeName());
|
||||
Assert.assertEquals("TEST", authscheme.toString());
|
||||
Assert.assertEquals("realm1", authscheme.getParameter("realm"));
|
||||
Assert.assertEquals(null, authscheme.getParameter("test"));
|
||||
Assert.assertEquals("stuff", authscheme.getParameter("test1"));
|
||||
Assert.assertEquals("stuff, stuff", authscheme.getParameter("test2"));
|
||||
Assert.assertEquals("crap", authscheme.getParameter("test3"));
|
||||
Assert.assertEquals(null, authscheme.getParameter(null));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testProcessChallengeWithLotsOfBlanks() throws Exception {
|
||||
final TestAuthScheme authscheme = new TestAuthScheme();
|
||||
final CharArrayBuffer buffer = new CharArrayBuffer(32);
|
||||
buffer.append(" WWW-Authenticate: Test realm=\"realm1\"");
|
||||
final Header header = new BufferedHeader(buffer);
|
||||
|
||||
|
||||
authscheme.processChallenge(header);
|
||||
|
||||
Assert.assertEquals("test", authscheme.getSchemeName());
|
||||
Assert.assertEquals("realm1", authscheme.getParameter("realm"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNullHeader() throws Exception {
|
||||
final TestAuthScheme authscheme = new TestAuthScheme();
|
||||
try {
|
||||
authscheme.processChallenge(null);
|
||||
Assert.fail("IllegalArgumentException should have been thrown");
|
||||
} catch (final IllegalArgumentException ex) {
|
||||
}
|
||||
}
|
||||
|
||||
@Test(expected=MalformedChallengeException.class)
|
||||
public void testInvalidHeader() throws Exception {
|
||||
final TestAuthScheme authscheme = new TestAuthScheme();
|
||||
final Header header = new BasicHeader("whatever", "Test realm=\"realm1\"");
|
||||
authscheme.processChallenge(header);
|
||||
}
|
||||
|
||||
@Test(expected=MalformedChallengeException.class)
|
||||
public void testInvalidSchemeName() throws Exception {
|
||||
final TestAuthScheme authscheme = new TestAuthScheme();
|
||||
final Header header = new BasicHeader(AUTH.WWW_AUTH, "Not-a-Test realm=\"realm1\"");
|
||||
authscheme.processChallenge(header);
|
||||
}
|
||||
|
||||
@Test(expected=MalformedChallengeException.class)
|
||||
public void testInvalidHeaderValue() throws Exception {
|
||||
final TestAuthScheme authscheme = new TestAuthScheme();
|
||||
final Header header = new BasicHeader("whatever", "whatever");
|
||||
authscheme.processChallenge(header);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSerialization() throws Exception {
|
||||
final Header challenge = new BasicHeader(AUTH.WWW_AUTH, "test realm=\"test\", blah=blah, yada=\"yada yada\"");
|
||||
|
||||
final TestAuthScheme testScheme = new TestAuthScheme(Consts.ISO_8859_1);
|
||||
testScheme.processChallenge(challenge);
|
||||
|
||||
final ByteArrayOutputStream buffer = new ByteArrayOutputStream();
|
||||
final ObjectOutputStream out = new ObjectOutputStream(buffer);
|
||||
out.writeObject(testScheme);
|
||||
out.flush();
|
||||
final byte[] raw = buffer.toByteArray();
|
||||
final ObjectInputStream in = new ObjectInputStream(new ByteArrayInputStream(raw));
|
||||
final TestAuthScheme authScheme = (TestAuthScheme) in.readObject();
|
||||
|
||||
Assert.assertEquals(Consts.ISO_8859_1, authScheme.getCredentialsCharset());
|
||||
Assert.assertEquals("test", authScheme.getParameter("realm"));
|
||||
Assert.assertEquals("blah", authScheme.getParameter("blah"));
|
||||
Assert.assertEquals("yada yada", authScheme.getParameter("yada"));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,95 @@
|
|||
/*
|
||||
* ====================================================================
|
||||
* 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.util.Arrays;
|
||||
|
||||
import org.apache.http.Header;
|
||||
import org.apache.http.HttpRequest;
|
||||
import org.apache.http.auth.AuthChallenge;
|
||||
import org.apache.http.auth.AuthenticationException;
|
||||
import org.apache.http.auth.ChallengeType;
|
||||
import org.apache.http.auth.Credentials;
|
||||
import org.apache.http.auth.MalformedChallengeException;
|
||||
import org.apache.http.message.BasicNameValuePair;
|
||||
import org.apache.http.protocol.HttpContext;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
public class TestStandardHttpScheme {
|
||||
|
||||
static class TestAuthScheme extends StandardAuthScheme {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Override
|
||||
public void processChallenge(
|
||||
final ChallengeType challengeType, final AuthChallenge authChallenge) throws MalformedChallengeException {
|
||||
update(challengeType, authChallenge);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Header authenticate(
|
||||
final Credentials credentials,
|
||||
final HttpRequest request,
|
||||
final HttpContext context) throws AuthenticationException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSchemeName() {
|
||||
return "test";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isComplete() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isConnectionBased() {
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testProcessChallenge() throws Exception {
|
||||
final TestAuthScheme authscheme = new TestAuthScheme();
|
||||
authscheme.processChallenge(ChallengeType.TARGET, new AuthChallenge("Test", null, Arrays.asList(
|
||||
new BasicNameValuePair("realm", "realm1"), new BasicNameValuePair("this", "blah"))));
|
||||
|
||||
Assert.assertEquals("test", authscheme.getSchemeName());
|
||||
Assert.assertEquals("test(TARGET) {realm=realm1, this=blah}", authscheme.toString());
|
||||
Assert.assertEquals("realm1", authscheme.getParameter("realm"));
|
||||
Assert.assertEquals(null, authscheme.getParameter("test"));
|
||||
Assert.assertEquals("blah", authscheme.getParameter("this"));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -27,23 +27,19 @@
|
|||
package org.apache.http.impl.client;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Queue;
|
||||
|
||||
import org.apache.http.Header;
|
||||
import org.apache.http.HttpHost;
|
||||
import org.apache.http.HttpResponse;
|
||||
import org.apache.http.HttpStatus;
|
||||
import org.apache.http.HttpVersion;
|
||||
import org.apache.http.auth.AUTH;
|
||||
import org.apache.http.auth.AuthChallenge;
|
||||
import org.apache.http.auth.AuthOption;
|
||||
import org.apache.http.auth.AuthScheme;
|
||||
import org.apache.http.auth.AuthSchemeProvider;
|
||||
import org.apache.http.auth.AuthScope;
|
||||
import org.apache.http.auth.ChallengeType;
|
||||
import org.apache.http.auth.CredentialsProvider;
|
||||
import org.apache.http.auth.UsernamePasswordCredentials;
|
||||
import org.apache.http.client.AuthCache;
|
||||
import org.apache.http.client.config.AuthSchemes;
|
||||
import org.apache.http.client.config.RequestConfig;
|
||||
import org.apache.http.client.protocol.HttpClientContext;
|
||||
|
@ -53,98 +49,38 @@ import org.apache.http.impl.auth.BasicScheme;
|
|||
import org.apache.http.impl.auth.BasicSchemeFactory;
|
||||
import org.apache.http.impl.auth.DigestScheme;
|
||||
import org.apache.http.impl.auth.DigestSchemeFactory;
|
||||
import org.apache.http.message.BasicHeader;
|
||||
import org.apache.http.message.BasicHttpResponse;
|
||||
import org.apache.http.message.BasicNameValuePair;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import org.mockito.Mockito;
|
||||
|
||||
/**
|
||||
* Simple tests for {@link AuthenticationStrategyImpl}.
|
||||
* Simple tests for {@link DefaultAuthenticationStrategy}.
|
||||
*/
|
||||
@SuppressWarnings("boxing") // test code
|
||||
public class TestAuthenticationStrategy {
|
||||
|
||||
@Test(expected=IllegalArgumentException.class)
|
||||
public void testIsAuthenticationRequestedInvalidInput() throws Exception {
|
||||
final TargetAuthenticationStrategy authStrategy = new TargetAuthenticationStrategy();
|
||||
final HttpHost host = new HttpHost("localhost", 80);
|
||||
final HttpClientContext context = HttpClientContext.create();
|
||||
authStrategy.isAuthenticationRequested(host, null, context);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTargetAuthRequested() throws Exception {
|
||||
final TargetAuthenticationStrategy authStrategy = new TargetAuthenticationStrategy();
|
||||
final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_UNAUTHORIZED, "UNAUTHORIZED");
|
||||
final HttpHost host = new HttpHost("localhost", 80);
|
||||
final HttpClientContext context = HttpClientContext.create();
|
||||
Assert.assertTrue(authStrategy.isAuthenticationRequested(host, response, context));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testProxyAuthRequested() throws Exception {
|
||||
final ProxyAuthenticationStrategy authStrategy = new ProxyAuthenticationStrategy();
|
||||
final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_PROXY_AUTHENTICATION_REQUIRED, "UNAUTHORIZED");
|
||||
final HttpHost host = new HttpHost("localhost", 80);
|
||||
final HttpClientContext context = HttpClientContext.create();
|
||||
Assert.assertTrue(authStrategy.isAuthenticationRequested(host, response, context));
|
||||
}
|
||||
|
||||
@Test(expected=IllegalArgumentException.class)
|
||||
public void testGetChallengesInvalidInput() throws Exception {
|
||||
final TargetAuthenticationStrategy authStrategy = new TargetAuthenticationStrategy();
|
||||
final HttpHost host = new HttpHost("localhost", 80);
|
||||
final HttpClientContext context = HttpClientContext.create();
|
||||
authStrategy.getChallenges(host, null, context);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetChallenges() throws Exception {
|
||||
final TargetAuthenticationStrategy authStrategy = new TargetAuthenticationStrategy();
|
||||
final HttpClientContext context = HttpClientContext.create();
|
||||
final HttpHost host = new HttpHost("localhost", 80);
|
||||
final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_UNAUTHORIZED, "UNAUTHORIZED");
|
||||
final Header h1 = new BasicHeader(AUTH.WWW_AUTH, " Basic realm=\"test\"");
|
||||
final Header h2 = new BasicHeader(AUTH.WWW_AUTH, "\t\tDigest realm=\"realm1\", nonce=\"1234\"");
|
||||
final Header h3 = new BasicHeader(AUTH.WWW_AUTH, "WhatEver realm=\"realm1\", stuff=\"1234\"");
|
||||
response.addHeader(h1);
|
||||
response.addHeader(h2);
|
||||
response.addHeader(h3);
|
||||
|
||||
final Map<String, Header> challenges = authStrategy.getChallenges(host, response, context);
|
||||
|
||||
Assert.assertNotNull(challenges);
|
||||
Assert.assertEquals(3, challenges.size());
|
||||
Assert.assertSame(h1, challenges.get("basic"));
|
||||
Assert.assertSame(h2, challenges.get("digest"));
|
||||
Assert.assertSame(h3, challenges.get("whatever"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSelectInvalidInput() throws Exception {
|
||||
final TargetAuthenticationStrategy authStrategy = new TargetAuthenticationStrategy();
|
||||
final Map<String, Header> challenges = new HashMap<>();
|
||||
final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_UNAUTHORIZED, "UNAUTHORIZED");
|
||||
final DefaultAuthenticationStrategy authStrategy = new DefaultAuthenticationStrategy();
|
||||
final HttpHost authhost = new HttpHost("locahost", 80);
|
||||
final HttpClientContext context = HttpClientContext.create();
|
||||
try {
|
||||
authStrategy.select(null, authhost, response, context);
|
||||
authStrategy.select(null, authhost, Collections.<String, AuthChallenge>emptyMap(), context);
|
||||
Assert.fail("IllegalArgumentException expected");
|
||||
} catch (final IllegalArgumentException ex) {
|
||||
}
|
||||
try {
|
||||
authStrategy.select(challenges, null, response, context);
|
||||
authStrategy.select(ChallengeType.TARGET, null, Collections.<String, AuthChallenge>emptyMap(), context);
|
||||
Assert.fail("IllegalArgumentException expected");
|
||||
} catch (final IllegalArgumentException ex) {
|
||||
}
|
||||
try {
|
||||
authStrategy.select(challenges, authhost, null, context);
|
||||
authStrategy.select(ChallengeType.TARGET, authhost, null, context);
|
||||
Assert.fail("IllegalArgumentException expected");
|
||||
} catch (final IllegalArgumentException ex) {
|
||||
}
|
||||
try {
|
||||
authStrategy.select(challenges, authhost, response, null);
|
||||
authStrategy.select(ChallengeType.TARGET, authhost, Collections.<String, AuthChallenge>emptyMap(), null);
|
||||
Assert.fail("IllegalArgumentException expected");
|
||||
} catch (final IllegalArgumentException ex) {
|
||||
}
|
||||
|
@ -152,51 +88,54 @@ public class TestAuthenticationStrategy {
|
|||
|
||||
@Test
|
||||
public void testSelectNoSchemeRegistry() throws Exception {
|
||||
final TargetAuthenticationStrategy authStrategy = new TargetAuthenticationStrategy();
|
||||
final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_UNAUTHORIZED, "UNAUTHORIZED");
|
||||
final DefaultAuthenticationStrategy authStrategy = new DefaultAuthenticationStrategy();
|
||||
final HttpHost authhost = new HttpHost("locahost", 80);
|
||||
final HttpClientContext context = HttpClientContext.create();
|
||||
|
||||
final Map<String, Header> challenges = new HashMap<>();
|
||||
challenges.put("basic", new BasicHeader(AUTH.WWW_AUTH, "Basic realm=\"test\""));
|
||||
challenges.put("digest", new BasicHeader(AUTH.WWW_AUTH, "Digest realm=\"realm1\", nonce=\"1234\""));
|
||||
final Map<String, AuthChallenge> challenges = new HashMap<>();
|
||||
challenges.put("basic", new AuthChallenge("Basic",
|
||||
new BasicNameValuePair("realm", "test")));
|
||||
challenges.put("digest", new AuthChallenge("Digest",
|
||||
new BasicNameValuePair("realm", "test"), new BasicNameValuePair("nonce", "1234")));
|
||||
|
||||
final Queue<AuthOption> options = authStrategy.select(challenges, authhost, response, context);
|
||||
final Queue<AuthOption> options = authStrategy.select(ChallengeType.TARGET, authhost, challenges, context);
|
||||
Assert.assertNotNull(options);
|
||||
Assert.assertEquals(0, options.size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSelectNoCredentialsProvider() throws Exception {
|
||||
final TargetAuthenticationStrategy authStrategy = new TargetAuthenticationStrategy();
|
||||
final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_UNAUTHORIZED, "UNAUTHORIZED");
|
||||
final DefaultAuthenticationStrategy authStrategy = new DefaultAuthenticationStrategy();
|
||||
final HttpHost authhost = new HttpHost("locahost", 80);
|
||||
final HttpClientContext context = HttpClientContext.create();
|
||||
|
||||
final Map<String, Header> challenges = new HashMap<>();
|
||||
challenges.put("basic", new BasicHeader(AUTH.WWW_AUTH, "Basic realm=\"test\""));
|
||||
challenges.put("digest", new BasicHeader(AUTH.WWW_AUTH, "Digest realm=\"realm1\", nonce=\"1234\""));
|
||||
final Map<String, AuthChallenge> challenges = new HashMap<>();
|
||||
challenges.put("basic", new AuthChallenge("Basic",
|
||||
new BasicNameValuePair("realm", "test")));
|
||||
challenges.put("digest", new AuthChallenge("Digest",
|
||||
new BasicNameValuePair("realm", "test"), new BasicNameValuePair("nonce", "1234")));
|
||||
|
||||
final Registry<AuthSchemeProvider> authSchemeRegistry = RegistryBuilder.<AuthSchemeProvider>create()
|
||||
.register("basic", new BasicSchemeFactory())
|
||||
.register("digest", new DigestSchemeFactory()).build();
|
||||
context.setAuthSchemeRegistry(authSchemeRegistry);
|
||||
|
||||
final Queue<AuthOption> options = authStrategy.select(challenges, authhost, response, context);
|
||||
final Queue<AuthOption> options = authStrategy.select(ChallengeType.TARGET, authhost, challenges, context);
|
||||
Assert.assertNotNull(options);
|
||||
Assert.assertEquals(0, options.size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNoCredentials() throws Exception {
|
||||
final TargetAuthenticationStrategy authStrategy = new TargetAuthenticationStrategy();
|
||||
final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_UNAUTHORIZED, "UNAUTHORIZED");
|
||||
final DefaultAuthenticationStrategy authStrategy = new DefaultAuthenticationStrategy();
|
||||
final HttpHost authhost = new HttpHost("locahost", 80);
|
||||
final HttpClientContext context = HttpClientContext.create();
|
||||
|
||||
final Map<String, Header> challenges = new HashMap<>();
|
||||
challenges.put("basic", new BasicHeader(AUTH.WWW_AUTH, "Basic realm=\"realm1\""));
|
||||
challenges.put("digest", new BasicHeader(AUTH.WWW_AUTH, "Digest realm=\"realm2\", nonce=\"1234\""));
|
||||
final Map<String, AuthChallenge> challenges = new HashMap<>();
|
||||
challenges.put("basic", new AuthChallenge("Basic",
|
||||
new BasicNameValuePair("realm", "realm1")));
|
||||
challenges.put("digest", new AuthChallenge("Digest",
|
||||
new BasicNameValuePair("realm", "realm2"), new BasicNameValuePair("nonce", "1234")));
|
||||
|
||||
final Registry<AuthSchemeProvider> authSchemeRegistry = RegistryBuilder.<AuthSchemeProvider>create()
|
||||
.register("basic", new BasicSchemeFactory())
|
||||
|
@ -206,21 +145,22 @@ public class TestAuthenticationStrategy {
|
|||
final CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
|
||||
context.setCredentialsProvider(credentialsProvider);
|
||||
|
||||
final Queue<AuthOption> options = authStrategy.select(challenges, authhost, response, context);
|
||||
final Queue<AuthOption> options = authStrategy.select(ChallengeType.TARGET, authhost, challenges, context);
|
||||
Assert.assertNotNull(options);
|
||||
Assert.assertEquals(0, options.size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCredentialsFound() throws Exception {
|
||||
final TargetAuthenticationStrategy authStrategy = new TargetAuthenticationStrategy();
|
||||
final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_UNAUTHORIZED, "UNAUTHORIZED");
|
||||
final DefaultAuthenticationStrategy authStrategy = new DefaultAuthenticationStrategy();
|
||||
final HttpHost authhost = new HttpHost("somehost", 80);
|
||||
final HttpClientContext context = HttpClientContext.create();
|
||||
|
||||
final Map<String, Header> challenges = new HashMap<>();
|
||||
challenges.put("basic", new BasicHeader(AUTH.WWW_AUTH, "Basic realm=\"realm1\""));
|
||||
challenges.put("digest", new BasicHeader(AUTH.WWW_AUTH, "Digest realm=\"realm2\", nonce=\"1234\""));
|
||||
final Map<String, AuthChallenge> challenges = new HashMap<>();
|
||||
challenges.put("basic", new AuthChallenge("Basic",
|
||||
new BasicNameValuePair("realm", "realm1")));
|
||||
challenges.put("digest", new AuthChallenge("Digest",
|
||||
new BasicNameValuePair("realm", "realm2"), new BasicNameValuePair("nonce", "1234")));
|
||||
|
||||
final Registry<AuthSchemeProvider> authSchemeRegistry = RegistryBuilder.<AuthSchemeProvider>create()
|
||||
.register("basic", new BasicSchemeFactory())
|
||||
|
@ -232,7 +172,7 @@ public class TestAuthenticationStrategy {
|
|||
new UsernamePasswordCredentials("user", "pwd"));
|
||||
context.setCredentialsProvider(credentialsProvider);
|
||||
|
||||
final Queue<AuthOption> options = authStrategy.select(challenges, authhost, response, context);
|
||||
final Queue<AuthOption> options = authStrategy.select(ChallengeType.TARGET, authhost, challenges, context);
|
||||
Assert.assertNotNull(options);
|
||||
Assert.assertEquals(1, options.size());
|
||||
final AuthOption option = options.remove();
|
||||
|
@ -241,15 +181,17 @@ public class TestAuthenticationStrategy {
|
|||
|
||||
@Test
|
||||
public void testUnsupportedScheme() throws Exception {
|
||||
final TargetAuthenticationStrategy authStrategy = new TargetAuthenticationStrategy();
|
||||
final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_UNAUTHORIZED, "UNAUTHORIZED");
|
||||
final DefaultAuthenticationStrategy authStrategy = new DefaultAuthenticationStrategy();
|
||||
final HttpHost authhost = new HttpHost("somehost", 80);
|
||||
final HttpClientContext context = HttpClientContext.create();
|
||||
|
||||
final Map<String, Header> challenges = new HashMap<>();
|
||||
challenges.put("basic", new BasicHeader(AUTH.WWW_AUTH, "Basic realm=\"realm1\""));
|
||||
challenges.put("digest", new BasicHeader(AUTH.WWW_AUTH, "Digest realm=\"realm2\", nonce=\"1234\""));
|
||||
challenges.put("whatever", new BasicHeader(AUTH.WWW_AUTH, "Whatever realm=\"realm3\""));
|
||||
final Map<String, AuthChallenge> challenges = new HashMap<>();
|
||||
challenges.put("basic", new AuthChallenge("Basic",
|
||||
new BasicNameValuePair("realm", "realm1")));
|
||||
challenges.put("digest", new AuthChallenge("Digest",
|
||||
new BasicNameValuePair("realm", "realm2"), new BasicNameValuePair("nonce", "1234")));
|
||||
challenges.put("whatever", new AuthChallenge("Whatever",
|
||||
new BasicNameValuePair("realm", "realm3")));
|
||||
|
||||
final Registry<AuthSchemeProvider> authSchemeRegistry = RegistryBuilder.<AuthSchemeProvider>create()
|
||||
.register("basic", new BasicSchemeFactory())
|
||||
|
@ -261,7 +203,7 @@ public class TestAuthenticationStrategy {
|
|||
new UsernamePasswordCredentials("user", "pwd"));
|
||||
context.setCredentialsProvider(credentialsProvider);
|
||||
|
||||
final Queue<AuthOption> options = authStrategy.select(challenges, authhost, response, context);
|
||||
final Queue<AuthOption> options = authStrategy.select(ChallengeType.TARGET, authhost, challenges, context);
|
||||
Assert.assertNotNull(options);
|
||||
Assert.assertEquals(2, options.size());
|
||||
final AuthOption option1 = options.remove();
|
||||
|
@ -272,8 +214,7 @@ public class TestAuthenticationStrategy {
|
|||
|
||||
@Test
|
||||
public void testCustomAuthPreference() throws Exception {
|
||||
final TargetAuthenticationStrategy authStrategy = new TargetAuthenticationStrategy();
|
||||
final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_UNAUTHORIZED, "UNAUTHORIZED");
|
||||
final DefaultAuthenticationStrategy authStrategy = new DefaultAuthenticationStrategy();
|
||||
final RequestConfig config = RequestConfig.custom()
|
||||
.setTargetPreferredAuthSchemes(Arrays.asList(AuthSchemes.BASIC))
|
||||
.build();
|
||||
|
@ -281,9 +222,11 @@ public class TestAuthenticationStrategy {
|
|||
final HttpHost authhost = new HttpHost("somehost", 80);
|
||||
final HttpClientContext context = HttpClientContext.create();
|
||||
|
||||
final Map<String, Header> challenges = new HashMap<>();
|
||||
challenges.put("basic", new BasicHeader(AUTH.WWW_AUTH, "Basic realm=\"realm1\""));
|
||||
challenges.put("digest", new BasicHeader(AUTH.WWW_AUTH, "Digest realm=\"realm2\", nonce=\"1234\""));
|
||||
final Map<String, AuthChallenge> challenges = new HashMap<>();
|
||||
challenges.put("basic", new AuthChallenge("Basic",
|
||||
new BasicNameValuePair("realm", "realm1")));
|
||||
challenges.put("digest", new AuthChallenge("Digest",
|
||||
new BasicNameValuePair("realm", "realm2"), new BasicNameValuePair("nonce", "1234")));
|
||||
|
||||
final Registry<AuthSchemeProvider> authSchemeRegistry = RegistryBuilder.<AuthSchemeProvider>create()
|
||||
.register("basic", new BasicSchemeFactory())
|
||||
|
@ -296,143 +239,11 @@ public class TestAuthenticationStrategy {
|
|||
new UsernamePasswordCredentials("user", "pwd"));
|
||||
context.setCredentialsProvider(credentialsProvider);
|
||||
|
||||
final Queue<AuthOption> options = authStrategy.select(challenges, authhost, response, context);
|
||||
final Queue<AuthOption> options = authStrategy.select(ChallengeType.TARGET, authhost, challenges, context);
|
||||
Assert.assertNotNull(options);
|
||||
Assert.assertEquals(1, options.size());
|
||||
final AuthOption option1 = options.remove();
|
||||
Assert.assertTrue(option1.getAuthScheme() instanceof BasicScheme);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAuthSucceededInvalidInput() throws Exception {
|
||||
final TargetAuthenticationStrategy authStrategy = new TargetAuthenticationStrategy();
|
||||
final HttpHost authhost = new HttpHost("locahost", 80);
|
||||
final BasicScheme authScheme = new BasicScheme();
|
||||
final HttpClientContext context = HttpClientContext.create();
|
||||
try {
|
||||
authStrategy.authSucceeded(null, authScheme, context);
|
||||
Assert.fail("IllegalArgumentException expected");
|
||||
} catch (final IllegalArgumentException ex) {
|
||||
}
|
||||
try {
|
||||
authStrategy.authSucceeded(authhost, null, context);
|
||||
Assert.fail("IllegalArgumentException expected");
|
||||
} catch (final IllegalArgumentException ex) {
|
||||
}
|
||||
try {
|
||||
authStrategy.authSucceeded(authhost, authScheme, null);
|
||||
Assert.fail("IllegalArgumentException expected");
|
||||
} catch (final IllegalArgumentException ex) {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAuthSucceeded() throws Exception {
|
||||
final TargetAuthenticationStrategy authStrategy = new TargetAuthenticationStrategy();
|
||||
final HttpHost authhost = new HttpHost("somehost", 80);
|
||||
final BasicScheme authScheme = new BasicScheme();
|
||||
authScheme.processChallenge(new BasicHeader(AUTH.WWW_AUTH, "Basic realm=test"));
|
||||
|
||||
final AuthCache authCache = Mockito.mock(AuthCache.class);
|
||||
|
||||
final HttpClientContext context = HttpClientContext.create();
|
||||
context.setAuthCache(authCache);
|
||||
|
||||
authStrategy.authSucceeded(authhost, authScheme, context);
|
||||
Mockito.verify(authCache).put(authhost, authScheme);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAuthSucceededNoCache() throws Exception {
|
||||
final TargetAuthenticationStrategy authStrategy = new TargetAuthenticationStrategy();
|
||||
final HttpHost authhost = new HttpHost("somehost", 80);
|
||||
final BasicScheme authScheme = new BasicScheme();
|
||||
authScheme.processChallenge(new BasicHeader(AUTH.WWW_AUTH, "Basic realm=test"));
|
||||
|
||||
final HttpClientContext context = HttpClientContext.create();
|
||||
context.setAuthCache(null);
|
||||
|
||||
authStrategy.authSucceeded(authhost, authScheme, context);
|
||||
final AuthCache authCache = context.getAuthCache();
|
||||
Assert.assertNotNull(authCache);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAuthScemeNotCompleted() throws Exception {
|
||||
final TargetAuthenticationStrategy authStrategy = new TargetAuthenticationStrategy();
|
||||
final HttpHost authhost = new HttpHost("somehost", 80);
|
||||
final BasicScheme authScheme = new BasicScheme();
|
||||
|
||||
final AuthCache authCache = Mockito.mock(AuthCache.class);
|
||||
|
||||
final HttpClientContext context = HttpClientContext.create();
|
||||
context.setAuthCache(authCache);
|
||||
|
||||
authStrategy.authSucceeded(authhost, authScheme, context);
|
||||
Mockito.verify(authCache, Mockito.never()).put(authhost, authScheme);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAuthScemeNonCacheable() throws Exception {
|
||||
final TargetAuthenticationStrategy authStrategy = new TargetAuthenticationStrategy();
|
||||
final HttpHost authhost = new HttpHost("somehost", 80);
|
||||
final AuthScheme authScheme = Mockito.mock(AuthScheme.class);
|
||||
Mockito.when(authScheme.isComplete()).thenReturn(true);
|
||||
Mockito.when(authScheme.getSchemeName()).thenReturn("whatever");
|
||||
|
||||
final AuthCache authCache = Mockito.mock(AuthCache.class);
|
||||
|
||||
final HttpClientContext context = HttpClientContext.create();
|
||||
context.setAuthCache(authCache);
|
||||
|
||||
authStrategy.authSucceeded(authhost, authScheme, context);
|
||||
Mockito.verify(authCache, Mockito.never()).put(authhost, authScheme);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAuthFailedInvalidInput() throws Exception {
|
||||
final TargetAuthenticationStrategy authStrategy = new TargetAuthenticationStrategy();
|
||||
final HttpHost authhost = new HttpHost("locahost", 80);
|
||||
final BasicScheme authScheme = new BasicScheme();
|
||||
final HttpClientContext context = HttpClientContext.create();
|
||||
try {
|
||||
authStrategy.authFailed(null, authScheme, context);
|
||||
Assert.fail("IllegalArgumentException expected");
|
||||
} catch (final IllegalArgumentException ex) {
|
||||
}
|
||||
try {
|
||||
authStrategy.authFailed(authhost, authScheme, null);
|
||||
Assert.fail("IllegalArgumentException expected");
|
||||
} catch (final IllegalArgumentException ex) {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAuthFailed() throws Exception {
|
||||
final TargetAuthenticationStrategy authStrategy = new TargetAuthenticationStrategy();
|
||||
final HttpHost authhost = new HttpHost("somehost", 80);
|
||||
final BasicScheme authScheme = new BasicScheme();
|
||||
authScheme.processChallenge(new BasicHeader(AUTH.WWW_AUTH, "Basic realm=test"));
|
||||
|
||||
final AuthCache authCache = Mockito.mock(AuthCache.class);
|
||||
|
||||
final HttpClientContext context = HttpClientContext.create();
|
||||
context.setAuthCache(authCache);
|
||||
|
||||
authStrategy.authFailed(authhost, authScheme, context);
|
||||
Mockito.verify(authCache).remove(authhost);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAuthFailedNoCache() throws Exception {
|
||||
final TargetAuthenticationStrategy authStrategy = new TargetAuthenticationStrategy();
|
||||
final HttpHost authhost = new HttpHost("somehost", 80);
|
||||
final BasicScheme authScheme = new BasicScheme();
|
||||
|
||||
final HttpClientContext context = HttpClientContext.create();
|
||||
context.setAuthCache(null);
|
||||
|
||||
authStrategy.authFailed(authhost, authScheme, context);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -28,6 +28,8 @@ package org.apache.http.impl.client.integration;
|
|||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.Map;
|
||||
import java.util.Queue;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
|
||||
import org.apache.http.Consts;
|
||||
|
@ -39,9 +41,13 @@ import org.apache.http.HttpRequest;
|
|||
import org.apache.http.HttpResponse;
|
||||
import org.apache.http.HttpStatus;
|
||||
import org.apache.http.auth.AUTH;
|
||||
import org.apache.http.auth.AuthChallenge;
|
||||
import org.apache.http.auth.AuthOption;
|
||||
import org.apache.http.auth.AuthScope;
|
||||
import org.apache.http.auth.ChallengeType;
|
||||
import org.apache.http.auth.Credentials;
|
||||
import org.apache.http.auth.CredentialsProvider;
|
||||
import org.apache.http.auth.MalformedChallengeException;
|
||||
import org.apache.http.auth.UsernamePasswordCredentials;
|
||||
import org.apache.http.client.AuthCache;
|
||||
import org.apache.http.client.ClientProtocolException;
|
||||
|
@ -56,7 +62,7 @@ import org.apache.http.entity.StringEntity;
|
|||
import org.apache.http.impl.auth.BasicScheme;
|
||||
import org.apache.http.impl.client.BasicAuthCache;
|
||||
import org.apache.http.impl.client.BasicCredentialsProvider;
|
||||
import org.apache.http.impl.client.TargetAuthenticationStrategy;
|
||||
import org.apache.http.impl.client.DefaultAuthenticationStrategy;
|
||||
import org.apache.http.localserver.BasicAuthTokenExtractor;
|
||||
import org.apache.http.localserver.LocalServerTestBase;
|
||||
import org.apache.http.localserver.RequestBasicAuth;
|
||||
|
@ -342,7 +348,7 @@ public class TestClientAuthentication extends LocalServerTestBase {
|
|||
}
|
||||
}
|
||||
|
||||
static class TestTargetAuthenticationStrategy extends TargetAuthenticationStrategy {
|
||||
static class TestTargetAuthenticationStrategy extends DefaultAuthenticationStrategy {
|
||||
|
||||
private final AtomicLong count;
|
||||
|
||||
|
@ -352,15 +358,14 @@ public class TestClientAuthentication extends LocalServerTestBase {
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean isAuthenticationRequested(
|
||||
public Queue<AuthOption> select(
|
||||
final ChallengeType challengeType,
|
||||
final HttpHost host,
|
||||
final HttpResponse response,
|
||||
final HttpContext context) {
|
||||
final boolean res = super.isAuthenticationRequested(host, response, context);
|
||||
if (res == true) {
|
||||
this.count.incrementAndGet();
|
||||
}
|
||||
return res;
|
||||
final Map<String, AuthChallenge> challenges,
|
||||
final HttpContext context) throws MalformedChallengeException {
|
||||
final Queue<AuthOption> authOptions = super.select(challengeType, host, challenges, context);
|
||||
this.count.incrementAndGet();
|
||||
return authOptions;
|
||||
}
|
||||
|
||||
public long getCount() {
|
||||
|
|
|
@ -46,6 +46,7 @@ import org.apache.http.auth.Credentials;
|
|||
import org.apache.http.auth.CredentialsProvider;
|
||||
import org.apache.http.auth.UsernamePasswordCredentials;
|
||||
import org.apache.http.client.config.RequestConfig;
|
||||
import org.apache.http.client.methods.CloseableHttpResponse;
|
||||
import org.apache.http.client.methods.HttpGet;
|
||||
import org.apache.http.client.protocol.HttpClientContext;
|
||||
import org.apache.http.config.Registry;
|
||||
|
@ -53,7 +54,6 @@ import org.apache.http.config.RegistryBuilder;
|
|||
import org.apache.http.entity.StringEntity;
|
||||
import org.apache.http.impl.auth.BasicScheme;
|
||||
import org.apache.http.impl.auth.BasicSchemeFactory;
|
||||
import org.apache.http.impl.client.TargetAuthenticationStrategy;
|
||||
import org.apache.http.localserver.LocalServerTestBase;
|
||||
import org.apache.http.localserver.RequestBasicAuth;
|
||||
import org.apache.http.protocol.HttpContext;
|
||||
|
@ -162,15 +162,6 @@ public class TestClientReauthentication extends LocalServerTestBase {
|
|||
|
||||
};
|
||||
|
||||
final TargetAuthenticationStrategy myAuthStrategy = new TargetAuthenticationStrategy() {
|
||||
|
||||
@Override
|
||||
protected boolean isCachable(final AuthScheme authScheme) {
|
||||
return "MyBasic".equalsIgnoreCase(authScheme.getSchemeName());
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
final TestCredentialsProvider credsProvider = new TestCredentialsProvider(
|
||||
new UsernamePasswordCredentials("test", "test"));
|
||||
|
||||
|
@ -182,7 +173,6 @@ public class TestClientReauthentication extends LocalServerTestBase {
|
|||
.build();
|
||||
this.httpclient = this.clientBuilder
|
||||
.setDefaultAuthSchemeRegistry(authSchemeRegistry)
|
||||
.setTargetAuthenticationStrategy(myAuthStrategy)
|
||||
.setDefaultCredentialsProvider(credsProvider)
|
||||
.build();
|
||||
|
||||
|
@ -192,11 +182,12 @@ public class TestClientReauthentication extends LocalServerTestBase {
|
|||
for (int i = 0; i < 10; i++) {
|
||||
final HttpGet httpget = new HttpGet("/");
|
||||
httpget.setConfig(config);
|
||||
final HttpResponse response = this.httpclient.execute(target, httpget, context);
|
||||
final HttpEntity entity = response.getEntity();
|
||||
Assert.assertEquals(HttpStatus.SC_OK, response.getStatusLine().getStatusCode());
|
||||
Assert.assertNotNull(entity);
|
||||
EntityUtils.consume(entity);
|
||||
try (final CloseableHttpResponse response = this.httpclient.execute(target, httpget, context)) {
|
||||
final HttpEntity entity = response.getEntity();
|
||||
Assert.assertEquals(HttpStatus.SC_OK, response.getStatusLine().getStatusCode());
|
||||
Assert.assertNotNull(entity);
|
||||
EntityUtils.consume(entity);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -32,25 +32,26 @@ import java.io.IOException;
|
|||
import java.io.InputStream;
|
||||
import java.io.InterruptedIOException;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedList;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.apache.http.ConnectionReuseStrategy;
|
||||
import org.apache.http.Header;
|
||||
import org.apache.http.HttpClientConnection;
|
||||
import org.apache.http.HttpEntityEnclosingRequest;
|
||||
import org.apache.http.HttpException;
|
||||
import org.apache.http.HttpHeaders;
|
||||
import org.apache.http.HttpHost;
|
||||
import org.apache.http.HttpRequest;
|
||||
import org.apache.http.HttpResponse;
|
||||
import org.apache.http.HttpVersion;
|
||||
import org.apache.http.auth.AUTH;
|
||||
import org.apache.http.auth.AuthChallenge;
|
||||
import org.apache.http.auth.AuthOption;
|
||||
import org.apache.http.auth.AuthProtocolState;
|
||||
import org.apache.http.auth.AuthState;
|
||||
import org.apache.http.auth.ChallengeType;
|
||||
import org.apache.http.auth.NTCredentials;
|
||||
import org.apache.http.auth.UsernamePasswordCredentials;
|
||||
import org.apache.http.client.AuthenticationStrategy;
|
||||
|
@ -74,7 +75,6 @@ import org.apache.http.entity.StringEntity;
|
|||
import org.apache.http.impl.auth.BasicScheme;
|
||||
import org.apache.http.impl.auth.NTLMScheme;
|
||||
import org.apache.http.impl.conn.ConnectionShutdownException;
|
||||
import org.apache.http.message.BasicHeader;
|
||||
import org.apache.http.message.BasicHttpResponse;
|
||||
import org.apache.http.protocol.HttpContext;
|
||||
import org.apache.http.protocol.HttpProcessor;
|
||||
|
@ -132,39 +132,6 @@ public class TestMainClientExec {
|
|||
Mockito.<HttpRoute>any(), Mockito.any())).thenReturn(connRequest);
|
||||
Mockito.when(connRequest.get(
|
||||
Mockito.anyLong(), Mockito.<TimeUnit>any())).thenReturn(managedConn);
|
||||
final Map<String, Header> challenges = new HashMap<>();
|
||||
challenges.put("basic", new BasicHeader(AUTH.WWW_AUTH, "Basic realm=test"));
|
||||
final AuthOption authOption = new AuthOption(
|
||||
new BasicScheme(), new UsernamePasswordCredentials("user:pass"));
|
||||
Mockito.when(targetAuthStrategy.getChallenges(
|
||||
Mockito.eq(target),
|
||||
Mockito.<HttpResponse>any(),
|
||||
Mockito.<HttpClientContext>any())).thenReturn(challenges);
|
||||
Mockito.when(targetAuthStrategy.getChallenges(
|
||||
Mockito.eq(target),
|
||||
Mockito.<HttpResponse>any(),
|
||||
Mockito.<HttpClientContext>any())).thenReturn(challenges);
|
||||
Mockito.when(targetAuthStrategy.select(
|
||||
Mockito.same(challenges),
|
||||
Mockito.eq(target),
|
||||
Mockito.<HttpResponse>any(),
|
||||
Mockito.<HttpClientContext>any())).thenReturn(
|
||||
new LinkedList<>(Arrays.asList(authOption)));
|
||||
Mockito.when(proxyAuthStrategy.getChallenges(
|
||||
Mockito.eq(proxy),
|
||||
Mockito.<HttpResponse>any(),
|
||||
Mockito.<HttpClientContext>any())).thenReturn(challenges);
|
||||
Mockito.when(proxyAuthStrategy.getChallenges(
|
||||
Mockito.eq(proxy),
|
||||
Mockito.<HttpResponse>any(),
|
||||
Mockito.<HttpClientContext>any())).thenReturn(challenges);
|
||||
Mockito.when(proxyAuthStrategy.select(
|
||||
Mockito.same(challenges),
|
||||
Mockito.eq(proxy),
|
||||
Mockito.<HttpResponse>any(),
|
||||
Mockito.<HttpClientContext>any())).thenReturn(
|
||||
new LinkedList<>(Arrays.asList(authOption)));
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -418,6 +385,7 @@ public class TestMainClientExec {
|
|||
final HttpClientContext context = new HttpClientContext();
|
||||
final HttpRequestWrapper request = HttpRequestWrapper.wrap(new HttpGet("http://bar/test"));
|
||||
final HttpResponse response1 = new BasicHttpResponse(HttpVersion.HTTP_1_1, 401, "Huh?");
|
||||
response1.setHeader(HttpHeaders.WWW_AUTHENTICATE, "Basic realm=test");
|
||||
final InputStream instream1 = Mockito.spy(new ByteArrayInputStream(new byte[] {1, 2, 3}));
|
||||
response1.setEntity(EntityBuilder.create()
|
||||
.setStream(instream1)
|
||||
|
@ -437,10 +405,14 @@ public class TestMainClientExec {
|
|||
Mockito.when(reuseStrategy.keepAlive(
|
||||
Mockito.<HttpResponse>any(),
|
||||
Mockito.<HttpClientContext>any())).thenReturn(Boolean.TRUE);
|
||||
Mockito.when(targetAuthStrategy.isAuthenticationRequested(
|
||||
Mockito.when(targetAuthStrategy.select(
|
||||
Mockito.eq(ChallengeType.TARGET),
|
||||
Mockito.eq(target),
|
||||
Mockito.same(response1),
|
||||
Mockito.<HttpClientContext>any())).thenReturn(Boolean.TRUE);
|
||||
Mockito.<Map<String, AuthChallenge>>any(),
|
||||
Mockito.<HttpClientContext>any())).thenReturn(new LinkedList<>(
|
||||
Collections.singleton(new AuthOption(
|
||||
new BasicScheme(),
|
||||
new UsernamePasswordCredentials("user", "pass")))));
|
||||
|
||||
final CloseableHttpResponse finalResponse = mainClientExec.execute(
|
||||
route, request, context, execAware);
|
||||
|
@ -457,6 +429,7 @@ public class TestMainClientExec {
|
|||
final HttpRoute route = new HttpRoute(target);
|
||||
final HttpRequestWrapper request = HttpRequestWrapper.wrap(new HttpGet("http://bar/test"));
|
||||
final HttpResponse response1 = new BasicHttpResponse(HttpVersion.HTTP_1_1, 401, "Huh?");
|
||||
response1.setHeader(HttpHeaders.WWW_AUTHENTICATE, "Basic realm=test");
|
||||
final InputStream instream1 = Mockito.spy(new ByteArrayInputStream(new byte[] {1, 2, 3}));
|
||||
response1.setEntity(EntityBuilder.create()
|
||||
.setStream(instream1)
|
||||
|
@ -483,10 +456,15 @@ public class TestMainClientExec {
|
|||
Mockito.when(reuseStrategy.keepAlive(
|
||||
Mockito.<HttpResponse>any(),
|
||||
Mockito.<HttpClientContext>any())).thenReturn(Boolean.FALSE);
|
||||
Mockito.when(targetAuthStrategy.isAuthenticationRequested(
|
||||
|
||||
final AuthOption authOption = new AuthOption(
|
||||
new BasicScheme(), new UsernamePasswordCredentials("user:pass"));
|
||||
Mockito.when(targetAuthStrategy.select(
|
||||
Mockito.eq(ChallengeType.TARGET),
|
||||
Mockito.eq(target),
|
||||
Mockito.same(response1),
|
||||
Mockito.<HttpClientContext>any())).thenReturn(Boolean.TRUE);
|
||||
Mockito.<Map<String, AuthChallenge>>any(),
|
||||
Mockito.<HttpClientContext>any())).thenReturn(
|
||||
new LinkedList<>(Arrays.asList(authOption)));
|
||||
|
||||
final CloseableHttpResponse finalResponse = mainClientExec.execute(
|
||||
route, request, context, execAware);
|
||||
|
@ -512,6 +490,7 @@ public class TestMainClientExec {
|
|||
final HttpRequestWrapper request = HttpRequestWrapper.wrap(post);
|
||||
|
||||
final HttpResponse response1 = new BasicHttpResponse(HttpVersion.HTTP_1_1, 401, "Huh?");
|
||||
response1.setHeader(HttpHeaders.WWW_AUTHENTICATE, "Basic realm=test");
|
||||
final InputStream instream1 = new ByteArrayInputStream(new byte[] {1, 2, 3});
|
||||
response1.setEntity(EntityBuilder.create()
|
||||
.setStream(instream1)
|
||||
|
@ -536,10 +515,15 @@ public class TestMainClientExec {
|
|||
Mockito.when(reuseStrategy.keepAlive(
|
||||
Mockito.<HttpResponse>any(),
|
||||
Mockito.<HttpClientContext>any())).thenReturn(Boolean.TRUE);
|
||||
Mockito.when(targetAuthStrategy.isAuthenticationRequested(
|
||||
|
||||
final AuthOption authOption = new AuthOption(
|
||||
new BasicScheme(), new UsernamePasswordCredentials("user:pass"));
|
||||
Mockito.when(targetAuthStrategy.select(
|
||||
Mockito.eq(ChallengeType.TARGET),
|
||||
Mockito.eq(target),
|
||||
Mockito.same(response1),
|
||||
Mockito.<HttpClientContext>any())).thenReturn(Boolean.TRUE);
|
||||
Mockito.<Map<String, AuthChallenge>>any(),
|
||||
Mockito.<HttpClientContext>any())).thenReturn(
|
||||
new LinkedList<>(Arrays.asList(authOption)));
|
||||
|
||||
mainClientExec.execute(route, request, context, execAware);
|
||||
}
|
||||
|
@ -732,7 +716,8 @@ public class TestMainClientExec {
|
|||
final HttpRoute route = new HttpRoute(target, null, proxy, true);
|
||||
final HttpClientContext context = new HttpClientContext();
|
||||
final HttpRequestWrapper request = HttpRequestWrapper.wrap(new HttpGet("http://bar/test"));
|
||||
final HttpResponse response1 = new BasicHttpResponse(HttpVersion.HTTP_1_1, 401, "Huh?");
|
||||
final HttpResponse response1 = new BasicHttpResponse(HttpVersion.HTTP_1_1, 407, "Huh?");
|
||||
response1.setHeader(HttpHeaders.PROXY_AUTHENTICATE, "Basic realm=test");
|
||||
final InputStream instream1 = Mockito.spy(new ByteArrayInputStream(new byte[] {1, 2, 3}));
|
||||
response1.setEntity(EntityBuilder.create()
|
||||
.setStream(instream1)
|
||||
|
@ -740,10 +725,6 @@ public class TestMainClientExec {
|
|||
final HttpResponse response2 = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK");
|
||||
|
||||
Mockito.when(managedConn.isOpen()).thenReturn(Boolean.TRUE);
|
||||
Mockito.when(proxyAuthStrategy.isAuthenticationRequested(
|
||||
Mockito.eq(proxy),
|
||||
Mockito.same(response1),
|
||||
Mockito.<HttpClientContext>any())).thenReturn(Boolean.TRUE);
|
||||
Mockito.when(reuseStrategy.keepAlive(
|
||||
Mockito.<HttpResponse>any(),
|
||||
Mockito.<HttpClientContext>any())).thenReturn(Boolean.TRUE);
|
||||
|
@ -752,6 +733,15 @@ public class TestMainClientExec {
|
|||
Mockito.<HttpClientConnection>any(),
|
||||
Mockito.<HttpClientContext>any())).thenReturn(response1, response2);
|
||||
|
||||
final AuthOption authOption = new AuthOption(
|
||||
new BasicScheme(), new UsernamePasswordCredentials("user:pass"));
|
||||
Mockito.when(proxyAuthStrategy.select(
|
||||
Mockito.eq(ChallengeType.PROXY),
|
||||
Mockito.eq(proxy),
|
||||
Mockito.<Map<String, AuthChallenge>>any(),
|
||||
Mockito.<HttpClientContext>any())).thenReturn(
|
||||
new LinkedList<>(Arrays.asList(authOption)));
|
||||
|
||||
mainClientExec.establishRoute(authState, managedConn, route, request, context);
|
||||
|
||||
Mockito.verify(connManager).connect(managedConn, route, 0, context);
|
||||
|
@ -765,7 +755,8 @@ public class TestMainClientExec {
|
|||
final HttpRoute route = new HttpRoute(target, null, proxy, true);
|
||||
final HttpClientContext context = new HttpClientContext();
|
||||
final HttpRequestWrapper request = HttpRequestWrapper.wrap(new HttpGet("http://bar/test"));
|
||||
final HttpResponse response1 = new BasicHttpResponse(HttpVersion.HTTP_1_1, 401, "Huh?");
|
||||
final HttpResponse response1 = new BasicHttpResponse(HttpVersion.HTTP_1_1, 407, "Huh?");
|
||||
response1.setHeader(HttpHeaders.PROXY_AUTHENTICATE, "Basic realm=test");
|
||||
final InputStream instream1 = Mockito.spy(new ByteArrayInputStream(new byte[] {1, 2, 3}));
|
||||
response1.setEntity(EntityBuilder.create()
|
||||
.setStream(instream1)
|
||||
|
@ -773,10 +764,6 @@ public class TestMainClientExec {
|
|||
final HttpResponse response2 = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK");
|
||||
|
||||
Mockito.when(managedConn.isOpen()).thenReturn(Boolean.TRUE);
|
||||
Mockito.when(proxyAuthStrategy.isAuthenticationRequested(
|
||||
Mockito.eq(proxy),
|
||||
Mockito.same(response1),
|
||||
Mockito.<HttpClientContext>any())).thenReturn(Boolean.TRUE);
|
||||
Mockito.when(reuseStrategy.keepAlive(
|
||||
Mockito.<HttpResponse>any(),
|
||||
Mockito.<HttpClientContext>any())).thenReturn(Boolean.FALSE);
|
||||
|
@ -785,6 +772,15 @@ public class TestMainClientExec {
|
|||
Mockito.<HttpClientConnection>any(),
|
||||
Mockito.<HttpClientContext>any())).thenReturn(response1, response2);
|
||||
|
||||
final AuthOption authOption = new AuthOption(
|
||||
new BasicScheme(), new UsernamePasswordCredentials("user:pass"));
|
||||
Mockito.when(proxyAuthStrategy.select(
|
||||
Mockito.eq(ChallengeType.PROXY),
|
||||
Mockito.eq(proxy),
|
||||
Mockito.<Map<String, AuthChallenge>>any(),
|
||||
Mockito.<HttpClientContext>any())).thenReturn(
|
||||
new LinkedList<>(Arrays.asList(authOption)));
|
||||
|
||||
mainClientExec.establishRoute(authState, managedConn, route, request, context);
|
||||
|
||||
Mockito.verify(connManager).connect(managedConn, route, 0, context);
|
||||
|
|
Loading…
Reference in New Issue