INT-1408, added changes based on Luke's comments

This commit is contained in:
Oleg Zhurakousky
2010-09-03 13:32:15 +00:00
parent c00c75d5d5
commit 3f390274db
7 changed files with 110 additions and 78 deletions

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2008 the original author or authors.
* Copyright 2002-2010 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.
@@ -13,72 +13,21 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.integration.security.channel;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import org.springframework.security.access.ConfigAttribute;
import org.springframework.security.access.SecurityConfig;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
/**
* Creates the {@link ConfigAttribute}s for secured channel
* send and receive operations based on simple String values.
* Interface to encapsulate {@link ConfigAttribute}s for secured channel
* send and receive operations.
*
* @author Mark Fisher
* @author Oleg Zhurakousky
* @since 2.0
*/
public class ChannelAccessPolicy {
public interface ChannelAccessPolicy {
public Collection<ConfigAttribute> getConfigAttributesForSend();
private final Collection<ConfigAttribute> configAttributeDefinitionForSend;
private final Collection<ConfigAttribute> configAttributeDefinitionForReceive;
/**
* Create an access policy instance. The provided 'sendAccess' and 'receiveAccess'
* values may be a single String or a comma-delimited list of values. All whitespace
* will be trimmed. A <code>null</code> value indicates that the policy does not
* apply for either send or receive access type. At most one of the values may be null.
*/
@SuppressWarnings("unchecked")
public ChannelAccessPolicy(String sendAccess, String receiveAccess) {
boolean sendAccessDefined = StringUtils.hasText(sendAccess);
boolean recieveAccessDefined = StringUtils.hasText(receiveAccess);
Assert.isTrue(sendAccessDefined || recieveAccessDefined,
"At least one of 'sendAccess' and 'receiveAccess' must not be null.");
if (sendAccessDefined){
String[] sendAccessValues = StringUtils.commaDelimitedListToStringArray(sendAccess);
configAttributeDefinitionForSend = new HashSet<ConfigAttribute>();
for (String sendAccessValue : sendAccessValues) {
configAttributeDefinitionForSend.add(new SecurityConfig(StringUtils.trimAllWhitespace(sendAccessValue)));
}
} else {
configAttributeDefinitionForSend = Collections.EMPTY_SET;
}
if (recieveAccessDefined){
String[] receiveAccessValues = StringUtils.commaDelimitedListToStringArray(receiveAccess);
configAttributeDefinitionForReceive = new HashSet<ConfigAttribute>();
for (String receiveAccessValue : receiveAccessValues) {
configAttributeDefinitionForReceive.add(new SecurityConfig(StringUtils.trimAllWhitespace(receiveAccessValue)));
}
} else {
configAttributeDefinitionForReceive = Collections.EMPTY_SET;
}
}
public Collection<ConfigAttribute> getConfigAttributeDefinitionForSend() {
return this.configAttributeDefinitionForSend;
}
public Collection<ConfigAttribute> getConfigAttributeDefinitionForReceive() {
return this.configAttributeDefinitionForReceive;
}
}
public Collection<ConfigAttribute> getConfigAttributesForReceive();
}

View File

