From b58a06208f261db26832db531eb975e1e7c7c232 Mon Sep 17 00:00:00 2001 From: Rob Winch Date: Thu, 8 Sep 2016 16:12:34 -0500 Subject: [PATCH] Add HttpBasic ClientWebRequestPostProcessor Issue: SPR-14682 --- .../ClientWebRequestPostProcessors.java | 68 ++++++++++++++++++ .../ClientWebRequestPostProcessorsTests.java | 71 +++++++++++++++++++ 2 files changed, 139 insertions(+) create mode 100644 spring-web/src/main/java/org/springframework/web/client/reactive/ClientWebRequestPostProcessors.java create mode 100644 spring-web/src/test/java/org/springframework/web/client/reactive/ClientWebRequestPostProcessorsTests.java diff --git a/spring-web/src/main/java/org/springframework/web/client/reactive/ClientWebRequestPostProcessors.java b/spring-web/src/main/java/org/springframework/web/client/reactive/ClientWebRequestPostProcessors.java new file mode 100644 index 00000000000..b7730c0b87e --- /dev/null +++ b/spring-web/src/main/java/org/springframework/web/client/reactive/ClientWebRequestPostProcessors.java @@ -0,0 +1,68 @@ +/* + * Copyright 2002-2016 the original author or authors. + * + * Licensed 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. + */ + +package org.springframework.web.client.reactive; + +import java.nio.charset.Charset; +import java.util.Base64; +import java.util.Base64.Encoder; + +import org.springframework.http.HttpHeaders; +import org.springframework.util.Assert; + +/** + * Static factory methods for creating {@link ClientWebRequestPostProcesor} instances. + * + * @author Rob Winch + * @since 5.0 + * @see DefaultClientWebRequestBuilder#apply(ClientWebRequestPostProcessors) + */ +public abstract class ClientWebRequestPostProcessors { + + /** + * Adds an Authorization header for HTTP Basic + * @param username the username to add + * @param password the password to add + * @return the {@link ClientWebRequestPostProcessor} that adds the Authorization header + */ + public static ClientWebRequestPostProcessor httpBasic(String username, String password) { + Assert.notNull(username, "username cannot be null"); + Assert.notNull(password, "password cannot be null"); + + return new ClientWebRequestPostProcessor() { + + @Override + public ClientWebRequest postProcess(ClientWebRequest toPostProcess) { + String authorization = authorization(username, password); + toPostProcess.getHttpHeaders().set(HttpHeaders.AUTHORIZATION, authorization); + return toPostProcess; + } + + private String authorization(String username, String password) { + String credentials = username + ":" + password; + return authorization(credentials); + } + + private String authorization(String credentials) { + byte[] credentialBytes = credentials.getBytes(Charset.defaultCharset()); + Encoder encoder = Base64.getEncoder(); + String encodedCredentials = encoder.encodeToString(credentialBytes); + return "Basic " + encodedCredentials; + } + }; + } + +} diff --git a/spring-web/src/test/java/org/springframework/web/client/reactive/ClientWebRequestPostProcessorsTests.java b/spring-web/src/test/java/org/springframework/web/client/reactive/ClientWebRequestPostProcessorsTests.java new file mode 100644 index 00000000000..7597f91c657 --- /dev/null +++ b/spring-web/src/test/java/org/springframework/web/client/reactive/ClientWebRequestPostProcessorsTests.java @@ -0,0 +1,71 @@ +/* + * Copyright 2002-2016 the original author or authors. + * + * Licensed 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. + */ + +package org.springframework.web.client.reactive; + +import java.nio.charset.Charset; +import java.util.Base64; +import java.util.Base64.Encoder; + +import org.junit.Test; +import org.springframework.http.HttpHeaders; + + +import static org.junit.Assert.*; +import static org.springframework.web.client.reactive.ClientWebRequestPostProcessors.*; +import static org.springframework.web.client.reactive.ClientWebRequestBuilders.*; + +/** + * + * @author Rob Winch + * @since 5.0 + */ +public class ClientWebRequestPostProcessorsTests { + + @Test + public void httpBasicWhenUsernamePasswordThenHeaderSet() { + ClientWebRequest request = get("/").apply(httpBasic("user", "password")).build(); + assertEquals(request.getHttpHeaders().getFirst(HttpHeaders.AUTHORIZATION), basic("user:password")); + } + + @Test + public void httpBasicWhenUsernameEmptyThenHeaderSet() { + ClientWebRequest request = get("/").apply(httpBasic("", "password")).build(); + assertEquals(request.getHttpHeaders().getFirst(HttpHeaders.AUTHORIZATION), basic(":password")); + } + + @Test + public void httpBasicWhenPasswordEmptyThenHeaderSet() { + ClientWebRequest request = get("/").apply(httpBasic("user", "")).build(); + assertEquals(request.getHttpHeaders().getFirst(HttpHeaders.AUTHORIZATION), basic("user:")); + } + + @Test(expected = IllegalArgumentException.class) + public void httpBasicWhenUsernameNullThenIllegalArgumentException() { + httpBasic(null, "password"); + } + + @Test(expected = IllegalArgumentException.class) + public void httpBasicWhenPasswordNullThenIllegalArgumentException() { + httpBasic("username", null); + } + + private static String basic(String string) { + Encoder encoder = Base64.getEncoder(); + byte[] bytes = string.getBytes(Charset.defaultCharset()); + return "Basic " + encoder.encodeToString(bytes); + } +}