@SuppressWarnings("unused") // Guice injected
    @Provides
    @Singleton
    WebTargetFactory provideJerseyRequestBuilder(final JerseyClientFactoryImpl jerseyClientFactory,
                                                 final SecurityContext securityContext,
                                                 final Provider<UserIdentityFactory> userIdentityFactoryProvider) {
        return url -> {
            final JerseyClientName clientName = JerseyClientName.STROOM;
            final Client client = jerseyClientFactory.getNamedClient(clientName);
            final WebTarget delegateWebTarget = client.target(url);
            LOGGER.debug("Building WebTarget for client: '{}', url: '{}'", clientName, url);

            return (WebTarget) new WebTargetProxy(delegateWebTarget) {
                @Override
                public Builder request() {
                    final Builder builder = super.request();
                    addAuthHeader(builder);
                    return builder;
                }

                @Override
                public Builder request(final String... acceptedResponseTypes) {
                    final Builder builder = super.request(acceptedResponseTypes);
                    addAuthHeader(builder);
                    return builder;
                }

                @Override
                public Builder request(final MediaType... acceptedResponseTypes) {
                    final Builder builder = super.request(acceptedResponseTypes);
                    addAuthHeader(builder);
                    return builder;
                }

                private void addAuthHeader(final Builder builder) {
                    final UserIdentity userIdentity = securityContext.getUserIdentity();

                    final UserIdentityFactory userIdentityFactory = userIdentityFactoryProvider.get();
                    if (!userIdentityFactory.isServiceUser(userIdentity)) {
                        // We are running as a user who is not the service/proc user so need to put their
                        // identity in the headers. We can't use the human user identity as they may have
                        // an AWS token that we can't refresh.
                        builder.header(UserIdentityFactory.RUN_AS_USER_HEADER, securityContext.getUserRef().getUuid());
                    }
                    // Always authenticate as the proc user
                    final Map<String, String> authHeaders = userIdentityFactory.getServiceUserAuthHeaders();

                    LOGGER.debug(() -> LogUtil.message("Adding auth headers to request, keys: '{}', userType: {}",
                            String.join(", ", NullSafe.map(authHeaders).keySet()),
                            NullSafe.get(userIdentity, Object::getClass, Class::getSimpleName)));

                    authHeaders.forEach(builder::header);
                }
            };
        };
    }
Provides a Jersey {@link WebTargetFactory} with added Authorization header containing the
user's access token.
Only use this when you want {@link WebTarget} with the Authorization header already added to it,
else just get a Client and create a {@link WebTarget} from that.
stroom-app/src/main/java/stroom/app/guice/JerseyModule.java