@@ -72,13 +72,13 @@ public class ChannelInvocationDefinitionSource implements SecurityMetadataSource
ChannelAccessPolicy accessPolicy = mapping.getValue();
if (pattern.matcher(channelName).matches()) {
if (invocation.isSend()) {
Collection<ConfigAttribute> definition = accessPolicy.getConfigAttributeDefinitionForSend();
Collection<ConfigAttribute> definition = accessPolicy.getConfigAttributesForSend();
if (definition != null) {
attributes.addAll(definition);
}
}
else if (invocation.isReceive()) {
Collection<ConfigAttribute> definition = accessPolicy.getConfigAttributeDefinitionForReceive();
Collection<ConfigAttribute> definition = accessPolicy.getConfigAttributesForReceive();
if (definition != null) {
attributes.addAll(definition);
}
@@ -92,9 +92,9 @@ public class ChannelInvocationDefinitionSource implements SecurityMetadataSource
Set<ConfigAttribute> allAttributes = new HashSet<ConfigAttribute>();
for (ChannelAccessPolicy policy : patternMappings.values()) {
Collection<ConfigAttribute> receiveAttributes = policy.getConfigAttributeDefinitionForReceive();
Collection<ConfigAttribute> receiveAttributes = policy.getConfigAttributesForReceive();
allAttributes.addAll(receiveAttributes);
Collection<ConfigAttribute> sendAttributes = policy.getConfigAttributeDefinitionForSend();
Collection<ConfigAttribute> sendAttributes = policy.getConfigAttributesForSend();
allAttributes.addAll(sendAttributes);
}

View File

@@ -0,0 +1,84 @@
/*
* Copyright 2002-2008 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.integration.security.channel;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import org.springframework.security.access.ConfigAttribute;
import org.springframework.security.access.SecurityConfig;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
/**
* Creates the {@link ConfigAttribute}s for secured channel
* send and receive operations based on simple String values.
*
* @author Mark Fisher
* @author Oleg Zhurakousky
*/
public class DefaultChannelAccessPolicy implements ChannelAccessPolicy {
private final Collection<ConfigAttribute> configAttributeDefinitionForSend;
private final Collection<ConfigAttribute> configAttributeDefinitionForReceive;
/**
* Create an access policy instance. The provided 'sendAccess' and 'receiveAccess'
* values may be a single String or a comma-delimited list of values. All whitespace
* will be trimmed. A <code>null</code> value indicates that the policy does not
* apply for either send or receive access type. At most one of the values may be null.
*/
@SuppressWarnings("unchecked")
public DefaultChannelAccessPolicy(String sendAccess, String receiveAccess) {
boolean sendAccessDefined = StringUtils.hasText(sendAccess);
boolean recieveAccessDefined = StringUtils.hasText(receiveAccess);
Assert.isTrue(sendAccessDefined || recieveAccessDefined,
"At least one of 'sendAccess' and 'receiveAccess' must not be null.");
if (sendAccessDefined){
String[] sendAccessValues = StringUtils.commaDelimitedListToStringArray(sendAccess);
configAttributeDefinitionForSend = new HashSet<ConfigAttribute>();
for (String sendAccessValue : sendAccessValues) {
configAttributeDefinitionForSend.add(new SecurityConfig(StringUtils.trimAllWhitespace(sendAccessValue)));
}
} else {
configAttributeDefinitionForSend = Collections.EMPTY_SET;
}
if (recieveAccessDefined){
String[] receiveAccessValues = StringUtils.commaDelimitedListToStringArray(receiveAccess);
configAttributeDefinitionForReceive = new HashSet<ConfigAttribute>();
for (String receiveAccessValue : receiveAccessValues) {
configAttributeDefinitionForReceive.add(new SecurityConfig(StringUtils.trimAllWhitespace(receiveAccessValue)));
}
} else {
configAttributeDefinitionForReceive = Collections.EMPTY_SET;
}
}
public Collection<ConfigAttribute> getConfigAttributesForSend() {
return this.configAttributeDefinitionForSend;
}
public Collection<ConfigAttribute> getConfigAttributesForReceive() {
return this.configAttributeDefinitionForReceive;
}
}

View File

@@ -83,7 +83,7 @@ public class SecuredChannelsParser extends AbstractSingleBeanDefinitionParser {
"At least one of 'send-access' or 'receive-access' must be provided.", accessPolicyElement);
}
BeanDefinitionBuilder accessPolicyBuilder = BeanDefinitionBuilder.genericBeanDefinition(
BASE_PACKAGE_NAME + ".channel.ChannelAccessPolicy");
BASE_PACKAGE_NAME + ".channel.DefaultChannelAccessPolicy");
accessPolicyBuilder.addConstructorArgValue(sendAccess);
accessPolicyBuilder.addConstructorArgValue(receiveAccess);
accessPolicyBuilder.getBeanDefinition().setRole(BeanDefinition.ROLE_SUPPORT);

View File

