我想自定义Spring Security提供的OAuth授权服务器的一些代码。负责生成/ oauth / authorize的代码是一个名为AuthorizationEndpoint的bean。在AuthorizationServerEndpointsConfiguration类中,以下代码创建AuthorizationEndpoint类的bean:
@Bean
public AuthorizationEndpoint authorizationEndpoint() throws Exception {
AuthorizationEndpoint authorizationEndpoint = new AuthorizationEndpoint();
FrameworkEndpointHandlerMapping mapping = getEndpointsConfigurer().getFrameworkEndpointHandlerMapping();
authorizationEndpoint.setUserApprovalPage(extractPath(mapping, "/oauth/confirm_access"));
authorizationEndpoint.setProviderExceptionHandler(exceptionTranslator());
authorizationEndpoint.setErrorPage(extractPath(mapping, "/oauth/error"));
authorizationEndpoint.setTokenGranter(tokenGranter());
authorizationEndpoint.setClientDetailsService(clientDetailsService);
authorizationEndpoint.setAuthorizationCodeServices(authorizationCodeServices());
authorizationEndpoint.setOAuth2RequestFactory(oauth2RequestFactory());
authorizationEndpoint.setOAuth2RequestValidator(oauth2RequestValidator());
authorizationEndpoint.setUserApprovalHandler(userApprovalHandler());
return authorizationEndpoint;
}
我想用新的自定义bean覆盖它。我创建了一个扩展AuthorizationEndpoint的类。现在,我已经在新类中粘贴了相同的代码。
public class AuthorizationEndpointCustom extends AuthorizationEndpoint {
创建bean:
@Autowired
private ClientDetailsService clientDetailsService;
@Autowired
AuthorizationServerEndpointsConfiguration asec;
@Bean
// @Order(value = Ordered.LOWEST_PRECEDENCE)
@Primary
public AuthorizationEndpoint authorizationEndpoint () {
AuthorizationEndpointCustom authorizationEndpoint = new AuthorizationEndpointCustom();
FrameworkEndpointHandlerMapping mapping = asec.getEndpointsConfigurer().getFrameworkEndpointHandlerMapping();
authorizationEndpoint.setUserApprovalPage(extractPath(mapping, "/oauth/confirm_access"));
authorizationEndpoint.setProviderExceptionHandler(asec.getEndpointsConfigurer().getExceptionTranslator());
authorizationEndpoint.setErrorPage(extractPath(mapping, "/oauth/error"));
authorizationEndpoint.setTokenGranter(asec.getEndpointsConfigurer().getTokenGranter());
authorizationEndpoint.setClientDetailsService(clientDetailsService);
authorizationEndpoint.setAuthorizationCodeServices(asec.getEndpointsConfigurer().getAuthorizationCodeServices());
authorizationEndpoint.setOAuth2RequestFactory(asec.getEndpointsConfigurer().getOAuth2RequestFactory());
authorizationEndpoint.setOAuth2RequestValidator(asec.getEndpointsConfigurer().getOAuth2RequestValidator());
authorizationEndpoint.setUserApprovalHandler(asec.getEndpointsConfigurer().getUserApprovalHandler());
return authorizationEndpoint;
}
private String extractPath(FrameworkEndpointHandlerMapping mapping, String page) {
String path = mapping.getPath(page);
if (path.contains(":")) {
return path;
}
return "forward:" + path;
}
当我尝试创建这个新类的bean时,遇到以下错误:
申请无法开始
说明:
bean'authorizationEndpoint',在org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerEndpointsConfiguration,无法注册。那个名字的豆已经在类路径资源中定义[com / example / demo / AuthorizationServerConfig.class]和覆盖是禁用。
动作:
考虑重命名一个bean或通过设置启用覆盖spring.main.allow-bean-definition-overriding = true
错误通过将建议的配置添加到application.properties而消失。但是新bean不会替代框架bean。在代码的另一部分中,我从applicationContext访问了AuthorizationEndpoint。我调用了该对象的.getClass(),它与框架中的bean是相同的:
“ org.springframework.security.oauth2.provider.endpoint.AuthorizationEndpoint”
如何强制spring使用我的bean?
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class AppConfig {
@Bean
public AuthorizationEndpoint authorizationEndpoint() {
if(...) return new AuthorizationEndpoint();
else return new AuthorizationEndpointCustom();
}
}