Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions client/src/main/java/org/asynchttpclient/Realm.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import java.nio.charset.Charset;
import java.security.MessageDigest;
import java.security.SecureRandom;
import java.util.Base64;
import java.util.Map;

import static java.nio.charset.StandardCharsets.ISO_8859_1;
Expand Down Expand Up @@ -70,6 +71,7 @@ public class Realm {
private final boolean userhash;
private final @Nullable String sid;
private final int maxIterationCount;
private @Nullable String basicAuthHeader;

private Realm(@Nullable AuthScheme scheme,
@Nullable String principal,
Expand Down Expand Up @@ -245,6 +247,23 @@ public int getMaxIterationCount() {
return maxIterationCount;
}

/**
* Returns the lazily computed and cached HTTP Basic authorization header for this immutable realm.
* Concurrent first calls may compute the same value more than once.
*
* @return the Basic authorization header
* @since 3.0.12
*/
public String getBasicAuthHeader() {
String header = basicAuthHeader;
if (header == null) {
String s = principal + ':' + password;
header = "Basic " + Base64.getEncoder().encodeToString(s.getBytes(charset));
basicAuthHeader = header;
}
return header;
}

@Override
public String toString() {
return "Realm{" +
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.security.MessageDigest;
import java.util.Base64;
import java.util.List;
import java.util.Set;

Expand Down Expand Up @@ -87,12 +86,7 @@ private AuthenticatorUtils() {
}

private static @Nullable String computeBasicAuthentication(@Nullable Realm realm) {
return realm != null ? computeBasicAuthentication(realm.getPrincipal(), realm.getPassword(), realm.getCharset()) : null;
}

private static String computeBasicAuthentication(@Nullable String principal, @Nullable String password, Charset charset) {
String s = principal + ':' + password;
return "Basic " + Base64.getEncoder().encodeToString(s.getBytes(charset));
return realm != null ? realm.getBasicAuthHeader() : null;
}

public static String computeRealmURI(Uri uri, boolean useAbsoluteURI, boolean omitQuery) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,12 +40,32 @@
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertSame;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

public class AuthenticatorUtilsTest {
@Test
void preemptiveBasicAuthorizationHeaderIsMemoizedOnRealm() {
Request request = new RequestBuilder("GET")
.setUrl("http://example.com/api/users")
.build();
Realm realm = new Realm.Builder("user", "pass")
.setScheme(Realm.AuthScheme.BASIC)
.setUsePreemptiveAuth(true)
.build();

String first = AuthenticatorUtils.perRequestAuthorizationHeader(request, realm);
String second = AuthenticatorUtils.perRequestAuthorizationHeader(request, realm);
String proxy = AuthenticatorUtils.perRequestProxyAuthorizationHeader(request, realm);

assertEquals("Basic dXNlcjpwYXNz", first);
assertSame(first, second);
assertSame(first, proxy);
}

@Test
void computeBodyHashEmptyBody() throws Exception {
Request request = new RequestBuilder("GET")
Expand Down
Loading