Polish InterceptMethodsBeanDefinitionDecorator

Issue gh-11328
This commit is contained in:
Josh Cummings 2022-07-11 16:39:41 -06:00
parent ba0f8ec3ef
commit 7560a32460
No known key found for this signature in database
GPG Key ID: A306A51F43B8E5A5

View File

@ -69,27 +69,26 @@ import org.springframework.util.xml.DomUtils;
*/
public class InterceptMethodsBeanDefinitionDecorator implements BeanDefinitionDecorator {
private final InternalAuthorizationManagerInterceptMethodsBeanDefinitionDecorator authorizationManagerDelegate =
new InternalAuthorizationManagerInterceptMethodsBeanDefinitionDecorator();
private final BeanDefinitionDecorator delegate = new InternalInterceptMethodsBeanDefinitionDecorator();
@Override
public BeanDefinitionHolder decorate(Node node, BeanDefinitionHolder definition, ParserContext parserContext) {
if (this.authorizationManagerDelegate.supports(node)) {
return this.authorizationManagerDelegate.decorate(node, definition, parserContext);
}
MethodConfigUtils.registerDefaultMethodAccessManagerIfNecessary(parserContext);
return this.delegate.decorate(node, definition, parserContext);
}
/**
* This is the real class which does the work. We need access to the ParserContext in
* order to do bean registration.
*/
static class InternalInterceptMethodsBeanDefinitionDecorator
static class InternalAuthorizationManagerInterceptMethodsBeanDefinitionDecorator
extends AbstractInterceptorDrivenBeanDefinitionDecorator {
static final String ATT_METHOD = "method";
static final String ATT_ACCESS = "access";
private static final String ATT_ACCESS_MGR = "access-decision-manager-ref";
private static final String ATT_USE_AUTHORIZATION_MGR = "use-authorization-manager";
private static final String ATT_AUTHORIZATION_MGR = "authorization-manager-ref";
@ -99,16 +98,6 @@ public class InterceptMethodsBeanDefinitionDecorator implements BeanDefinitionDe
@Override
protected BeanDefinition createInterceptorDefinition(Node node) {
Element interceptMethodsElt = (Element) node;
if (Boolean.parseBoolean(interceptMethodsElt.getAttribute(ATT_USE_AUTHORIZATION_MGR))) {
return createAuthorizationManagerInterceptorDefinition(interceptMethodsElt);
}
if (StringUtils.hasText(interceptMethodsElt.getAttribute(ATT_AUTHORIZATION_MGR))) {
return createAuthorizationManagerInterceptorDefinition(interceptMethodsElt);
}
return createMethodSecurityInterceptorDefinition(interceptMethodsElt);
}
private BeanDefinition createAuthorizationManagerInterceptorDefinition(Element interceptMethodsElt) {
BeanDefinitionBuilder interceptor = BeanDefinitionBuilder
.rootBeanDefinition(AuthorizationManagerBeforeMethodInterceptor.class);
interceptor.setAutowireMode(AbstractBeanDefinition.AUTOWIRE_BY_TYPE);
@ -122,6 +111,14 @@ public class InterceptMethodsBeanDefinitionDecorator implements BeanDefinitionDe
.addConstructorArgValue(authorizationManager(managers)).getBeanDefinition();
}
boolean supports(Node node) {
Element interceptMethodsElt = (Element) node;
if (Boolean.parseBoolean(interceptMethodsElt.getAttribute(ATT_USE_AUTHORIZATION_MGR))) {
return true;
}
return StringUtils.hasText(interceptMethodsElt.getAttribute(ATT_AUTHORIZATION_MGR));
}
private Pointcut pointcut(Element interceptorElt, Element protectElt) {
String method = protectElt.getAttribute(ATT_METHOD);
Class<?> javaType = javaType(interceptorElt, method);
@ -159,55 +156,14 @@ public class InterceptMethodsBeanDefinitionDecorator implements BeanDefinitionDe
return ClassUtils.resolveClassName(typeName, this.beanClassLoader);
}
private BeanDefinition createMethodSecurityInterceptorDefinition(Element interceptMethodsElt) {
BeanDefinitionBuilder interceptor = BeanDefinitionBuilder
.rootBeanDefinition(MethodSecurityInterceptor.class);
// Default to autowiring to pick up after invocation mgr
interceptor.setAutowireMode(AbstractBeanDefinition.AUTOWIRE_BY_TYPE);
String accessManagerId = interceptMethodsElt.getAttribute(ATT_ACCESS_MGR);
if (!StringUtils.hasText(accessManagerId)) {
accessManagerId = BeanIds.METHOD_ACCESS_MANAGER;
}
interceptor.addPropertyValue("accessDecisionManager", new RuntimeBeanReference(accessManagerId));
interceptor.addPropertyValue("authenticationManager",
new RuntimeBeanReference(BeanIds.AUTHENTICATION_MANAGER));
// Lookup parent bean information
String parentBeanClass = ((Element) interceptMethodsElt.getParentNode()).getAttribute("class");
// Parse the included methods
List<Element> methods = DomUtils.getChildElementsByTagName(interceptMethodsElt, Elements.PROTECT);
Map<String, BeanDefinition> mappings = new ManagedMap<>();
for (Element protectmethodElt : methods) {
BeanDefinitionBuilder attributeBuilder = BeanDefinitionBuilder.rootBeanDefinition(SecurityConfig.class);
attributeBuilder.setFactoryMethod("createListFromCommaDelimitedString");
attributeBuilder.addConstructorArgValue(protectmethodElt.getAttribute(ATT_ACCESS));
// Support inference of class names
String methodName = protectmethodElt.getAttribute(ATT_METHOD);
if (methodName.lastIndexOf(".") == -1) {
if (parentBeanClass != null && !"".equals(parentBeanClass)) {
methodName = parentBeanClass + "." + methodName;
}
}
mappings.put(methodName, attributeBuilder.getBeanDefinition());
}
BeanDefinition metadataSource = new RootBeanDefinition(MapBasedMethodSecurityMetadataSource.class);
metadataSource.getConstructorArgumentValues().addGenericArgumentValue(mappings);
interceptor.addPropertyValue("securityMetadataSource", metadataSource);
return interceptor.getBeanDefinition();
}
}
private static class PrefixBasedMethodMatcher implements MethodMatcher, Pointcut {
private final ClassFilter classFilter;
private final Class<?> javaType;
private final String methodPrefix;
PrefixBasedMethodMatcher(Class<?> javaType, String methodPrefix) {
this.classFilter = new RootClassFilter(javaType);
this.javaType = javaType;
this.methodPrefix = methodPrefix;
}
@ -295,5 +251,58 @@ public class InterceptMethodsBeanDefinitionDecorator implements BeanDefinitionDe
}
}
}
/**
* This is the real class which does the work. We need access to the ParserContext in
* order to do bean registration.
*/
static class InternalInterceptMethodsBeanDefinitionDecorator
extends AbstractInterceptorDrivenBeanDefinitionDecorator {
static final String ATT_METHOD = "method";
static final String ATT_ACCESS = "access";
private static final String ATT_ACCESS_MGR = "access-decision-manager-ref";
@Override
protected BeanDefinition createInterceptorDefinition(Node node) {
Element interceptMethodsElt = (Element) node;
BeanDefinitionBuilder interceptor = BeanDefinitionBuilder
.rootBeanDefinition(MethodSecurityInterceptor.class);
// Default to autowiring to pick up after invocation mgr
interceptor.setAutowireMode(AbstractBeanDefinition.AUTOWIRE_BY_TYPE);
String accessManagerId = interceptMethodsElt.getAttribute(ATT_ACCESS_MGR);
if (!StringUtils.hasText(accessManagerId)) {
accessManagerId = BeanIds.METHOD_ACCESS_MANAGER;
}
interceptor.addPropertyValue("accessDecisionManager", new RuntimeBeanReference(accessManagerId));
interceptor.addPropertyValue("authenticationManager",
new RuntimeBeanReference(BeanIds.AUTHENTICATION_MANAGER));
// Lookup parent bean information
String parentBeanClass = ((Element) interceptMethodsElt.getParentNode()).getAttribute("class");
// Parse the included methods
List<Element> methods = DomUtils.getChildElementsByTagName(interceptMethodsElt, Elements.PROTECT);
Map<String, BeanDefinition> mappings = new ManagedMap<>();
for (Element protectmethodElt : methods) {
BeanDefinitionBuilder attributeBuilder = BeanDefinitionBuilder.rootBeanDefinition(SecurityConfig.class);
attributeBuilder.setFactoryMethod("createListFromCommaDelimitedString");
attributeBuilder.addConstructorArgValue(protectmethodElt.getAttribute(ATT_ACCESS));
// Support inference of class names
String methodName = protectmethodElt.getAttribute(ATT_METHOD);
if (methodName.lastIndexOf(".") == -1) {
if (parentBeanClass != null && !"".equals(parentBeanClass)) {
methodName = parentBeanClass + "." + methodName;
}
}
mappings.put(methodName, attributeBuilder.getBeanDefinition());
}
BeanDefinition metadataSource = new RootBeanDefinition(MapBasedMethodSecurityMetadataSource.class);
metadataSource.getConstructorArgumentValues().addGenericArgumentValue(mappings);
interceptor.addPropertyValue("securityMetadataSource", metadataSource);
return interceptor.getBeanDefinition();
}
}
}