diff --git a/oauth2/oauth2-resource-server/src/main/java/org/springframework/security/oauth2/server/resource/web/ServletBearerExchangeFilterFunction.java b/oauth2/oauth2-resource-server/src/main/java/org/springframework/security/oauth2/server/resource/web/ServletBearerExchangeFilterFunction.java
new file mode 100644
index 0000000000..820c05ac48
--- /dev/null
+++ b/oauth2/oauth2-resource-server/src/main/java/org/springframework/security/oauth2/server/resource/web/ServletBearerExchangeFilterFunction.java
@@ -0,0 +1,248 @@
+/*
+ * Copyright 2002-2019 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
+ *
+ * https://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.security.oauth2.server.resource.web;
+
+import java.util.Map;
+import java.util.function.Consumer;
+
+import org.reactivestreams.Subscription;
+import reactor.core.CoreSubscriber;
+import reactor.core.publisher.Hooks;
+import reactor.core.publisher.Mono;
+import reactor.core.publisher.Operators;
+import reactor.util.context.Context;
+
+import org.springframework.beans.factory.DisposableBean;
+import org.springframework.beans.factory.InitializingBean;
+import org.springframework.lang.Nullable;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.core.context.SecurityContextHolder;
+import org.springframework.security.oauth2.core.AbstractOAuth2Token;
+import org.springframework.web.reactive.function.client.ClientRequest;
+import org.springframework.web.reactive.function.client.ClientResponse;
+import org.springframework.web.reactive.function.client.ExchangeFilterFunction;
+import org.springframework.web.reactive.function.client.ExchangeFunction;
+import org.springframework.web.reactive.function.client.WebClient;
+
+/**
+ * An {@link ExchangeFilterFunction} that adds the
+ * Bearer Token
+ * from an existing {@link AbstractOAuth2Token} tied to the current {@link Authentication}.
+ *
+ * Suitable for Servlet applications, applying it to a typical {@link org.springframework.web.reactive.function.client.WebClient}
+ * configuration:
+ *
+ *
+ * @Bean
+ * WebClient webClient() {
+ * ServletBearerExchangeFilterFunction bearer = new ServletBearerExchangeFilterFunction();
+ * return WebClient.builder()
+ * .apply(bearer.oauth2Configuration())
+ * .build();
+ * }
+ *
+ *
+ * @author Josh Cummings
+ * @since 5.2
+ */
+public class ServletBearerExchangeFilterFunction
+ implements ExchangeFilterFunction, InitializingBean, DisposableBean {
+
+ private static final String AUTHENTICATION_ATTR_NAME = Authentication.class.getName();
+
+ private static final String REQUEST_CONTEXT_OPERATOR_KEY = RequestContextSubscriber.class.getName();
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void afterPropertiesSet() throws Exception {
+ Hooks.onLastOperator(REQUEST_CONTEXT_OPERATOR_KEY,
+ Operators.liftPublisher((s, sub) -> createRequestContextSubscriber(sub)));
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void destroy() throws Exception {
+ Hooks.resetOnLastOperator(REQUEST_CONTEXT_OPERATOR_KEY);
+ }
+
+ /**
+ * Configures the builder with {@link #defaultRequest()} and adds this as a {@link ExchangeFilterFunction}
+ * @return the {@link Consumer} to configure the builder
+ */
+ public Consumer oauth2Configuration() {
+ return builder -> builder.defaultRequest(defaultRequest()).filter(this);
+ }
+
+ /**
+ * Provides defaults for the {@link Authentication} using
+ * {@link SecurityContextHolder}. It also can default the {@link AbstractOAuth2Token} using the
+ * {@link #authentication(Authentication)}.
+ * @return the {@link Consumer} to populate the attributes
+ */
+ public Consumer> defaultRequest() {
+ return spec -> spec.attributes(attrs -> {
+ populateDefaultAuthentication(attrs);
+ });
+ }
+
+ /**
+ * Modifies the {@link ClientRequest#attributes()} to include the {@link Authentication} used to
+ * look up and save the {@link AbstractOAuth2Token}. The value is defaulted in
+ * {@link ServletBearerExchangeFilterFunction#defaultRequest()}
+ *
+ * @param authentication the {@link Authentication} to use.
+ * @return the {@link Consumer} to populate the attributes
+ */
+ public static Consumer