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
This commit is contained in:
parent
c181a2d157
commit
c5008f844c
|
@ -17,13 +17,18 @@
|
||||||
package org.springframework.boot.autoconfigure.security.oauth2.method;
|
package org.springframework.boot.autoconfigure.security.oauth2.method;
|
||||||
|
|
||||||
import org.springframework.beans.BeansException;
|
import org.springframework.beans.BeansException;
|
||||||
|
import org.springframework.beans.factory.BeanFactoryUtils;
|
||||||
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
|
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
|
||||||
import org.springframework.beans.factory.config.BeanPostProcessor;
|
import org.springframework.beans.factory.config.BeanPostProcessor;
|
||||||
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
|
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
|
||||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
|
||||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
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.context.annotation.Configuration;
|
||||||
|
import org.springframework.security.access.PermissionEvaluator;
|
||||||
import org.springframework.security.access.expression.method.DefaultMethodSecurityExpressionHandler;
|
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.config.annotation.method.configuration.GlobalMethodSecurityConfiguration;
|
||||||
import org.springframework.security.oauth2.common.OAuth2AccessToken;
|
import org.springframework.security.oauth2.common.OAuth2AccessToken;
|
||||||
import org.springframework.security.oauth2.provider.expression.OAuth2MethodSecurityExpressionHandler;
|
import org.springframework.security.oauth2.provider.expression.OAuth2MethodSecurityExpressionHandler;
|
||||||
|
@ -39,18 +44,35 @@ import org.springframework.security.oauth2.provider.expression.OAuth2MethodSecur
|
||||||
@Configuration
|
@Configuration
|
||||||
@ConditionalOnClass({ OAuth2AccessToken.class })
|
@ConditionalOnClass({ OAuth2AccessToken.class })
|
||||||
@ConditionalOnBean(GlobalMethodSecurityConfiguration.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
|
@Override
|
||||||
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory)
|
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory)
|
||||||
throws BeansException {
|
throws BeansException {
|
||||||
OAuth2ExpressionHandlerInjectionPostProcessor processor = new OAuth2ExpressionHandlerInjectionPostProcessor();
|
OAuth2ExpressionHandlerInjectionPostProcessor processor = new OAuth2ExpressionHandlerInjectionPostProcessor(
|
||||||
|
this.applicationContext);
|
||||||
beanFactory.addBeanPostProcessor(processor);
|
beanFactory.addBeanPostProcessor(processor);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class OAuth2ExpressionHandlerInjectionPostProcessor implements
|
private static class OAuth2ExpressionHandlerInjectionPostProcessor implements
|
||||||
BeanPostProcessor {
|
BeanPostProcessor {
|
||||||
|
|
||||||
|
private ApplicationContext applicationContext;
|
||||||
|
|
||||||
|
public OAuth2ExpressionHandlerInjectionPostProcessor(
|
||||||
|
ApplicationContext applicationContext) {
|
||||||
|
this.applicationContext = applicationContext;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object postProcessBeforeInitialization(Object bean, String beanName)
|
public Object postProcessBeforeInitialization(Object bean, String beanName)
|
||||||
throws BeansException {
|
throws BeansException {
|
||||||
|
@ -60,11 +82,36 @@ public class OAuth2MethodSecurityConfiguration implements BeanFactoryPostProcess
|
||||||
@Override
|
@Override
|
||||||
public Object postProcessAfterInitialization(Object bean, String beanName)
|
public Object postProcessAfterInitialization(Object bean, String beanName)
|
||||||
throws BeansException {
|
throws BeansException {
|
||||||
if (bean instanceof DefaultMethodSecurityExpressionHandler) {
|
if (bean instanceof DefaultMethodSecurityExpressionHandler
|
||||||
return new OAuth2MethodSecurityExpressionHandler();
|
&& !(bean instanceof OAuth2MethodSecurityExpressionHandler)) {
|
||||||
|
return getExpressionHandler((DefaultMethodSecurityExpressionHandler) bean);
|
||||||
}
|
}
|
||||||
return 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> T findInContext(Class<T> type) {
|
||||||
|
if (BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
|
||||||
|
this.applicationContext, type).length == 1) {
|
||||||
|
return this.applicationContext.getBean(type);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue