diff --git a/src/main/java/org/littleshoot/proxy/BasicProxyAuthenticator.java b/src/main/java/org/littleshoot/proxy/BasicProxyAuthenticator.java new file mode 100644 index 000000000..6d69c4598 --- /dev/null +++ b/src/main/java/org/littleshoot/proxy/BasicProxyAuthenticator.java @@ -0,0 +1,42 @@ +package org.littleshoot.proxy; + +import com.google.common.io.BaseEncoding; + +import org.apache.commons.lang3.StringUtils; + +import java.nio.charset.Charset; + +/** + * + */ +public abstract class BasicProxyAuthenticator implements ProxyAuthenticator { + + @Override + public boolean authenticate(String proxyAuthorizationHeaderValue) { + String value = StringUtils.substringAfter(proxyAuthorizationHeaderValue, "Basic ").trim(); + + byte[] decodedValue = BaseEncoding.base64().decode(value); + + String decodedString = new String(decodedValue, Charset.forName("UTF-8")); + + String userName = StringUtils.substringBefore(decodedString, ":"); + String password = StringUtils.substringAfter(decodedString, ":"); + + return authenticate(userName, password); + } + + /** + * Authenticates the user using the specified userName and password. + * + * @param username + * The user name. + * @param password + * The password. + * @return true if the credentials are acceptable, otherwise + * false. + * requests. + */ + abstract boolean authenticate(String username, String password); + + abstract public String getRealm(); +} diff --git a/src/main/java/org/littleshoot/proxy/ProxyAuthenticator.java b/src/main/java/org/littleshoot/proxy/ProxyAuthenticator.java index df77c687f..493d4f476 100644 --- a/src/main/java/org/littleshoot/proxy/ProxyAuthenticator.java +++ b/src/main/java/org/littleshoot/proxy/ProxyAuthenticator.java @@ -5,18 +5,17 @@ * the basis of a username and password. */ public interface ProxyAuthenticator { + /** - * Authenticates the user using the specified userName and password. - * - * @param userName - * The user name. - * @param password - * The password. - * @return true if the credentials are acceptable, otherwise + * Authenticates the user using the specified proxy authorization header. + * + * @param proxyAuthorizationHeaderValue + * The proxy authorization header value. + * @return true if the credential is acceptable, otherwise * false. */ - boolean authenticate(String userName, String password); - + boolean authenticate(String proxyAuthorizationHeaderValue); + /** * The realm value to be used in the request for proxy authentication * ("Proxy-Authenticate" header). Returning null will cause the string diff --git a/src/main/java/org/littleshoot/proxy/impl/ClientToProxyConnection.java b/src/main/java/org/littleshoot/proxy/impl/ClientToProxyConnection.java index 964858fbf..f7c906c71 100644 --- a/src/main/java/org/littleshoot/proxy/impl/ClientToProxyConnection.java +++ b/src/main/java/org/littleshoot/proxy/impl/ClientToProxyConnection.java @@ -982,15 +982,7 @@ private boolean authenticationRequired(HttpRequest request) { List values = request.headers().getAll( HttpHeaders.Names.PROXY_AUTHORIZATION); String fullValue = values.iterator().next(); - String value = StringUtils.substringAfter(fullValue, "Basic ").trim(); - - byte[] decodedValue = BaseEncoding.base64().decode(value); - - String decodedString = new String(decodedValue, Charset.forName("UTF-8")); - - String userName = StringUtils.substringBefore(decodedString, ":"); - String password = StringUtils.substringAfter(decodedString, ":"); - if (!authenticator.authenticate(userName, password)) { + if (!authenticator.authenticate(fullValue)) { writeAuthenticationRequired(authenticator.getRealm()); return true; } diff --git a/src/test/java/org/littleshoot/proxy/MITMUsernamePasswordAuthenticatingProxyTest.java b/src/test/java/org/littleshoot/proxy/MITMUsernamePasswordAuthenticatingProxyTest.java index 48369cdd0..f9ef07210 100644 --- a/src/test/java/org/littleshoot/proxy/MITMUsernamePasswordAuthenticatingProxyTest.java +++ b/src/test/java/org/littleshoot/proxy/MITMUsernamePasswordAuthenticatingProxyTest.java @@ -22,4 +22,5 @@ protected void setUp() { protected boolean isMITM() { return true; } + } diff --git a/src/test/java/org/littleshoot/proxy/UsernamePasswordAuthenticatingProxyTest.java b/src/test/java/org/littleshoot/proxy/UsernamePasswordAuthenticatingProxyTest.java index f3c704aeb..511fb26a6 100644 --- a/src/test/java/org/littleshoot/proxy/UsernamePasswordAuthenticatingProxyTest.java +++ b/src/test/java/org/littleshoot/proxy/UsernamePasswordAuthenticatingProxyTest.java @@ -24,8 +24,8 @@ protected String getPassword() { } @Override - public boolean authenticate(String userName, String password) { - return getUsername().equals(userName) && getPassword().equals(password); + public boolean authenticate(String proxyAuthorizationHeaderValue) { + return new TestBasicProxyAuthenticator(getUsername(), getPassword()).authenticate(proxyAuthorizationHeaderValue); } @Override @@ -37,4 +37,25 @@ protected boolean isAuthenticating() { public String getRealm() { return null; } + + static class TestBasicProxyAuthenticator extends BasicProxyAuthenticator{ + + private final String username; + private final String password; + + TestBasicProxyAuthenticator(String username, String password) { + this.username = username; + this.password = password; + } + + @Override + boolean authenticate(String username, String password) { + return this.username.equals(username) && this.password.equals(password); + } + + @Override + public String getRealm() { + return null; + } + } }