diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/oauth2/method/OAuth2MethodSecurityConfiguration.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/oauth2/method/OAuth2MethodSecurityConfiguration.java index 9d81f39cba..3c71a9dc0d 100644 --- a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/oauth2/method/OAuth2MethodSecurityConfiguration.java +++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/oauth2/method/OAuth2MethodSecurityConfiguration.java @@ -17,13 +17,18 @@ package org.springframework.boot.autoconfigure.security.oauth2.method; import org.springframework.beans.BeansException; +import org.springframework.beans.factory.BeanFactoryUtils; import org.springframework.beans.factory.config.BeanFactoryPostProcessor; import org.springframework.beans.factory.config.BeanPostProcessor; import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.context.ApplicationContext; +import org.springframework.context.ApplicationContextAware; import org.springframework.context.annotation.Configuration; +import org.springframework.security.access.PermissionEvaluator; import org.springframework.security.access.expression.method.DefaultMethodSecurityExpressionHandler; +import org.springframework.security.authentication.AuthenticationTrustResolver; import org.springframework.security.config.annotation.method.configuration.GlobalMethodSecurityConfiguration; import org.springframework.security.oauth2.common.OAuth2AccessToken; import org.springframework.security.oauth2.provider.expression.OAuth2MethodSecurityExpressionHandler; @@ -39,18 +44,35 @@ import org.springframework.security.oauth2.provider.expression.OAuth2MethodSecur @Configuration @ConditionalOnClass({ OAuth2AccessToken.class }) @ConditionalOnBean(GlobalMethodSecurityConfiguration.class) -public class OAuth2MethodSecurityConfiguration implements BeanFactoryPostProcessor { +public class OAuth2MethodSecurityConfiguration implements BeanFactoryPostProcessor, + ApplicationContextAware { + + private ApplicationContext applicationContext; + + @Override + public void setApplicationContext(ApplicationContext applicationContext) + throws BeansException { + this.applicationContext = applicationContext; + } @Override public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException { - OAuth2ExpressionHandlerInjectionPostProcessor processor = new OAuth2ExpressionHandlerInjectionPostProcessor(); + OAuth2ExpressionHandlerInjectionPostProcessor processor = new OAuth2ExpressionHandlerInjectionPostProcessor( + this.applicationContext); beanFactory.addBeanPostProcessor(processor); } private static class OAuth2ExpressionHandlerInjectionPostProcessor implements BeanPostProcessor { + private ApplicationContext applicationContext; + + public OAuth2ExpressionHandlerInjectionPostProcessor( + ApplicationContext applicationContext) { + this.applicationContext = applicationContext; + } + @Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { @@ -60,11 +82,36 @@ public class OAuth2MethodSecurityConfiguration implements BeanFactoryPostProcess @Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { - if (bean instanceof DefaultMethodSecurityExpressionHandler) { - return new OAuth2MethodSecurityExpressionHandler(); + if (bean instanceof DefaultMethodSecurityExpressionHandler + && !(bean instanceof OAuth2MethodSecurityExpressionHandler)) { + return getExpressionHandler((DefaultMethodSecurityExpressionHandler) bean); } return bean; } + + private OAuth2MethodSecurityExpressionHandler getExpressionHandler( + DefaultMethodSecurityExpressionHandler bean) { + OAuth2MethodSecurityExpressionHandler handler = new OAuth2MethodSecurityExpressionHandler(); + handler.setApplicationContext(this.applicationContext); + AuthenticationTrustResolver trustResolver = findInContext(AuthenticationTrustResolver.class); + if (trustResolver != null) { + handler.setTrustResolver(trustResolver); + } + PermissionEvaluator permissions = findInContext(PermissionEvaluator.class); + if (permissions != null) { + handler.setPermissionEvaluator(permissions); + } + handler.setExpressionParser(bean.getExpressionParser()); + return handler; + } + + private T findInContext(Class type) { + if (BeanFactoryUtils.beanNamesForTypeIncludingAncestors( + this.applicationContext, type).length == 1) { + return this.applicationContext.getBean(type); + } + return null; + } } }