@@ -36,7 +36,7 @@ public class ChannelSecurityInterceptorBeanPostProcessorTests {
@Test
public void securedChannelIsProxied() {
ChannelInvocationDefinitionSource objectDefinitionSource = new ChannelInvocationDefinitionSource();
objectDefinitionSource.addPatternMapping(Pattern.compile("secured.*"), new ChannelAccessPolicy("ROLE_ADMIN", null));
objectDefinitionSource.addPatternMapping(Pattern.compile("secured.*"), new DefaultChannelAccessPolicy("ROLE_ADMIN", null));
ChannelSecurityInterceptor interceptor = new ChannelSecurityInterceptor(objectDefinitionSource);
ChannelSecurityInterceptorBeanPostProcessor postProcessor = new ChannelSecurityInterceptorBeanPostProcessor(interceptor);
QueueChannel securedChannel = new QueueChannel();
@@ -48,7 +48,7 @@ public class ChannelSecurityInterceptorBeanPostProcessorTests {
@Test
public void nonsecuredChannelIsNotProxied() {
ChannelInvocationDefinitionSource objectDefinitionSource = new ChannelInvocationDefinitionSource();
objectDefinitionSource.addPatternMapping(Pattern.compile("secured.*"), new ChannelAccessPolicy("ROLE_ADMIN", null));
objectDefinitionSource.addPatternMapping(Pattern.compile("secured.*"), new DefaultChannelAccessPolicy("ROLE_ADMIN", null));
ChannelSecurityInterceptor interceptor = new ChannelSecurityInterceptor(objectDefinitionSource);
ChannelSecurityInterceptorBeanPostProcessor postProcessor = new ChannelSecurityInterceptorBeanPostProcessor(interceptor);
QueueChannel channel = new QueueChannel();

View File

@@ -80,7 +80,7 @@ public class ChannelSecurityInterceptorTests {
private static ChannelSecurityInterceptor createInterceptor(String role) throws Exception {
ChannelInvocationDefinitionSource objectDefinitionSource = new ChannelInvocationDefinitionSource();
objectDefinitionSource.addPatternMapping(Pattern.compile("secured.*"), new ChannelAccessPolicy(role, null));
objectDefinitionSource.addPatternMapping(Pattern.compile("secured.*"), new DefaultChannelAccessPolicy(role, null));
ChannelSecurityInterceptor interceptor = new ChannelSecurityInterceptor(objectDefinitionSource);
AffirmativeBased accessDecisionManager = new AffirmativeBased();

View File

@@ -43,7 +43,6 @@ import org.springframework.test.context.junit4.AbstractJUnit4SpringContextTests;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
/**
@@ -73,8 +72,8 @@ public class SecuredChannelsParserTests extends AbstractJUnit4SpringContextTests
ChannelSecurityInterceptor interceptor = (ChannelSecurityInterceptor) advisors[0].getAdvice();
ChannelAccessPolicy policy = this.retrievePolicyForPatternString(beanName, interceptor);
assertNotNull("Pattern '" + beanName + "' is not included in mappings", policy);
Collection<ConfigAttribute> sendDefinition = policy.getConfigAttributeDefinitionForSend();
Collection<ConfigAttribute> receiveDefinition = policy.getConfigAttributeDefinitionForReceive();
Collection<ConfigAttribute> sendDefinition = policy.getConfigAttributesForSend();
Collection<ConfigAttribute> receiveDefinition = policy.getConfigAttributesForReceive();
assertTrue("ROLE_ADMIN not found as send attribute", this.getRolesFromDefintion(sendDefinition).contains("ROLE_ADMIN"));
assertTrue("Policy applies to receive", receiveDefinition.size() == 0);
}
@@ -91,8 +90,8 @@ public class SecuredChannelsParserTests extends AbstractJUnit4SpringContextTests
ChannelSecurityInterceptor interceptor = (ChannelSecurityInterceptor) advisors[0].getAdvice();
ChannelAccessPolicy policy = this.retrievePolicyForPatternString(beanName, interceptor);
assertNotNull("Pattern '" + beanName + "' is not included in mappings", policy);
Collection<ConfigAttribute> sendDefinition = policy.getConfigAttributeDefinitionForSend();
Collection<ConfigAttribute> receiveDefinition = policy.getConfigAttributeDefinitionForReceive();
Collection<ConfigAttribute> sendDefinition = policy.getConfigAttributesForSend();
Collection<ConfigAttribute> receiveDefinition = policy.getConfigAttributesForReceive();
Collection<String> sendRoles = this.getRolesFromDefintion(sendDefinition);
assertTrue("ROLE_ADMIN not found as send attribute", sendRoles.contains("ROLE_ADMIN"));
assertTrue("ROLE_USER not found as send attribute", sendRoles.contains("ROLE_USER"));
@@ -111,8 +110,8 @@ public class SecuredChannelsParserTests extends AbstractJUnit4SpringContextTests
ChannelSecurityInterceptor interceptor = (ChannelSecurityInterceptor) advisors[0].getAdvice();
ChannelAccessPolicy policy = this.retrievePolicyForPatternString(beanName, interceptor);
assertNotNull("Pattern '" + beanName + "' is not included in mappings", policy);
Collection<ConfigAttribute> sendDefinition = policy.getConfigAttributeDefinitionForSend();
Collection<ConfigAttribute> receiveDefinition = policy.getConfigAttributeDefinitionForReceive();
Collection<ConfigAttribute> sendDefinition = policy.getConfigAttributesForSend();
Collection<ConfigAttribute> receiveDefinition = policy.getConfigAttributesForReceive();
Collection<String> receiveRoles = this.getRolesFromDefintion(receiveDefinition);
assertTrue("ROLE_ADMIN not found as receive attribute", receiveRoles.contains("ROLE_ADMIN"));
assertTrue("Policy applies to receive", sendDefinition.size() == 0);
@@ -130,8 +129,8 @@ public class SecuredChannelsParserTests extends AbstractJUnit4SpringContextTests
ChannelSecurityInterceptor interceptor = (ChannelSecurityInterceptor) advisors[0].getAdvice();
ChannelAccessPolicy policy = this.retrievePolicyForPatternString(beanName, interceptor);
assertNotNull("Pattern '" + beanName + "' is not included in mappings", policy);
Collection<ConfigAttribute> sendDefinition = policy.getConfigAttributeDefinitionForSend();
Collection<ConfigAttribute> receiveDefinition = policy.getConfigAttributeDefinitionForReceive();
Collection<ConfigAttribute> sendDefinition = policy.getConfigAttributesForSend();
Collection<ConfigAttribute> receiveDefinition = policy.getConfigAttributesForReceive();
Collection<String> receiveRoles = this.getRolesFromDefintion(receiveDefinition);
assertTrue("ROLE_ADMIN not found as receive attribute", receiveRoles.contains("ROLE_ADMIN"));
assertTrue("ROLE_USER not found as receive attribute", receiveRoles.contains("ROLE_USER"));
@@ -150,8 +149,8 @@ public class SecuredChannelsParserTests extends AbstractJUnit4SpringContextTests
ChannelSecurityInterceptor interceptor = (ChannelSecurityInterceptor) advisors[0].getAdvice();
ChannelAccessPolicy policy = this.retrievePolicyForPatternString(beanName, interceptor);
assertNotNull("Pattern '" + beanName + "' is not included in mappings", policy);
Collection<ConfigAttribute> sendDefinition = policy.getConfigAttributeDefinitionForSend();
Collection<ConfigAttribute> receiveDefinition = policy.getConfigAttributeDefinitionForReceive();
Collection<ConfigAttribute> sendDefinition = policy.getConfigAttributesForSend();
Collection<ConfigAttribute> receiveDefinition = policy.getConfigAttributesForReceive();
assertNotNull("Pattern does not apply to 'send'", sendDefinition);
assertNotNull("Pattern does not apply to 'receive'", receiveDefinition);
Collection<String> sendRoles = this.getRolesFromDefintion(sendDefinition);