ResourceServerTokenRelayAutoConfiguration.java
/*
* Copyright 2012-present 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.cloud.commons.security;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.boot.autoconfigure.condition.AllNestedConditions;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
import org.springframework.context.annotation.Conditional;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
/**
* Adds an MVC interceptor for relaying OAuth2 access tokens into the client context (if
* there is one). In this way an incoming request to a resource server can be relayed
* downstream just be using <code>@EnableOAuth2Client</code> and an
* <code>OAuth2RestTemplate</code>. An MVC interceptor is used so as to have a minimal
* impact on the call stack. If you are not using MVC you could use a custom filter or AOP
* interceptor wrapping the same call to an {@link AccessTokenContextRelay}.
*
* <br/>
*
* N.B. an app that is using {@link UserInfoTokenServices} generally doesn't need this
* interceptor, but it doesn't hurt to include it.
*
* @author Dave Syer
*
*/
@Configuration(proxyBeanMethods = false)
// @AutoConfigureAfter(OAuth2AutoConfiguration.class)
// @ResourceServerTokenRelayAutoConfiguration.ConditionalOnOAuth2ClientInResourceServer
// @ConditionalOnClass(ResourceServerConfiguration.class)
@ConditionalOnClass(WebMvcConfigurer.class)
@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET)
@ConditionalOnProperty(value = "spring.cloud.mvc.token-relay.enabled", matchIfMissing = true)
public class ResourceServerTokenRelayAutoConfiguration {
/*
* @Bean public AccessTokenContextRelay accessTokenContextRelay(OAuth2ClientContext
* context) { return new AccessTokenContextRelay(context); }
*/
/**
* A {@link WebMvcConfigurer} for the access token interceptor.
*
* @author Dave Syer
*
*/
@Configuration(proxyBeanMethods = false)
public static class ResourceServerTokenRelayRegistrationAutoConfiguration implements WebMvcConfigurer {
// @Autowired
// AccessTokenContextRelay accessTokenContextRelay;
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new HandlerInterceptor() {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
// accessTokenContextRelay.copyToken();
return true;
}
});
}
}
@Target({ ElementType.TYPE, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Conditional(OAuth2OnClientInResourceServerCondition.class)
@interface ConditionalOnOAuth2ClientInResourceServer {
}
private static class OAuth2OnClientInResourceServerCondition extends AllNestedConditions {
OAuth2OnClientInResourceServerCondition() {
super(ConfigurationPhase.REGISTER_BEAN);
}
/*
* @ConditionalOnBean(ResourceServerConfiguration.class) static class Server {
*
* }
*
* @ConditionalOnBean(OAuth2ClientConfiguration.class) static class Client {
*
* }
*/
}
}