Add EnableReactiveMethodSecurity
Issue gh-4496
This commit is contained in:
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
*
|
||||
* * Copyright 2002-2017 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.context.annotation.AdviceMode;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.core.Ordered;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Rob Winch
|
||||
* @since 5.0
|
||||
*/
|
||||
@Retention(value = java.lang.annotation.RetentionPolicy.RUNTIME)
|
||||
@Target(value = { java.lang.annotation.ElementType.TYPE })
|
||||
@Documented
|
||||
@Import({ ReactiveMethodSecuritySelector.class })
|
||||
@Configuration
|
||||
public @interface EnableReactiveMethodSecurity {
|
||||
/**
|
||||
* Indicate whether subclass-based (CGLIB) proxies are to be created as opposed
|
||||
* to standard Java interface-based proxies. The default is {@code false}. <strong>
|
||||
* Applicable only if {@link #mode()} is set to {@link AdviceMode#PROXY}</strong>.
|
||||
* <p>Note that setting this attribute to {@code true} will affect <em>all</em>
|
||||
* Spring-managed beans requiring proxying, not just those marked with {@code @Cacheable}.
|
||||
* For example, other beans marked with Spring's {@code @Transactional} annotation will
|
||||
* be upgraded to subclass proxying at the same time. This approach has no negative
|
||||
* impact in practice unless one is explicitly expecting one type of proxy vs another,
|
||||
* e.g. in tests.
|
||||
*/
|
||||
boolean proxyTargetClass() default false;
|
||||
|
||||
/**
|
||||
* Indicate how security advice should be applied. The default is
|
||||
* {@link AdviceMode#PROXY}.
|
||||
* @see AdviceMode
|
||||
*
|
||||
* @return the {@link AdviceMode} to use
|
||||
*/
|
||||
AdviceMode mode() default AdviceMode.PROXY;
|
||||
|
||||
/**
|
||||
* Indicate the ordering of the execution of the security advisor when multiple
|
||||
* advices are applied at a specific joinpoint. The default is
|
||||
* {@link Ordered#LOWEST_PRECEDENCE}.
|
||||
*
|
||||
* @return the order the security advisor should be applied
|
||||
*/
|
||||
int order() default Ordered.LOWEST_PRECEDENCE;
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
/*
|
||||
*
|
||||
* * Copyright 2002-2017 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.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.ImportAware;
|
||||
import org.springframework.context.annotation.Role;
|
||||
import org.springframework.core.type.AnnotationMetadata;
|
||||
import org.springframework.security.access.expression.method.*;
|
||||
import org.springframework.security.access.intercept.aopalliance.MethodSecurityMetadataSourceAdvisor;
|
||||
import org.springframework.security.access.method.AbstractMethodSecurityMetadataSource;
|
||||
import org.springframework.security.access.method.DelegatingMethodSecurityMetadataSource;
|
||||
import org.springframework.security.access.method.PrePostAdviceMethodInterceptor;
|
||||
import org.springframework.security.access.prepost.PrePostAnnotationSecurityMetadataSource;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* @author Rob Winch
|
||||
* @since 5.0
|
||||
*/
|
||||
@Configuration
|
||||
class ReactiveMethodSecurityConfiguration implements ImportAware {
|
||||
private int advisorOrder;
|
||||
|
||||
@Bean
|
||||
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
|
||||
public MethodSecurityMetadataSourceAdvisor methodSecurityInterceptor(AbstractMethodSecurityMetadataSource source) throws Exception {
|
||||
MethodSecurityMetadataSourceAdvisor advisor = new MethodSecurityMetadataSourceAdvisor(
|
||||
"securityMethodInterceptor", source, "methodMetadataSource");
|
||||
advisor.setOrder(advisorOrder);
|
||||
return advisor;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public DelegatingMethodSecurityMetadataSource methodMetadataSource() {
|
||||
ExpressionBasedAnnotationAttributeFactory attributeFactory = new ExpressionBasedAnnotationAttributeFactory(
|
||||
new DefaultMethodSecurityExpressionHandler());
|
||||
PrePostAnnotationSecurityMetadataSource prePostSource = new PrePostAnnotationSecurityMetadataSource(
|
||||
attributeFactory);
|
||||
return new DelegatingMethodSecurityMetadataSource(Arrays.asList(prePostSource));
|
||||
}
|
||||
|
||||
@Bean
|
||||
public PrePostAdviceMethodInterceptor securityMethodInterceptor(AbstractMethodSecurityMetadataSource source, MethodSecurityExpressionHandler handler) {
|
||||
|
||||
ExpressionBasedPostInvocationAdvice postAdvice = new ExpressionBasedPostInvocationAdvice(
|
||||
handler);
|
||||
ExpressionBasedPreInvocationAdvice preAdvice = new ExpressionBasedPreInvocationAdvice();
|
||||
preAdvice.setExpressionHandler(handler);
|
||||
|
||||
PrePostAdviceMethodInterceptor result = new PrePostAdviceMethodInterceptor(source);
|
||||
result.setPostAdvice(postAdvice);
|
||||
result.setPreAdvice(preAdvice);
|
||||
return result;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public DefaultMethodSecurityExpressionHandler methodSecurityExpressionHandler() {
|
||||
return new DefaultMethodSecurityExpressionHandler();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setImportMetadata(AnnotationMetadata importMetadata) {
|
||||
this.advisorOrder = (int) importMetadata.getAnnotationAttributes(EnableReactiveMethodSecurity.class.getName()).get("order");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
*
|
||||
* * Copyright 2002-2017 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.cache.annotation.ProxyCachingConfiguration;
|
||||
import org.springframework.context.annotation.AdviceMode;
|
||||
import org.springframework.context.annotation.AdviceModeImportSelector;
|
||||
import org.springframework.context.annotation.AutoProxyRegistrar;
|
||||
import org.springframework.lang.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Rob Winch
|
||||
* @since 5.0
|
||||
*/
|
||||
class ReactiveMethodSecuritySelector extends
|
||||
AdviceModeImportSelector<EnableReactiveMethodSecurity> {
|
||||
|
||||
@Override
|
||||
protected String[] selectImports(AdviceMode adviceMode) {
|
||||
switch (adviceMode) {
|
||||
case PROXY:
|
||||
return getProxyImports();
|
||||
default:
|
||||
throw new IllegalStateException("AdviceMode " + adviceMode + " is not supported");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the imports to use if the {@link AdviceMode} is set to {@link AdviceMode#PROXY}.
|
||||
* <p>Take care of adding the necessary JSR-107 import if it is available.
|
||||
*/
|
||||
private String[] getProxyImports() {
|
||||
List<String> result = new ArrayList<>();
|
||||
result.add(AutoProxyRegistrar.class.getName());
|
||||
result.add(ReactiveMethodSecurityConfiguration.class.getName());
|
||||
return result.toArray(new String[result.size()]);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user