SEC-3045: Conditionally add MethodSecurityMetadataSourceAdvisor
This commit is contained in:
		
							parent
							
								
									a3df41b380
								
							
						
					
					
						commit
						9654df2cc3
					
				| 
						 | 
				
			
			@ -1,5 +1,5 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright 2002-2013 the original author or authors.
 | 
			
		||||
 * Copyright 2002-2015 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.
 | 
			
		||||
| 
						 | 
				
			
			@ -23,9 +23,11 @@ import org.aopalliance.intercept.MethodInterceptor;
 | 
			
		|||
import org.apache.commons.logging.Log;
 | 
			
		||||
import org.apache.commons.logging.LogFactory;
 | 
			
		||||
import org.springframework.beans.factory.annotation.Autowired;
 | 
			
		||||
import org.springframework.beans.factory.config.BeanDefinition;
 | 
			
		||||
import org.springframework.context.ApplicationContext;
 | 
			
		||||
import org.springframework.context.annotation.*;
 | 
			
		||||
import org.springframework.context.annotation.AdviceMode;
 | 
			
		||||
import org.springframework.context.annotation.Bean;
 | 
			
		||||
import org.springframework.context.annotation.Configuration;
 | 
			
		||||
import org.springframework.context.annotation.ImportAware;
 | 
			
		||||
import org.springframework.core.annotation.AnnotationAttributes;
 | 
			
		||||
import org.springframework.core.annotation.AnnotationUtils;
 | 
			
		||||
import org.springframework.core.type.AnnotationMetadata;
 | 
			
		||||
| 
						 | 
				
			
			@ -45,7 +47,6 @@ import org.springframework.security.access.intercept.AfterInvocationManager;
 | 
			
		|||
import org.springframework.security.access.intercept.AfterInvocationProviderManager;
 | 
			
		||||
import org.springframework.security.access.intercept.RunAsManager;
 | 
			
		||||
import org.springframework.security.access.intercept.aopalliance.MethodSecurityInterceptor;
 | 
			
		||||
import org.springframework.security.access.intercept.aopalliance.MethodSecurityMetadataSourceAdvisor;
 | 
			
		||||
import org.springframework.security.access.intercept.aspectj.AspectJMethodSecurityInterceptor;
 | 
			
		||||
import org.springframework.security.access.method.DelegatingMethodSecurityMetadataSource;
 | 
			
		||||
import org.springframework.security.access.method.MethodSecurityMetadataSource;
 | 
			
		||||
