diff --git a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/trace/TraceProperties.java b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/trace/TraceProperties.java index 4bc9a24c1f7..bb257df24f1 100644 --- a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/trace/TraceProperties.java +++ b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/trace/TraceProperties.java @@ -29,6 +29,7 @@ import org.springframework.boot.context.properties.ConfigurationProperties; * @author Wallace Wadge * @author Phillip Webb * @author Venil Noronha + * @author Madhura Bhave * @since 1.3.0 */ @ConfigurationProperties(prefix = "management.trace") @@ -79,6 +80,11 @@ public class TraceProperties { */ COOKIES, + /** + * Include authorization header (if any). + */ + AUTHORIZATION_HEADER, + /** * Include errors (if any). */ diff --git a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/trace/WebRequestTraceFilter.java b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/trace/WebRequestTraceFilter.java index dfaa375bea5..81c835de751 100644 --- a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/trace/WebRequestTraceFilter.java +++ b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/trace/WebRequestTraceFilter.java @@ -20,9 +20,11 @@ import java.io.IOException; import java.security.Principal; import java.util.Collections; import java.util.Enumeration; +import java.util.HashSet; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; +import java.util.Set; import javax.servlet.Filter; import javax.servlet.FilterChain; @@ -49,6 +51,7 @@ import org.springframework.web.filter.OncePerRequestFilter; * @author Wallace Wadge * @author Andy Wilkinson * @author Venil Noronha + * @author Madhura Bhave */ public class WebRequestTraceFilter extends OncePerRequestFilter implements Ordered { @@ -151,8 +154,18 @@ public class WebRequestTraceFilter extends OncePerRequestFilter implements Order private Map getRequestHeaders(HttpServletRequest request) { Map headers = new LinkedHashMap(); Enumeration names = request.getHeaderNames(); + Set excludedHeaders = new HashSet(); + if (!isIncluded(Include.COOKIES)) { + excludedHeaders.add("cookie"); + } + if (!isIncluded(Include.AUTHORIZATION_HEADER)) { + excludedHeaders.add("authorization"); + } while (names.hasMoreElements()) { String name = names.nextElement(); + if (excludedHeaders.contains(name.toLowerCase())) { + continue; + } List values = Collections.list(request.getHeaders(name)); Object value = values; if (values.size() == 1) { @@ -163,9 +176,6 @@ public class WebRequestTraceFilter extends OncePerRequestFilter implements Order } headers.put(name, value); } - if (!isIncluded(Include.COOKIES)) { - headers.remove("Cookie"); - } postProcessRequestHeaders(headers); return headers; } diff --git a/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/trace/WebRequestTraceFilterTests.java b/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/trace/WebRequestTraceFilterTests.java index fe81ff1aade..a60593d3ce9 100644 --- a/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/trace/WebRequestTraceFilterTests.java +++ b/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/trace/WebRequestTraceFilterTests.java @@ -51,6 +51,7 @@ import static org.mockito.Mockito.verify; * @author Andy Wilkinson * @author Venil Noronha * @author Stephane Nicoll + * @author Madhura Bhave */ public class WebRequestTraceFilterTests { @@ -168,6 +169,43 @@ public class WebRequestTraceFilterTests { assertThat(map.get("request").toString()).isEqualTo("{Accept=application/json}"); } + @Test + @SuppressWarnings({ "unchecked" }) + public void filterDoesNotAddAuthorizationHeaderWithoutAuthorizationHeaderInclude() + throws ServletException, IOException { + MockHttpServletRequest request = new MockHttpServletRequest("GET", "/foo"); + request.addHeader("Authorization", "my-auth-header"); + MockHttpServletResponse response = new MockHttpServletResponse(); + this.filter.doFilterInternal(request, response, new FilterChain() { + @Override + public void doFilter(ServletRequest request, ServletResponse response) + throws IOException, ServletException { + } + }); + Map info = this.repository.findAll().iterator().next().getInfo(); + Map headers = (Map) info.get("headers"); + assertThat(((Map) headers.get("request"))).hasSize(0); + } + + @Test + @SuppressWarnings({ "unchecked" }) + public void filterAddsAuthorizationHeaderWhenAuthorizationHeaderIncluded() + throws ServletException, IOException { + this.properties.setInclude(EnumSet.of(Include.REQUEST_HEADERS, Include.AUTHORIZATION_HEADER)); + MockHttpServletRequest request = new MockHttpServletRequest("GET", "/foo"); + request.addHeader("Authorization", "my-auth-header"); + MockHttpServletResponse response = new MockHttpServletResponse(); + this.filter.doFilterInternal(request, response, new FilterChain() { + @Override + public void doFilter(ServletRequest request, ServletResponse response) + throws IOException, ServletException { + } + }); + Map info = this.repository.findAll().iterator().next().getInfo(); + Map headers = (Map) info.get("headers"); + assertThat(((Map) headers.get("request"))).containsKey("Authorization"); + } + @Test @SuppressWarnings({ "unchecked" }) public void filterDoesNotAddResponseCookiesWithCookiesExclude()