From c5008f844c93b571b092995dba5f97e0567a7f95 Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Mon, 20 Jul 2015 14:12:48 +0100 Subject: [PATCH] Make sure bean resolver is set in the OAuth2 expression evaluator Also copies the ExpressionParser (the only public getter), trust resolver and permission evaluator (if available in the context). Changes the logic to not replace an existing OAuth2MethodSecurityExpressionHandler so that users can override simply by providing a bean of that type. Fixes gh-3542 --- .../OAuth2MethodSecurityConfiguration.java | 55 +++++++++++++++++-- 1 file changed, 51 insertions(+), 4 deletions(-) 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; + } } }