| 
						 | 
				
			
			@ -317,21 +318,6 @@ public class GlobalMethodSecurityConfiguration implements ImportAware {
 | 
			
		|||
		return preInvocationAdvice;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Obtains the {@link MethodSecurityMetadataSourceAdvisor} to be used.
 | 
			
		||||
	 *
 | 
			
		||||
	 * @return
 | 
			
		||||
	 */
 | 
			
		||||
	@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
 | 
			
		||||
	@Bean
 | 
			
		||||
	public MethodSecurityMetadataSourceAdvisor metaDataSourceAdvisor() {
 | 
			
		||||
		MethodSecurityMetadataSourceAdvisor methodAdvisor = new MethodSecurityMetadataSourceAdvisor(
 | 
			
		||||
				"methodSecurityInterceptor", methodSecurityMetadataSource(),
 | 
			
		||||
				"methodSecurityMetadataSource");
 | 
			
		||||
		methodAdvisor.setOrder(order());
 | 
			
		||||
		return methodAdvisor;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Obtains the attributes from {@link EnableGlobalMethodSecurity} if this class was
 | 
			
		||||
	 * imported using the {@link EnableGlobalMethodSecurity} annotation.
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,5 +1,5 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright 2002-2013 the original author or authors.
 | 
			
		||||
 * Copyright 2002-2015 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.
 | 
			
		||||
| 
						 | 
				
			
			@ -54,13 +54,18 @@ final class GlobalMethodSecuritySelector implements ImportSelector {
 | 
			
		|||
				.isAssignableFrom(importingClass);
 | 
			
		||||
 | 
			
		||||
		AdviceMode mode = attributes.getEnum("mode");
 | 
			
		||||
		String autoProxyClassName = AdviceMode.PROXY == mode ? AutoProxyRegistrar.class
 | 
			
		||||
		boolean isProxy = AdviceMode.PROXY == mode;
 | 
			
		||||
		String autoProxyClassName = isProxy ? AutoProxyRegistrar.class
 | 
			
		||||
				.getName() : GlobalMethodSecurityAspectJAutoProxyRegistrar.class
 | 
			
		||||
				.getName();
 | 
			
		||||
 | 
			
		||||
		boolean jsr250Enabled = attributes.getBoolean("jsr250Enabled");
 | 
			
		||||
 | 
			
		||||
		List<String> classNames = new ArrayList<String>(4);
 | 
			
		||||
		if(isProxy) {
 | 
			
		||||
			classNames.add(MethodSecurityMetadataSourceAdvisorRegistrar.class.getName());
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		classNames.add(autoProxyClassName);
 | 
			
		||||
 | 
			
		||||
		if (!skipMethodSecurityConfiguration) {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,62 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright 2002-2015 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
 | 
			
		||||
 *
 | 
			
		||||
 *      http://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.security.config.annotation.method.configuration;
 | 
			
		||||
 | 
			
		||||
import org.springframework.beans.factory.config.BeanDefinition;
 | 
			
		||||
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
 | 
			
		||||
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
 | 
			
		||||
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
 | 
			
		||||
import org.springframework.core.type.AnnotationMetadata;
 | 
			
		||||
import org.springframework.security.access.intercept.aopalliance.MethodSecurityMetadataSourceAdvisor;
 | 
			
		||||
import org.springframework.util.MultiValueMap;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Creates Spring Security's MethodSecurityMetadataSourceAdvisor only when
 | 
			
		||||
 * using proxy based method security (i.e. do not do it when using ASPECTJ).
 | 
			
		||||
 * The conditional logic is controlled through {@link GlobalMethodSecuritySelector}.
 | 
			
		||||
 *
 | 
			
		||||
 * @author Rob Winch
 | 
			
		||||
 * @since 4.0.2
 | 
			
		||||
 * @see GlobalMethodSecuritySelector
 | 
			
		||||
 */
 | 
			
		||||
class MethodSecurityMetadataSourceAdvisorRegistrar implements
 | 
			
		||||
		ImportBeanDefinitionRegistrar {
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Register, escalate, and configure the AspectJ auto proxy creator based on the value
 | 
			
		||||
	 * of the @{@link EnableGlobalMethodSecurity#proxyTargetClass()} attribute on the
 | 
			
		||||
	 * importing {@code @Configuration} class.
 | 
			
		||||
	 */
 | 
			
		||||
	public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata,
 | 
			
		||||
			BeanDefinitionRegistry registry) {
 | 
			
		||||
 | 
			
		||||
		BeanDefinitionBuilder advisor = BeanDefinitionBuilder
 | 
			
		||||
				.rootBeanDefinition(MethodSecurityMetadataSourceAdvisor.class);
 | 
			
		||||
		advisor.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
 | 
			
		||||
		advisor.addConstructorArgValue("methodSecurityInterceptor");
 | 
			
		||||
		advisor.addConstructorArgReference("methodSecurityMetadataSource");
 | 
			
		||||
		advisor.addConstructorArgValue("methodSecurityMetadataSource");
 | 
			
		||||
 | 
			
		||||
		MultiValueMap<String,Object> attributes = importingClassMetadata.getAllAnnotationAttributes(EnableGlobalMethodSecurity.class.getName());
 | 
			
		||||
		Integer order = (Integer) attributes.getFirst("order");
 | 
			
		||||
		if(order != null) {
 | 
			
		||||
			advisor.addPropertyValue("order", order);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		registry.registerBeanDefinition("metaDataSourceAdvisor",
 | 
			
		||||
				advisor.getBeanDefinition());
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -15,6 +15,9 @@
 | 
			
		|||
 */
 | 
			
		||||
package org.springframework.security.config.annotation.method.configuration
 | 
			
		||||
 | 
			
		||||
import java.lang.reflect.Proxy;
 | 
			
		||||
 | 
			
		||||
import org.junit.After;
 | 
			
		||||
import org.springframework.beans.BeansException
 | 
			
		||||
import org.springframework.beans.factory.config.BeanPostProcessor
 | 
			
		||||
import org.springframework.security.config.annotation.authentication.configurers.GlobalAuthenticationConfigurerAdapter
 | 
			
		||||
| 
						 | 
				
			
			@ -29,6 +32,7 @@ import org.aopalliance.intercept.MethodInterceptor
 | 
			
		|||
import org.springframework.beans.factory.annotation.Autowired
 | 
			
		||||
import org.springframework.context.ApplicationContext
 | 
			
		||||
import org.springframework.context.ApplicationListener
 | 
			
		||||
import org.springframework.context.annotation.AdviceMode
 | 
			
		||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext
 | 
			
		||||
import org.springframework.context.annotation.Bean
 | 
			
		||||
import org.springframework.context.annotation.Configuration
 | 
			
		||||
| 
						 | 
				
			
			@ -48,6 +52,7 @@ import org.springframework.security.config.method.TestPermissionEvaluator;
 | 
			
		|||
import org.springframework.security.core.Authentication
 | 
			
		||||
import org.springframework.security.core.authority.AuthorityUtils
 | 
			
		||||
import org.springframework.security.core.context.SecurityContextHolder
 | 
			
		||||
import org.springframework.transaction.annotation.EnableTransactionManagement;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 *
 | 
			
		||||
| 
						 | 
				
			
			@ -398,4 +403,29 @@ public class GlobalMethodSecurityConfigurationTests extends BaseSpringSpec {
 | 
			
		|||
			bean
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	def "SEC-3045: Global Security proxies security"() {
 | 
			
		||||
		setup:
 | 
			
		||||
		when: 'load a Configuration that uses a Bean (DataSource) in a GlobalAuthenticationConfigurerAdapter'
 | 
			
		||||
		loadConfig(Sec3005Config)
 | 
			
		||||
		MethodSecurityService service = context.getBean(MethodSecurityService)
 | 
			
		||||
		then: 'The Bean (DataSource) is still properly post processed with all BeanPostProcessor'
 | 
			
		||||
		!Proxy.isProxyClass(service.getClass())
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@EnableGlobalMethodSecurity(prePostEnabled = true, mode= AdviceMode.ASPECTJ)
 | 
			
		||||
	@EnableTransactionManagement
 | 
			
		||||
	static class Sec3005Config {
 | 
			
		||||
		static DataSource dataSource;
 | 
			
		||||
 | 
			
		||||
		@Bean
 | 
			
		||||
		public MethodSecurityService service() {
 | 
			
		||||
			new MethodSecurityServiceImpl()
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		@Autowired
 | 
			
		||||
		public void configureGlobal(AuthenticationManagerBuilder auth) {
 | 
			
		||||
			auth.inMemoryAuthentication()
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue