From db963bc556e746509a0c3c3938520a794874202a Mon Sep 17 00:00:00 2001 From: Stephane Nicoll Date: Tue, 28 Jun 2016 17:28:56 +0200 Subject: [PATCH] Add BasicAuthorizationInterceptor This commit adds a `ClientHttpRequestInterceptor` that applies a BASIC authorization header for each request. It can be used as follows: ``` BasicAuthorizationInterceptor basicAuthorization = new BasicAuthorizationInterceptor("user", "secret"); restTemplate.getInterceptors().add(basicAuthorization); ``` Issue: SPR-14412 --- .../client/BasicAuthorizationInterceptor.java | 55 ++++++++++++++ .../BasicAuthorizationInterceptorTests.java | 75 +++++++++++++++++++ 2 files changed, 130 insertions(+) create mode 100644 spring-web/src/main/java/org/springframework/http/client/BasicAuthorizationInterceptor.java create mode 100644 spring-web/src/test/java/org/springframework/http/client/BasicAuthorizationInterceptorTests.java diff --git a/spring-web/src/main/java/org/springframework/http/client/BasicAuthorizationInterceptor.java b/spring-web/src/main/java/org/springframework/http/client/BasicAuthorizationInterceptor.java new file mode 100644 index 00000000000..3d49b918e76 --- /dev/null +++ b/spring-web/src/main/java/org/springframework/http/client/BasicAuthorizationInterceptor.java @@ -0,0 +1,55 @@ +/* + * 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.http.client; + +import java.io.IOException; +import java.nio.charset.Charset; + +import org.springframework.http.HttpRequest; +import org.springframework.util.Assert; +import org.springframework.util.Base64Utils; + +/** + * {@link ClientHttpRequestInterceptor} to apply a BASIC authorization header. + * + * @author Phillip Webb + * @since 4.3.1 + */ +public class BasicAuthorizationInterceptor implements ClientHttpRequestInterceptor { + + private static final Charset UTF_8 = Charset.forName("UTF-8"); + + private final String username; + + private final String password; + + public BasicAuthorizationInterceptor(String username, String password) { + Assert.hasLength(username, "Username must not be empty"); + this.username = username; + this.password = (password == null ? "" : password); + } + + @Override + public ClientHttpResponse intercept(HttpRequest request, byte[] body, + ClientHttpRequestExecution execution) throws IOException { + String token = Base64Utils + .encodeToString((this.username + ":" + this.password).getBytes(UTF_8)); + request.getHeaders().add("Authorization", "Basic " + token); + return execution.execute(request, body); + } + +} diff --git a/spring-web/src/test/java/org/springframework/http/client/BasicAuthorizationInterceptorTests.java b/spring-web/src/test/java/org/springframework/http/client/BasicAuthorizationInterceptorTests.java new file mode 100644 index 00000000000..ea1071c04bb --- /dev/null +++ b/spring-web/src/test/java/org/springframework/http/client/BasicAuthorizationInterceptorTests.java @@ -0,0 +1,75 @@ +/* + * 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.http.client; + +import java.net.URI; + +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; + +import org.springframework.beans.DirectFieldAccessor; +import org.springframework.http.HttpMethod; + +import static org.junit.Assert.*; +import static org.mockito.Mockito.*; + +/** + * Tests for {@link BasicAuthorizationInterceptor}. + * + * @author Phillip Webb + * @author Stephane Nicoll + */ +public class BasicAuthorizationInterceptorTests { + + @Rule + public ExpectedException thrown = ExpectedException.none(); + + @Test + public void createWhenUsernameIsNullShouldThrowException() { + this.thrown.expect(IllegalArgumentException.class); + this.thrown.expectMessage("Username must not be empty"); + new BasicAuthorizationInterceptor(null, "password"); + } + + @Test + public void createWhenUsernameIsEmptyShouldThrowException() throws Exception { + this.thrown.expect(IllegalArgumentException.class); + this.thrown.expectMessage("Username must not be empty"); + new BasicAuthorizationInterceptor("", "password"); + } + + @Test + public void createWhenPasswordIsNullShouldUseEmptyPassword() throws Exception { + BasicAuthorizationInterceptor interceptor = new BasicAuthorizationInterceptor( + "username", null); + assertEquals("", new DirectFieldAccessor(interceptor).getPropertyValue("password")); + } + + @Test + public void interceptShouldAddHeader() throws Exception { + SimpleClientHttpRequestFactory requestFactory = new SimpleClientHttpRequestFactory(); + ClientHttpRequest request = requestFactory.createRequest(new URI("http://example.com"), HttpMethod.GET); + ClientHttpRequestExecution execution = mock(ClientHttpRequestExecution.class); + byte[] body = new byte[] {}; + new BasicAuthorizationInterceptor("spring", "boot").intercept(request, body, + execution); + verify(execution).execute(request, body); + assertEquals("Basic c3ByaW5nOmJvb3Q=", request.getHeaders().getFirst("Authorization")); + } + +}