diff --git a/org.springframework.integration.security/src/main/java/org/springframework/integration/security/SecurityContextAssociatingHandlerInterceptor.java b/org.springframework.integration.security/src/main/java/org/springframework/integration/security/SecurityContextAssociatingHandlerInterceptor.java deleted file mode 100644 index fb7a7b47e8..0000000000 --- a/org.springframework.integration.security/src/main/java/org/springframework/integration/security/SecurityContextAssociatingHandlerInterceptor.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * 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; - -import org.springframework.integration.handler.InterceptingMessageHandler; -import org.springframework.integration.handler.MessageHandler; -import org.springframework.integration.message.Message; -import org.springframework.security.context.SecurityContext; -import org.springframework.security.context.SecurityContextHolder; - -/** - * Associates the {@link SecurityContext} propagated in the message header with - * the thread executing the handle call to a {@link MessageHandler}. - * - * @author Jonas Partner - */ -public class SecurityContextAssociatingHandlerInterceptor extends InterceptingMessageHandler { - - /** - * One time only set the strategy to be stack based to allow use of direct - * channels where push and pop is required rather than set and clear - */ - static { - SecurityContextHolder.setStrategyName(StackBasedSecurityContextHolderStrategy.class.getName()); - } - - public SecurityContextAssociatingHandlerInterceptor(MessageHandler target) { - super(target); - } - - @Override - public Message handle(Message message, MessageHandler target) { - if (message.getHeader().getAttributeNames().contains(SecurityContextUtils.SECURITY_CONTEXT_HEADER_ATTRIBUTE)) { - return handleInSecurityContext(message, target); - } - return target.handle(message); - } - - private Message handleInSecurityContext(Message message, MessageHandler target) { - SecurityContext context = SecurityContextUtils.getSecurityContextFromHeader(message); - SecurityContextHolder.setContext(context); - try { - return target.handle(message); - } - finally { - SecurityContextHolder.clearContext(); - } - } - -} diff --git a/org.springframework.integration.security/src/main/java/org/springframework/integration/security/SecurityContextPropagatingChannelInterceptor.java b/org.springframework.integration.security/src/main/java/org/springframework/integration/security/SecurityContextPropagatingChannelInterceptor.java deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/org.springframework.integration.security/src/main/java/org/springframework/integration/security/SecurityEnforcingChannelInterceptor.java b/org.springframework.integration.security/src/main/java/org/springframework/integration/security/SecurityEnforcingChannelInterceptor.java deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/org.springframework.integration.security/src/main/java/org/springframework/integration/security/config/SecuredChannelsParser.java b/org.springframework.integration.security/src/main/java/org/springframework/integration/security/channel/config/SecuredChannelsParser.java similarity index 87% rename from org.springframework.integration.security/src/main/java/org/springframework/integration/security/config/SecuredChannelsParser.java rename to org.springframework.integration.security/src/main/java/org/springframework/integration/security/channel/config/SecuredChannelsParser.java index 5ff3346b10..eec92924ac 100644 --- a/org.springframework.integration.security/src/main/java/org/springframework/integration/security/config/SecuredChannelsParser.java +++ b/org.springframework.integration.security/src/main/java/org/springframework/integration/security/channel/config/SecuredChannelsParser.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.integration.security.config; +package org.springframework.integration.security.channel.config; import java.util.ArrayList; import java.util.List; @@ -61,7 +61,6 @@ public class SecuredChannelsParser extends AbstractSingleBeanDefinitionParser { String receiveAccess = element.getAttribute("receive-access"); String sendAccess = element.getAttribute("send-access"); String accessDecisionManager = element.getAttribute("access-decision-manager"); - String propagation = element.getAttribute("propagate"); BeanDefinition interceptorBeanDefinition = createSecurityEnforcingChannelInterceptor(accessDecisionManager, sendAccess, receiveAccess); @@ -75,7 +74,6 @@ public class SecuredChannelsParser extends AbstractSingleBeanDefinitionParser { builder.getBeanDefinition().getConstructorArgumentValues() .addGenericArgumentValue(new ValueHolder(patternList)); - setPropagation(Boolean.parseBoolean(propagation), patternList, parserContext); } protected List processPatterns(NodeList patternList) { @@ -85,19 +83,6 @@ public class SecuredChannelsParser extends AbstractSingleBeanDefinitionParser { patterns.add(patternElement.getTextContent()); } return patterns; - - } - - protected void setPropagation(boolean propagation, List patterns, ParserContext parserContext) { - for (String pattern : patterns) { - if (propagation) { - SecurityPropagatingBeanPostProcessorDefinitionHelper.addToIncludeChannelList(pattern, parserContext); - } - else { - SecurityPropagatingBeanPostProcessorDefinitionHelper.addToExcludeChannelList(pattern, parserContext); - } - } - } protected BeanDefinition createSecurityEnforcingChannelInterceptor(String accessDecisionManager, String sendAccess, diff --git a/org.springframework.integration.security/src/main/java/org/springframework/integration/security/config/SecurityPropagatingBeanPostProcessor.java b/org.springframework.integration.security/src/main/java/org/springframework/integration/security/channel/config/SecurityPropagatingBeanPostProcessor.java similarity index 64% rename from org.springframework.integration.security/src/main/java/org/springframework/integration/security/config/SecurityPropagatingBeanPostProcessor.java rename to org.springframework.integration.security/src/main/java/org/springframework/integration/security/channel/config/SecurityPropagatingBeanPostProcessor.java index ba2cef2efb..edadc110fb 100644 --- a/org.springframework.integration.security/src/main/java/org/springframework/integration/security/config/SecurityPropagatingBeanPostProcessor.java +++ b/org.springframework.integration.security/src/main/java/org/springframework/integration/security/channel/config/SecurityPropagatingBeanPostProcessor.java @@ -14,11 +14,7 @@ * limitations under the License. */ -package org.springframework.integration.security.config; - -import java.util.ArrayList; -import java.util.List; -import java.util.regex.Pattern; +package org.springframework.integration.security.channel.config; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -27,6 +23,7 @@ import org.springframework.beans.factory.config.BeanPostProcessor; import org.springframework.core.Ordered; import org.springframework.integration.channel.AbstractMessageChannel; import org.springframework.integration.security.channel.SecurityContextPropagatingChannelInterceptor; +import org.springframework.integration.security.config.OrderedIncludeExcludeList; /** * Post processes channels applying appropriate propagation behaviour. If @@ -43,36 +40,12 @@ public class SecurityPropagatingBeanPostProcessor implements BeanPostProcessor, private final SecurityContextPropagatingChannelInterceptor interceptor = new SecurityContextPropagatingChannelInterceptor(); - private boolean propagateByDefault; - private final Log logger = LogFactory.getLog(this.getClass()); - private List channelsToInclude = new ArrayList(); + private final OrderedIncludeExcludeList includeExcludeList; - private List channelsToExclude = new ArrayList(); - - public boolean isPropagateByDefault() { - return this.propagateByDefault; - } - - public void setPropagateByDefault(boolean propagateByDefault) { - this.propagateByDefault = propagateByDefault; - } - - public List getChannelsToInclude() { - return this.channelsToInclude; - } - - public void setChannelsToInclude(List channelsToInclude) { - this.channelsToInclude = channelsToInclude; - } - - public List getChannelsToExclude() { - return this.channelsToExclude; - } - - public void setChannelsToExclude(List channelsToExclude) { - this.channelsToExclude = channelsToExclude; + public SecurityPropagatingBeanPostProcessor(OrderedIncludeExcludeList includeExcludeList) { + this.includeExcludeList = includeExcludeList; } public int getOrder() { @@ -86,7 +59,7 @@ public class SecurityPropagatingBeanPostProcessor implements BeanPostProcessor, public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { if (AbstractMessageChannel.class.isAssignableFrom(bean.getClass())) { AbstractMessageChannel channel = (AbstractMessageChannel) bean; - if (isIncluded(beanName) || (this.propagateByDefault && !isExcluded(beanName))) { + if (includeExcludeList.isIncluded(beanName)) { channel.addInterceptor(this.interceptor); if (logger.isDebugEnabled()) { logger.debug("Channel '" + beanName + "' will propagate a SecurityContext."); @@ -99,21 +72,4 @@ public class SecurityPropagatingBeanPostProcessor implements BeanPostProcessor, return bean; } - protected boolean isExcluded(String str) { - return matchesOnePattern(channelsToExclude, str); - } - - protected boolean isIncluded(String str) { - return matchesOnePattern(channelsToInclude, str); - } - - protected boolean matchesOnePattern(List patterns, String str) { - for (Pattern pattern : patterns) { - if (pattern.matcher(str).matches()) { - return true; - } - } - return false; - } - } diff --git a/org.springframework.integration.security/src/main/java/org/springframework/integration/security/config/SecurityPropagatingChannelsParser.java b/org.springframework.integration.security/src/main/java/org/springframework/integration/security/channel/config/SecurityPropagatingChannelsParser.java similarity index 62% rename from org.springframework.integration.security/src/main/java/org/springframework/integration/security/config/SecurityPropagatingChannelsParser.java rename to org.springframework.integration.security/src/main/java/org/springframework/integration/security/channel/config/SecurityPropagatingChannelsParser.java index 91fc4d758a..6ee2ad08da 100644 --- a/org.springframework.integration.security/src/main/java/org/springframework/integration/security/config/SecurityPropagatingChannelsParser.java +++ b/org.springframework.integration.security/src/main/java/org/springframework/integration/security/channel/config/SecurityPropagatingChannelsParser.java @@ -14,15 +14,23 @@ * limitations under the License. */ -package org.springframework.integration.security.config; +package org.springframework.integration.security.channel.config; + +import java.util.ArrayList; +import java.util.List; import org.w3c.dom.Element; +import org.w3c.dom.NodeList; import org.springframework.beans.factory.BeanDefinitionStoreException; +import org.springframework.beans.factory.config.ConstructorArgumentValues.ValueHolder; import org.springframework.beans.factory.support.AbstractBeanDefinition; import org.springframework.beans.factory.support.BeanDefinitionBuilder; import org.springframework.beans.factory.xml.AbstractSingleBeanDefinitionParser; import org.springframework.beans.factory.xml.ParserContext; +import org.springframework.integration.security.config.IncludeExcludePattern; +import org.springframework.integration.security.config.IncludeExcludePatternParser; +import org.springframework.integration.security.config.OrderedIncludeExcludeList; import org.springframework.security.context.SecurityContext; import org.springframework.util.StringUtils; @@ -34,17 +42,17 @@ import org.springframework.util.StringUtils; */ public class SecurityPropagatingChannelsParser extends AbstractSingleBeanDefinitionParser { + IncludeExcludePatternParser includeExcludePatternParser = new IncludeExcludePatternParser(); + @Override protected void doParse(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) { - builder.getBeanDefinition().setAbstract(true); - String propagation = element.getAttribute("propagate"); - boolean propagateByDefault = true; - if (StringUtils.hasText(propagation)) { - propagateByDefault = Boolean.parseBoolean(propagation); - } - if (propagateByDefault) { - SecurityPropagatingBeanPostProcessorDefinitionHelper.setPropagationDefault(true, parserContext); - } + boolean propagateByDefault = Boolean.parseBoolean(element.getAttribute("propagate-by-default")); + OrderedIncludeExcludeList includeExcludeList = includeExcludePatternParser.createFromNodeList( + propagateByDefault, element.getChildNodes()); + builder.getBeanDefinition().setBeanClass(SecurityPropagatingBeanPostProcessor.class); + builder.getBeanDefinition().getConstructorArgumentValues().addGenericArgumentValue( + new ValueHolder(includeExcludeList)); + } @Override diff --git a/org.springframework.integration.security/src/main/java/org/springframework/integration/security/config/IncludeExcludePattern.java b/org.springframework.integration.security/src/main/java/org/springframework/integration/security/config/IncludeExcludePattern.java index f0c6c37bea..68f1cc4ea3 100644 --- a/org.springframework.integration.security/src/main/java/org/springframework/integration/security/config/IncludeExcludePattern.java +++ b/org.springframework.integration.security/src/main/java/org/springframework/integration/security/config/IncludeExcludePattern.java @@ -1,14 +1,30 @@ +/* + * 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.config; /** * * @author Jonas Partner - * + * */ public class IncludeExcludePattern { - + private final boolean isIncludePattern; - + private final String pattern; public IncludeExcludePattern(boolean isIncludePattern, String pattern) { @@ -17,9 +33,9 @@ public class IncludeExcludePattern { } public IncludeExcludePattern(String pattern) { - this(true,pattern); + this(true, pattern); } - + public boolean isIncludePattern() { return isIncludePattern; } @@ -27,5 +43,5 @@ public class IncludeExcludePattern { public String getPattern() { return pattern; } - + } diff --git a/org.springframework.integration.security/src/main/java/org/springframework/integration/security/config/IncludeExcludePatternParser.java b/org.springframework.integration.security/src/main/java/org/springframework/integration/security/config/IncludeExcludePatternParser.java new file mode 100644 index 0000000000..9c9e017762 --- /dev/null +++ b/org.springframework.integration.security/src/main/java/org/springframework/integration/security/config/IncludeExcludePatternParser.java @@ -0,0 +1,40 @@ +/* + * 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.config; + +import java.util.ArrayList; +import java.util.List; + +import org.w3c.dom.Element; +import org.w3c.dom.NodeList; + +public class IncludeExcludePatternParser { + + public OrderedIncludeExcludeList createFromNodeList(boolean includeByDefault, NodeList nodeList) { + List patterns = new ArrayList(); + for (int i = 0; i < nodeList.getLength(); i++) { + if (nodeList.item(i).getNodeName().equals("includePattern")) { + patterns.add(new IncludeExcludePattern(true, ((Element) nodeList.item(i)).getTextContent())); + } + else if (nodeList.item(i).getNodeName().equals("excludePattern")) { + patterns.add(new IncludeExcludePattern(false, ((Element) nodeList.item(i)).getTextContent())); + } + } + return new JdkRegExpOrderedIncludeExcludeList(includeByDefault, patterns); + } + +} diff --git a/org.springframework.integration.security/src/main/java/org/springframework/integration/security/config/IntegrationSecurityNamespaceHandler.java b/org.springframework.integration.security/src/main/java/org/springframework/integration/security/config/IntegrationSecurityNamespaceHandler.java index 0f27f472d5..5f3ea53315 100644 --- a/org.springframework.integration.security/src/main/java/org/springframework/integration/security/config/IntegrationSecurityNamespaceHandler.java +++ b/org.springframework.integration.security/src/main/java/org/springframework/integration/security/config/IntegrationSecurityNamespaceHandler.java @@ -17,6 +17,8 @@ package org.springframework.integration.security.config; import org.springframework.beans.factory.xml.NamespaceHandlerSupport; +import org.springframework.integration.security.channel.config.SecuredChannelsParser; +import org.springframework.integration.security.channel.config.SecurityPropagatingChannelsParser; /** * Namespace handler for the security namespace. diff --git a/org.springframework.integration.security/src/main/java/org/springframework/integration/security/config/JdkRegExpOrderedIncludeExcludeList.java b/org.springframework.integration.security/src/main/java/org/springframework/integration/security/config/JdkRegExpOrderedIncludeExcludeList.java index d970b202f6..37276600f0 100644 --- a/org.springframework.integration.security/src/main/java/org/springframework/integration/security/config/JdkRegExpOrderedIncludeExcludeList.java +++ b/org.springframework.integration.security/src/main/java/org/springframework/integration/security/config/JdkRegExpOrderedIncludeExcludeList.java @@ -1,3 +1,19 @@ +/* + * 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.config; import java.util.ArrayList; @@ -6,38 +22,38 @@ import java.util.List; import java.util.regex.Pattern; public class JdkRegExpOrderedIncludeExcludeList implements OrderedIncludeExcludeList { - + private final boolean includeByDefault; - + private final List patternHolders; - - public JdkRegExpOrderedIncludeExcludeList(List patterns){ + + public JdkRegExpOrderedIncludeExcludeList(List patterns) { this(true, patterns); } - + public JdkRegExpOrderedIncludeExcludeList(boolean includeByDefault, List patterns) { super(); this.includeByDefault = includeByDefault; List patternHolders = new ArrayList(); - for(int i = 0 ; i (); - beanDefintion.getPropertyValues().addPropertyValue(CHANNELS_TO_EXCLUDE, channelsToExclude); - } - channelsToExclude.add(channelName); - } - - @SuppressWarnings("unchecked") - public static void addToIncludeChannelList(String channelName, ParserContext context) { - BeanDefinition beanDefintion = getOrCreateSecurityPropagatingBeanPostProcessor(context); - List channelsToExclude; - if (beanDefintion.getPropertyValues().contains(CHANNELS_TO_INCLUDE)) { - channelsToExclude = (List) beanDefintion.getPropertyValues().getPropertyValue(CHANNELS_TO_INCLUDE) - .getValue(); - } - else { - channelsToExclude = new ArrayList(); - beanDefintion.getPropertyValues().addPropertyValue(CHANNELS_TO_INCLUDE, channelsToExclude); - } - channelsToExclude.add(channelName); - } - - private static BeanDefinition getOrCreateSecurityPropagatingBeanPostProcessor(ParserContext context) { - BeanDefinition beanDefinition = null; - String postProcessorBeanName = SecurityPropagatingBeanPostProcessor.SECURITY_PROPAGATING_BEAN_POST_PROCESSOR_NAME; - if (context.getRegistry().containsBeanDefinition(postProcessorBeanName)) { - beanDefinition = context.getRegistry().getBeanDefinition(postProcessorBeanName); - } - if (beanDefinition == null) { - beanDefinition = new RootBeanDefinition(SecurityPropagatingBeanPostProcessor.class); - context.registerBeanComponent(new BeanComponentDefinition(beanDefinition, postProcessorBeanName)); - } - return beanDefinition; - } - -} diff --git a/org.springframework.integration.security/src/main/java/org/springframework/integration/security/config/spring-integration-security-1.0.xsd b/org.springframework.integration.security/src/main/java/org/springframework/integration/security/config/spring-integration-security-1.0.xsd index ad732c8684..26bd4f7ebf 100644 --- a/org.springframework.integration.security/src/main/java/org/springframework/integration/security/config/spring-integration-security-1.0.xsd +++ b/org.springframework.integration.security/src/main/java/org/springframework/integration/security/config/spring-integration-security-1.0.xsd @@ -24,7 +24,6 @@ - @@ -49,14 +48,26 @@ + Defines a bean post processor which propagates the - security context. + security context by registering interceptors with channels. - + + + + + + + + + + + + \ No newline at end of file diff --git a/org.springframework.integration.security/src/main/java/org/springframework/integration/security/target/TargetSecuringInterceptor.java b/org.springframework.integration.security/src/main/java/org/springframework/integration/security/endpoint/SecurityEndpointInterceptor.java similarity index 68% rename from org.springframework.integration.security/src/main/java/org/springframework/integration/security/target/TargetSecuringInterceptor.java rename to org.springframework.integration.security/src/main/java/org/springframework/integration/security/endpoint/SecurityEndpointInterceptor.java index 21cb1f0196..51ed14c9a4 100644 --- a/org.springframework.integration.security/src/main/java/org/springframework/integration/security/target/TargetSecuringInterceptor.java +++ b/org.springframework.integration.security/src/main/java/org/springframework/integration/security/endpoint/SecurityEndpointInterceptor.java @@ -14,9 +14,8 @@ * limitations under the License. */ -package org.springframework.integration.security.target; +package org.springframework.integration.security.endpoint; -import org.aopalliance.intercept.MethodInterceptor; import org.aopalliance.intercept.MethodInvocation; import org.springframework.integration.message.Message; import org.springframework.integration.security.SecurityContextUtils; @@ -24,33 +23,35 @@ import org.springframework.security.AccessDecisionManager; import org.springframework.security.ConfigAttributeDefinition; import org.springframework.security.context.SecurityContext; import org.springframework.security.context.SecurityContextHolder; +import org.springframework.temp.endpoint.EndpointInterceptor; -/** - * - * @author Jonas Partner - * - */ -public class TargetSecuringInterceptor implements MethodInterceptor { +public class SecurityEndpointInterceptor implements EndpointInterceptor { private final ConfigAttributeDefinition targetSecurityAttributes; private final AccessDecisionManager accessDecisionManager; - public TargetSecuringInterceptor(ConfigAttributeDefinition targetSecurityAttributes, + public SecurityEndpointInterceptor(ConfigAttributeDefinition endpointSecurityAttributes, AccessDecisionManager accessDecisionManager) { - this.targetSecurityAttributes = targetSecurityAttributes; + super(); + this.targetSecurityAttributes = endpointSecurityAttributes; this.accessDecisionManager = accessDecisionManager; } - public Object invoke(MethodInvocation invocation) throws Throwable { + public void aroundInvoke(MethodInvocation invocation) throws Throwable { Message message = (Message) invocation.getArguments()[0]; - SecurityContext ctx = SecurityContextUtils.getSecurityContextFromHeader(message); - if (ctx != null) { + + SecurityContext securityCtx = null; + + if(message != null){ + securityCtx = SecurityContextUtils.getSecurityContextFromHeader(message); + } + if (securityCtx != null) { try { - SecurityContextHolder.setContext(ctx); + SecurityContextHolder.setContext(securityCtx); accessDecisionManager.decide(SecurityContextHolder.getContext().getAuthentication(), invocation .getThis(), targetSecurityAttributes); - return invocation.proceed(); + invocation.proceed(); } finally { SecurityContextHolder.clearContext(); @@ -59,8 +60,16 @@ public class TargetSecuringInterceptor implements MethodInterceptor { else { accessDecisionManager.decide(SecurityContextHolder.getContext().getAuthentication(), invocation.getThis(), targetSecurityAttributes); - return invocation.proceed(); + invocation.proceed(); } } + public void postInvoke(Message message) { + + } + + public void preInvoke(Message message) { + + } + } diff --git a/org.springframework.integration.security/src/main/java/org/springframework/integration/security/target/TargetSecuringAdvisor.java b/org.springframework.integration.security/src/main/java/org/springframework/integration/security/target/TargetSecuringAdvisor.java deleted file mode 100644 index 86fb3567af..0000000000 --- a/org.springframework.integration.security/src/main/java/org/springframework/integration/security/target/TargetSecuringAdvisor.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * 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.target; - -import org.aopalliance.aop.Advice; -import org.springframework.aop.ClassFilter; -import org.springframework.aop.MethodMatcher; -import org.springframework.aop.Pointcut; -import org.springframework.aop.support.AbstractPointcutAdvisor; -import org.springframework.aop.support.ClassFilters; -import org.springframework.aop.support.MethodMatchers; -import org.springframework.aop.support.NameMatchMethodPointcut; -import org.springframework.aop.support.RootClassFilter; -import org.springframework.integration.message.BlockingTarget; -import org.springframework.integration.message.Target; -import org.springframework.security.AccessDecisionManager; -import org.springframework.security.ConfigAttributeDefinition; -import org.springframework.util.StringUtils; - -@SuppressWarnings("serial") -public class TargetSecuringAdvisor extends AbstractPointcutAdvisor implements Pointcut { - - private ClassFilter classFilter; - - private MethodMatcher matcher; - - private Advice targetSecuringInterceptor; - - public TargetSecuringAdvisor(AccessDecisionManager accessDecisionManager, String securityConfig) { - targetSecuringInterceptor = new TargetSecuringInterceptor(new ConfigAttributeDefinition(StringUtils - .tokenizeToStringArray(securityConfig, ",")), accessDecisionManager); - classFilter = ClassFilters.union(new RootClassFilter(Target.class), new RootClassFilter(BlockingTarget.class)); - NameMatchMethodPointcut nameMatcher = new NameMatchMethodPointcut(); - nameMatcher.addMethodName("send"); - matcher = MethodMatchers.intersection(nameMatcher, new TargetSendMethodArgMatcher()); - } - - public Pointcut getPointcut() { - return this; - } - - public Advice getAdvice() { - return targetSecuringInterceptor; - } - - public ClassFilter getClassFilter() { - return classFilter; - } - - public MethodMatcher getMethodMatcher() { - return matcher; - } - -} diff --git a/org.springframework.integration.security/src/main/java/org/springframework/integration/security/target/TargetSendMethodArgMatcher.java b/org.springframework.integration.security/src/main/java/org/springframework/integration/security/target/TargetSendMethodArgMatcher.java deleted file mode 100644 index de5bf8770b..0000000000 --- a/org.springframework.integration.security/src/main/java/org/springframework/integration/security/target/TargetSendMethodArgMatcher.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * 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.target; - -import java.lang.reflect.Method; - -import org.springframework.aop.support.StaticMethodMatcher; -import org.springframework.integration.message.Message; - -/** - * - * @author Jonas Partner - * - */ -public class TargetSendMethodArgMatcher extends StaticMethodMatcher{ - - - @SuppressWarnings("unchecked") - public boolean matches(Method method, Class targetClass) { - return argsTypesMatch(method.getParameterTypes()); - } - - - - @SuppressWarnings("unchecked") - protected boolean argsTypesMatch(Class[] args){ - if(args.length > 2){ - return false; - } - - if(args.length > 0){ - if(!Message.class.isAssignableFrom(args[0] )){ - return false; - } - } - - if (args.length > 1 ){ - if(!long.class.isAssignableFrom(args[1])){ - return false; - } - } - return true; - - - } -} \ No newline at end of file diff --git a/org.springframework.integration.security/src/main/java/org/springframework/integration/security/target/config/SecuredTargetsParser.java b/org.springframework.integration.security/src/main/java/org/springframework/integration/security/target/config/SecuredTargetsParser.java deleted file mode 100644 index 9faebf7d51..0000000000 --- a/org.springframework.integration.security/src/main/java/org/springframework/integration/security/target/config/SecuredTargetsParser.java +++ /dev/null @@ -1,30 +0,0 @@ -package org.springframework.integration.security.target.config; - -import org.springframework.beans.factory.support.BeanDefinitionBuilder; -import org.springframework.beans.factory.xml.AbstractSingleBeanDefinitionParser; -import org.springframework.beans.factory.xml.ParserContext; -import org.w3c.dom.Element; - -public class SecuredTargetsParser extends AbstractSingleBeanDefinitionParser { - - public SecuredTargetsParser() { - super(); - } - - @Override - protected boolean shouldGenerateId() { - return true; - } - - @Override - protected boolean shouldGenerateIdAsFallback() { - return true; - } - - @Override - protected void doParse(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) { - - } - - -} diff --git a/org.springframework.integration.security/src/main/java/org/springframework/temp/endpoint/EndpointInterceptor.java b/org.springframework.integration.security/src/main/java/org/springframework/temp/endpoint/EndpointInterceptor.java new file mode 100644 index 0000000000..06f5ae039c --- /dev/null +++ b/org.springframework.integration.security/src/main/java/org/springframework/temp/endpoint/EndpointInterceptor.java @@ -0,0 +1,28 @@ +/* + * 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.temp.endpoint; + +import org.aopalliance.intercept.MethodInvocation; +import org.springframework.integration.message.Message; + +public interface EndpointInterceptor { + + void preInvoke(Message message); + + void aroundInvoke(MethodInvocation invocation) throws Throwable; + + void postInvoke(Message message); +} diff --git a/org.springframework.integration.security/src/test/java/org/springframework/integration/security/ChannelInterceptorRegisteringBeanPostProcessorTests.java b/org.springframework.integration.security/src/test/java/org/springframework/integration/security/ChannelInterceptorRegisteringBeanPostProcessorTests.java index 22b26fe001..82e02de827 100644 --- a/org.springframework.integration.security/src/test/java/org/springframework/integration/security/ChannelInterceptorRegisteringBeanPostProcessorTests.java +++ b/org.springframework.integration.security/src/test/java/org/springframework/integration/security/ChannelInterceptorRegisteringBeanPostProcessorTests.java @@ -33,7 +33,7 @@ import org.springframework.integration.message.selector.MessageSelector; /** * * @author Jonas Partner - * + * */ public class ChannelInterceptorRegisteringBeanPostProcessorTests { diff --git a/org.springframework.integration.security/src/test/java/org/springframework/integration/security/SecurityContextAssociatingHandlerInterceptorTests.java b/org.springframework.integration.security/src/test/java/org/springframework/integration/security/SecurityContextAssociatingHandlerInterceptorTests.java deleted file mode 100644 index 08f47937ad..0000000000 --- a/org.springframework.integration.security/src/test/java/org/springframework/integration/security/SecurityContextAssociatingHandlerInterceptorTests.java +++ /dev/null @@ -1,171 +0,0 @@ -/* - * 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; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotSame; -import static org.junit.Assert.assertNull; - -import org.junit.After; -import org.junit.Test; -import org.springframework.integration.handler.MessageHandler; -import org.springframework.integration.message.Message; -import org.springframework.integration.message.StringMessage; -import org.springframework.security.AccessDeniedException; -import org.springframework.security.Authentication; -import org.springframework.security.GrantedAuthority; -import org.springframework.security.context.SecurityContext; -import org.springframework.security.context.SecurityContextHolder; - -/** - * @author Jonas Partner - */ -public class SecurityContextAssociatingHandlerInterceptorTests { - - @After - public void clearSecurityContext(){ - SecurityContextHolder.clearContext(); - } - - @Test - public void testMessageWithSecurityContext() { - final StubSecurityContext securityContext = new StubSecurityContext(); - StringMessage message = new StringMessage("test"); - SecurityContextUtils.setSecurityContextHeader(securityContext, message); - MessageHandler handler = new MessageHandler() { - public Message handle(Message message) { - SecurityContext associatedContext = SecurityContextHolder.getContext(); - assertEquals("Wrong security context", securityContext, associatedContext); - return null; - } - }; - SecurityContextAssociatingHandlerInterceptor associatingInterceptor = - new SecurityContextAssociatingHandlerInterceptor(handler); - associatingInterceptor.handle(message); - assertNull("Security context still present after handler returned", - SecurityContextHolder.getContext().getAuthentication()); - } - - @Test(expected = AccessDeniedException.class) - public void testForSecurityLeakageIfHandlerThrowsException() { - final StubSecurityContext securityContext = new StubSecurityContext(); - StringMessage message = new StringMessage("test"); - SecurityContextUtils.setSecurityContextHeader(securityContext, message); - MessageHandler handler = new MessageHandler() { - public Message handle(Message message) { - SecurityContext associatedContext = SecurityContextHolder.getContext(); - assertEquals("Wrong security context", securityContext, associatedContext); - throw new AccessDeniedException("Not allowed"); - } - }; - SecurityContextAssociatingHandlerInterceptor associatingInterceptor = - new SecurityContextAssociatingHandlerInterceptor(handler); - try { - associatingInterceptor.handle(message); - } - finally { - assertNull("Security context still present after handler threw exception", - SecurityContextHolder.getContext().getAuthentication()); - } - } - - @Test - public void testMessageWithoutSecurityContext() { - final StubSecurityContext securityContext = new StubSecurityContext(); - StringMessage message = new StringMessage("test"); - MessageHandler handler = new MessageHandler() { - public Message handle(Message message) { - SecurityContext associatedContext = SecurityContextHolder.getContext(); - assertNotSame("Wrong security context", securityContext, associatedContext); - return null; - } - }; - SecurityContextAssociatingHandlerInterceptor associatingInterceptor = - new SecurityContextAssociatingHandlerInterceptor(handler); - associatingInterceptor.handle(message); - assertNull("Security context still present after handler returned", - SecurityContextHolder.getContext().getAuthentication()); - } - - @Test - public void testExistingSecurityContextIsNotCleared(){ - SecurityContextHolder.setStrategyName(StackBasedSecurityContextHolderStrategy.class.getName()); - final StubSecurityContext securityContext = new StubSecurityContext(); - SecurityContextHolder.setContext(securityContext); - - StringMessage message = new StringMessage("test"); - - final MessageHandler handler = new MessageHandler() { - public Message handle(Message message) { - SecurityContext associatedContext = SecurityContextHolder.getContext(); - assertEquals("Wrong security context", securityContext, associatedContext); - return null; - } - }; - SecurityContextAssociatingHandlerInterceptor associatingInterceptor = - new SecurityContextAssociatingHandlerInterceptor(handler); - associatingInterceptor.handle(message); - assertEquals("Security context no logner set", securityContext, SecurityContextHolder.getContext()); - } - - - @SuppressWarnings("serial") - private static class StubSecurityContext implements SecurityContext { - - StubAuthentication stubAuthentication = new StubAuthentication(); - - public Authentication getAuthentication() { - return stubAuthentication; - } - - public void setAuthentication(Authentication authentication) { - } - } - - - @SuppressWarnings("serial") - private static class StubAuthentication implements Authentication { - - public GrantedAuthority[] getAuthorities() { - return null; - } - - public Object getCredentials() { - return null; - } - - public Object getDetails() { - return null; - } - - public Object getPrincipal() { - return null; - } - - public boolean isAuthenticated() { - return false; - } - - public void setAuthenticated(boolean isAuthenticated) throws IllegalArgumentException { - } - - public String getName() { - return null; - } - } - -} diff --git a/org.springframework.integration.security/src/test/java/org/springframework/integration/security/channel/SecurityContextPropagatingChannelInterceptorTests.java b/org.springframework.integration.security/src/test/java/org/springframework/integration/security/channel/SecurityContextPropagatingChannelInterceptorTests.java index d90d34032b..7af2ad286e 100644 --- a/org.springframework.integration.security/src/test/java/org/springframework/integration/security/channel/SecurityContextPropagatingChannelInterceptorTests.java +++ b/org.springframework.integration.security/src/test/java/org/springframework/integration/security/channel/SecurityContextPropagatingChannelInterceptorTests.java @@ -16,9 +16,7 @@ package org.springframework.integration.security.channel; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; +import static org.junit.Assert.*; import org.junit.After; import org.junit.Before; @@ -36,13 +34,12 @@ import org.springframework.security.context.SecurityContextHolder; * @author Jonas Partner */ public class SecurityContextPropagatingChannelInterceptorTests { - + private QueueChannel channel; private SecurityContextPropagatingChannelInterceptor securityPropogatingChannelInterceptor; - - private StubSecurityContext securityContext; + private StubSecurityContext securityContext; @Before public void setUp() { @@ -53,11 +50,10 @@ public class SecurityContextPropagatingChannelInterceptorTests { } @After - public void tearDown(){ + public void tearDown() { SecurityContextHolder.clearContext(); } - @Test public void testPropogationWhenSecurityContextExists() { this.associateContextWithThread(); @@ -65,11 +61,11 @@ public class SecurityContextPropagatingChannelInterceptorTests { this.channel.send(message); message = (StringMessage) channel.receive(0); MessageHeader header = message.getHeader(); - assertTrue("No security context attribute found in header.", - header.getAttributeNames().contains(SecurityContextUtils.SECURITY_CONTEXT_HEADER_ATTRIBUTE)); + assertTrue("No security context attribute found in header.", header.getAttributeNames().contains( + SecurityContextUtils.SECURITY_CONTEXT_HEADER_ATTRIBUTE)); SecurityContext contextFromHeader = SecurityContextUtils.getSecurityContextFromHeader(message); assertEquals("Incorrect security context in message header.", securityContext, contextFromHeader); - } + } @Test public void testHeaderNotSetWhenNoSecurityContextExists() { @@ -77,19 +73,16 @@ public class SecurityContextPropagatingChannelInterceptorTests { channel.send(message); message = (StringMessage) channel.receive(0); MessageHeader header = message.getHeader(); - assertFalse("Security context header found when no security context existed.", - header.getAttributeNames().contains(SecurityContextUtils.SECURITY_CONTEXT_HEADER_ATTRIBUTE)); + assertFalse("Security context header found when no security context existed.", header.getAttributeNames() + .contains(SecurityContextUtils.SECURITY_CONTEXT_HEADER_ATTRIBUTE)); } - - - private void associateContextWithThread(){ + private void associateContextWithThread() { SecurityContextHolder.setContext(securityContext); - } - + } @SuppressWarnings("serial") - private static class StubSecurityContext implements SecurityContext{ + private static class StubSecurityContext implements SecurityContext { private Authentication authentication = new Authentication() { @@ -113,8 +106,7 @@ public class SecurityContextPropagatingChannelInterceptorTests { return false; } - public void setAuthenticated(boolean isAuthenticated) - throws IllegalArgumentException { + public void setAuthenticated(boolean isAuthenticated) throws IllegalArgumentException { } public String getName() { diff --git a/org.springframework.integration.security/src/test/java/org/springframework/integration/security/config/SecuredChannelsParserTests-context.xml b/org.springframework.integration.security/src/test/java/org/springframework/integration/security/channel/config/SecuredChannelsParserTests-context.xml similarity index 86% rename from org.springframework.integration.security/src/test/java/org/springframework/integration/security/config/SecuredChannelsParserTests-context.xml rename to org.springframework.integration.security/src/test/java/org/springframework/integration/security/channel/config/SecuredChannelsParserTests-context.xml index 19862d8a17..d527711e00 100644 --- a/org.springframework.integration.security/src/test/java/org/springframework/integration/security/config/SecuredChannelsParserTests-context.xml +++ b/org.springframework.integration.security/src/test/java/org/springframework/integration/security/channel/config/SecuredChannelsParserTests-context.xml @@ -12,25 +12,25 @@ http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd"> - + - + adminRequiredForSend - + adminOrUserRequiredForSend - + adminRequiredForReceive - + adminOrUserRequiredForReceive - + adminForSendAndReceive diff --git a/org.springframework.integration.security/src/test/java/org/springframework/integration/security/config/SecuredChannelsParserTests.java b/org.springframework.integration.security/src/test/java/org/springframework/integration/security/channel/config/SecuredChannelsParserTests.java similarity index 96% rename from org.springframework.integration.security/src/test/java/org/springframework/integration/security/config/SecuredChannelsParserTests.java rename to org.springframework.integration.security/src/test/java/org/springframework/integration/security/channel/config/SecuredChannelsParserTests.java index df476f3542..f943debc80 100644 --- a/org.springframework.integration.security/src/test/java/org/springframework/integration/security/config/SecuredChannelsParserTests.java +++ b/org.springframework.integration.security/src/test/java/org/springframework/integration/security/channel/config/SecuredChannelsParserTests.java @@ -14,11 +14,9 @@ * limitations under the License. */ -package org.springframework.integration.security.config; +package org.springframework.integration.security.channel.config; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; +import static org.junit.Assert.*; import java.util.ArrayList; import java.util.List; diff --git a/org.springframework.integration.security/src/test/java/org/springframework/integration/security/config/SecurityPropagatingChannelsParserTests-noPropagationByDefaultContext.xml b/org.springframework.integration.security/src/test/java/org/springframework/integration/security/channel/config/SecurityPropagatingChannelsParserTests-noPropagationByDefaultContext.xml similarity index 68% rename from org.springframework.integration.security/src/test/java/org/springframework/integration/security/config/SecurityPropagatingChannelsParserTests-noPropagationByDefaultContext.xml rename to org.springframework.integration.security/src/test/java/org/springframework/integration/security/channel/config/SecurityPropagatingChannelsParserTests-noPropagationByDefaultContext.xml index 44dd6fc3e4..4f49dfec3e 100644 --- a/org.springframework.integration.security/src/test/java/org/springframework/integration/security/config/SecurityPropagatingChannelsParserTests-noPropagationByDefaultContext.xml +++ b/org.springframework.integration.security/src/test/java/org/springframework/integration/security/channel/config/SecurityPropagatingChannelsParserTests-noPropagationByDefaultContext.xml @@ -11,23 +11,11 @@ http://www.springframework.org/schema/integration-security http://www.springframework.org/schema/integration/spring-integration-security-1.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd"> - - - - - - - - adminRequiredForSend - - - - - excludedFromPropagation - - - - - + + + adminSpecial + admin.* + + \ No newline at end of file diff --git a/org.springframework.integration.security/src/test/java/org/springframework/integration/security/config/SecurityPropagatingChannelsParserTests-propagateByDefaultContext.xml b/org.springframework.integration.security/src/test/java/org/springframework/integration/security/channel/config/SecurityPropagatingChannelsParserTests-propagateByDefaultContext.xml similarity index 54% rename from org.springframework.integration.security/src/test/java/org/springframework/integration/security/config/SecurityPropagatingChannelsParserTests-propagateByDefaultContext.xml rename to org.springframework.integration.security/src/test/java/org/springframework/integration/security/channel/config/SecurityPropagatingChannelsParserTests-propagateByDefaultContext.xml index dfc3200316..fcf5cf340b 100644 --- a/org.springframework.integration.security/src/test/java/org/springframework/integration/security/config/SecurityPropagatingChannelsParserTests-propagateByDefaultContext.xml +++ b/org.springframework.integration.security/src/test/java/org/springframework/integration/security/channel/config/SecurityPropagatingChannelsParserTests-propagateByDefaultContext.xml @@ -11,32 +11,6 @@ http://www.springframework.org/schema/integration-security http://www.springframework.org/schema/integration/spring-integration-security-1.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd"> - - - - - - - - - - - - excludedFromPropagation - - - - - - includedInPropagation - - - - - - - - - + \ No newline at end of file diff --git a/org.springframework.integration.security/src/test/java/org/springframework/integration/security/config/SecurityPropagatingChannelsParserTests.java b/org.springframework.integration.security/src/test/java/org/springframework/integration/security/channel/config/SecurityPropagatingChannelsParserTests.java similarity index 69% rename from org.springframework.integration.security/src/test/java/org/springframework/integration/security/config/SecurityPropagatingChannelsParserTests.java rename to org.springframework.integration.security/src/test/java/org/springframework/integration/security/channel/config/SecurityPropagatingChannelsParserTests.java index 68dfb6425d..2507411404 100644 --- a/org.springframework.integration.security/src/test/java/org/springframework/integration/security/config/SecurityPropagatingChannelsParserTests.java +++ b/org.springframework.integration.security/src/test/java/org/springframework/integration/security/channel/config/SecurityPropagatingChannelsParserTests.java @@ -14,19 +14,16 @@ * limitations under the License. */ -package org.springframework.integration.security.config; +package org.springframework.integration.security.channel.config; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; +import static org.junit.Assert.*; import org.junit.After; import org.junit.Test; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.beans.factory.config.AutowireCapableBeanFactory; import org.springframework.context.support.ClassPathXmlApplicationContext; import org.springframework.integration.channel.MessageChannel; +import org.springframework.integration.channel.QueueChannel; import org.springframework.integration.message.StringMessage; import org.springframework.security.context.SecurityContext; import org.springframework.security.context.SecurityContextHolder; @@ -40,15 +37,6 @@ public class SecurityPropagatingChannelsParserTests { private ClassPathXmlApplicationContext applicationContext; - @Autowired - @Qualifier("propagationDefault") - MessageChannel propagationDefault; - - @Autowired - @Qualifier("excludedFromPropagation") - MessageChannel excludedFromPropagation; - - @After public void tearDown() { if (applicationContext != null) { @@ -57,34 +45,39 @@ public class SecurityPropagatingChannelsParserTests { SecurityContextHolder.clearContext(); } - @Test public void testPropagationByDefault() { loadApplicationContext(this.getClass().getSimpleName() + "-propagateByDefaultContext.xml"); + MessageChannel channel = new QueueChannel(); + applicationContext.getAutowireCapableBeanFactory().applyBeanPostProcessorsAfterInitialization(channel, + "Does not matter"); assertTrue("security context did not propagate by setting message bus level default", - channelPropagatesSecurityContext(propagationDefault)); + channelPropagatesSecurityContext(channel)); } + // @Test + // public void testNoPropagationOnExcludedChannel() { + // loadApplicationContext(this.getClass().getSimpleName() + + // "-propagateByDefaultContext.xml"); + // assertFalse("security context propagated when channel was explicitly + // excluded", + // channelPropagatesSecurityContext(excludedFromPropagation)); + // } + // @Test - public void testNoPropagationOnExcludedChannel() { - loadApplicationContext(this.getClass().getSimpleName() + "-propagateByDefaultContext.xml"); - assertFalse("security context propagated when channel was explicitly excluded", - channelPropagatesSecurityContext(excludedFromPropagation)); - } - - @Test - public void testNoPropagationWithNoDefaultPropagation() { + public void testNoPropagationWithExcludedChannel() { loadApplicationContext(this.getClass().getSimpleName() + "-noPropagationByDefaultContext.xml"); - assertFalse("security context propagated when channel default was false and no secured tag present", - channelPropagatesSecurityContext(propagationDefault)); + MessageChannel channel = new QueueChannel(); + applicationContext.getAutowireCapableBeanFactory().applyBeanPostProcessorsAfterInitialization(channel, + "adminSpecial"); + assertFalse("security context propagated when channel excluded", channelPropagatesSecurityContext(channel)); } - private boolean channelPropagatesSecurityContext(MessageChannel channel) { login("bob", "bobspassword"); channel.send(new StringMessage("testMessage")); - SecurityContext context = (SecurityContext) - channel.receive(-1).getHeader().getAttribute("SPRING_SECURITY_CONTEXT"); + SecurityContext context = (SecurityContext) channel.receive(-1).getHeader().getAttribute( + "SPRING_SECURITY_CONTEXT"); return context != null; } diff --git a/org.springframework.integration.security/src/test/java/org/springframework/integration/security/config/IncludeExcludePatternParserTests.java b/org.springframework.integration.security/src/test/java/org/springframework/integration/security/config/IncludeExcludePatternParserTests.java new file mode 100644 index 0000000000..b185ccc073 --- /dev/null +++ b/org.springframework.integration.security/src/test/java/org/springframework/integration/security/config/IncludeExcludePatternParserTests.java @@ -0,0 +1,68 @@ +/* + * 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.config; + +import static org.junit.Assert.*; + +import java.io.StringReader; + +import javax.xml.parsers.DocumentBuilderFactory; + +import org.junit.Before; +import org.junit.Test; +import org.w3c.dom.Document; +import org.w3c.dom.NodeList; +import org.xml.sax.InputSource; + +public class IncludeExcludePatternParserTests { + + IncludeExcludePatternParser patternParser; + + @Before + public void setUp() { + patternParser = new IncludeExcludePatternParser(); + } + + @Test + public void testSimpleIncludeWithIncludeByDefaultFalse() throws Exception { + NodeList nodeList = getNodeList("includeMe.*"); + OrderedIncludeExcludeList matcher = patternParser.createFromNodeList(false, nodeList); + assertTrue("Did not match expected entry includeMe", matcher.isIncluded("includeMe")); + assertFalse("Matched unexpected entry notMe", matcher.isIncluded("notMe")); + } + + @Test + public void testIncludeByDefaultTrue() throws Exception { + NodeList nodeList = getNodeList(""); + OrderedIncludeExcludeList matcher = patternParser.createFromNodeList(true, nodeList); + assertTrue("Did not match expected entry includeMe", matcher.isIncluded("anything")); + } + + @Test + public void testIncludeByDefaultTrueButExcluded() throws Exception { + NodeList nodeList = getNodeList("ex.*exShouldNotMatter"); + OrderedIncludeExcludeList matcher = patternParser.createFromNodeList(true, nodeList); + assertFalse("Matched unexpected entry exNotMe", matcher.isIncluded("exNotMe")); + assertFalse("Matched unexpected entry exShouldNotMatter", matcher.isIncluded("exShouldNotMatter")); + } + + public NodeList getNodeList(String xmlString) throws Exception { + StringReader reader = new StringReader(xmlString); + Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(new InputSource(reader)); + return doc.getDocumentElement().getChildNodes(); + } + +} diff --git a/org.springframework.integration.security/src/test/java/org/springframework/integration/security/config/JdkRegExpOrderedIncludeExcludeListTests.java b/org.springframework.integration.security/src/test/java/org/springframework/integration/security/config/JdkRegExpOrderedIncludeExcludeListTests.java index a5d2f356ee..1007fbfff6 100644 --- a/org.springframework.integration.security/src/test/java/org/springframework/integration/security/config/JdkRegExpOrderedIncludeExcludeListTests.java +++ b/org.springframework.integration.security/src/test/java/org/springframework/integration/security/config/JdkRegExpOrderedIncludeExcludeListTests.java @@ -1,19 +1,31 @@ +/* + * 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.config; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; +import static org.junit.Assert.*; import java.util.ArrayList; import java.util.List; import org.junit.Test; - /** * * @author Jonas Partner - * + * */ public class JdkRegExpOrderedIncludeExcludeListTests { @@ -39,15 +51,15 @@ public class JdkRegExpOrderedIncludeExcludeListTests { assertFalse("Unexpected match when match by default false and no patterns", matcher.isIncluded("anyoldthing")); } - @Test public void testExcludeThenIncludeWithIncludeByDefaultFalse() { - List patterns = createIncludeExcludeList(new boolean[] {false, true}, new String[] {"admin.*",".*"}); + List patterns = createIncludeExcludeList(new boolean[] { false, true }, new String[] { + "admin.*", ".*" }); JdkRegExpOrderedIncludeExcludeList matcher = new JdkRegExpOrderedIncludeExcludeList(false, patterns); - assertFalse("Unexpected match when match by default false and should have been excluded", matcher.isIncluded("adminChannel")); + assertFalse("Unexpected match when match by default false and should have been excluded", matcher + .isIncluded("adminChannel")); } - - + List createIncludeExcludeList(boolean[] includeExclude, String[] patterns) { assertEquals("flag and patterns arrays must be same length", includeExclude.length, patterns.length); diff --git a/org.springframework.integration.security/src/test/java/org/springframework/integration/security/config/SecurityTestUtil.java b/org.springframework.integration.security/src/test/java/org/springframework/integration/security/config/SecurityTestUtil.java index 02be693193..a355d0e724 100644 --- a/org.springframework.integration.security/src/test/java/org/springframework/integration/security/config/SecurityTestUtil.java +++ b/org.springframework.integration.security/src/test/java/org/springframework/integration/security/config/SecurityTestUtil.java @@ -24,20 +24,21 @@ import org.springframework.security.providers.UsernamePasswordAuthenticationToke /** * * @author Jonas Partner - * + * */ public class SecurityTestUtil { - - public static SecurityContext createContext(String username, String password, String... roles){ + + public static SecurityContext createContext(String username, String password, String... roles) { SecurityContextImpl ctxImpl = new SecurityContextImpl(); UsernamePasswordAuthenticationToken authToken; - if(roles != null && roles.length > 0){ + if (roles != null && roles.length > 0) { GrantedAuthority[] authorities = new GrantedAuthority[roles.length]; - for (int i =0; i < roles.length; i++) { + for (int i = 0; i < roles.length; i++) { authorities[i] = new GrantedAuthorityImpl(roles[i]); } - authToken = new UsernamePasswordAuthenticationToken(username,password,authorities); - } else { + authToken = new UsernamePasswordAuthenticationToken(username, password, authorities); + } + else { authToken = new UsernamePasswordAuthenticationToken(username, password); } ctxImpl.setAuthentication(authToken); diff --git a/org.springframework.integration.security/src/test/java/org/springframework/integration/security/endpoint/SecurityEndpointInterceptorTests.java b/org.springframework.integration.security/src/test/java/org/springframework/integration/security/endpoint/SecurityEndpointInterceptorTests.java new file mode 100644 index 0000000000..a0a6d8527e --- /dev/null +++ b/org.springframework.integration.security/src/test/java/org/springframework/integration/security/endpoint/SecurityEndpointInterceptorTests.java @@ -0,0 +1,142 @@ +/* + * 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.endpoint; + +import static org.easymock.EasyMock.*; +import static org.junit.Assert.assertNull; + +import org.aopalliance.intercept.MethodInvocation; +import org.junit.Test; +import org.springframework.integration.message.Message; +import org.springframework.integration.message.StringMessage; +import org.springframework.integration.security.SecurityContextUtils; +import org.springframework.integration.security.config.SecurityTestUtil; +import org.springframework.security.AccessDecisionManager; +import org.springframework.security.AccessDeniedException; +import org.springframework.security.ConfigAttributeDefinition; +import org.springframework.security.context.SecurityContext; +import org.springframework.security.context.SecurityContextHolder; + +/** + * + * @author Jonas Partner + * + */ +public class SecurityEndpointInterceptorTests { + + @Test(expected = AccessDeniedException.class) + public void testUnauthenticatedAccessToSecuredEndpointWithNullMessage() throws Throwable { + try { + Object target = new Object(); + MethodInvocation invocation = createTestMethodInvocationWithNullMessage(target); + ConfigAttributeDefinition attDefintion = new ConfigAttributeDefinition("ROLE_ADMIN"); + AccessDecisionManager adm = createMock(AccessDecisionManager.class); + adm.decide(null, target, attDefintion); + expectLastCall().andThrow(new AccessDeniedException("nope")); + + replay(invocation); + replay(adm); + + SecurityEndpointInterceptor interceptor = new SecurityEndpointInterceptor(attDefintion, adm); + interceptor.aroundInvoke(invocation); + + verify(invocation, adm); + } + finally { + assertNull("Authentication was not null after invocation threw AccessDeniedException", + SecurityContextHolder.getContext().getAuthentication()); + } + } + + @Test(expected = AccessDeniedException.class) + public void testUnauthenticatedAccessToSecuredEndpoint() throws Throwable { + try { + Object target = new Object(); + MethodInvocation invocation = createTestMethodInvocationNoSecurityHeaderInMessage(target); + ConfigAttributeDefinition attDefintion = new ConfigAttributeDefinition("ROLE_ADMIN"); + AccessDecisionManager adm = createMock(AccessDecisionManager.class); + adm.decide(null, target, attDefintion); + expectLastCall().andThrow(new AccessDeniedException("nope")); + + replay(invocation); + replay(adm); + + SecurityEndpointInterceptor interceptor = new SecurityEndpointInterceptor(attDefintion, adm); + interceptor.aroundInvoke(invocation); + + verify(invocation, adm); + } + finally { + assertNull("Authentication was not null after invocation threw AccessDeniedException", + SecurityContextHolder.getContext().getAuthentication()); + } + } + + @Test + public void testAuthenticatedAccessToSecuredEndpoint() throws Throwable { + try { + Object target = new Object(); + SecurityContext context = SecurityTestUtil.createContext("bob", "bobspassword", + new String[] { "ROLE_ADMIN" }); + MethodInvocation invocation = createTestMethodInvocation(target, context); + expect(invocation.proceed()).andReturn(null); + replay(invocation); + + ConfigAttributeDefinition attDefintion = new ConfigAttributeDefinition("ROLE_ADMIN"); + + AccessDecisionManager adm = createMock(AccessDecisionManager.class); + adm.decide(context.getAuthentication(), target, attDefintion); + expectLastCall(); + replay(adm); + + SecurityEndpointInterceptor interceptor = new SecurityEndpointInterceptor(attDefintion, adm); + interceptor.aroundInvoke(invocation); + + verify(invocation, adm); + + } + finally { + assertNull("Authentication was not null after successful invocation", SecurityContextHolder.getContext() + .getAuthentication()); + } + } + + public MethodInvocation createTestMethodInvocation(Object target, SecurityContext securityContext) { + Message message = new StringMessage("test"); + SecurityContextUtils.setSecurityContextHeader(securityContext, message); + MethodInvocation mockInvocation = createMock(MethodInvocation.class); + expect(mockInvocation.getArguments()).andReturn(new Object[] { message }); + expect(mockInvocation.getThis()).andReturn(target); + return mockInvocation; + } + + public MethodInvocation createTestMethodInvocationNoSecurityHeaderInMessage(Object target) { + Message message = new StringMessage("test"); + MethodInvocation mockInvocation = createMock(MethodInvocation.class); + expect(mockInvocation.getArguments()).andReturn(new Object[] { message }); + expect(mockInvocation.getThis()).andReturn(target); + return mockInvocation; + } + + public MethodInvocation createTestMethodInvocationWithNullMessage(Object target) { + MethodInvocation mockInvocation = createMock(MethodInvocation.class); + expect(mockInvocation.getArguments()).andReturn(new Object[] { null }); + expect(mockInvocation.getThis()).andReturn(target); + return mockInvocation; + } + +} diff --git a/org.springframework.integration.security/src/test/java/org/springframework/integration/security/target/TargetSecuringAdvisorTests.java b/org.springframework.integration.security/src/test/java/org/springframework/integration/security/target/TargetSecuringAdvisorTests.java deleted file mode 100644 index f171dce4c5..0000000000 --- a/org.springframework.integration.security/src/test/java/org/springframework/integration/security/target/TargetSecuringAdvisorTests.java +++ /dev/null @@ -1,131 +0,0 @@ -/* - * 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.target; - -import org.junit.Test; -import org.springframework.aop.framework.ProxyFactory; -import org.springframework.integration.message.BlockingTarget; -import org.springframework.integration.message.Message; -import org.springframework.integration.message.StringMessage; -import org.springframework.integration.message.Target; -import org.springframework.integration.security.target.TargetSecuringAdvisor; -import org.springframework.security.AccessDecisionManager; -import org.springframework.security.AccessDeniedException; -import org.springframework.security.Authentication; -import org.springframework.security.ConfigAttribute; -import org.springframework.security.ConfigAttributeDefinition; -import org.springframework.security.InsufficientAuthenticationException; - -/** - * - * @author Jonas Partner - * - */ -public class TargetSecuringAdvisorTests { - - public Object proxy(Object target, TargetSecuringAdvisor advisor) { - ProxyFactory proxyFactory = new ProxyFactory(target); - proxyFactory.addAdvisor(advisor); - - return proxyFactory.getProxy(); - - } - - @Test(expected = AccessDeniedException.class) - public void testTargetSendAdvised() { - TargetSecuringAdvisor advisor = new TargetSecuringAdvisor(new AlwaysDenyAccessDecisionManager(), "ROLE_ADMIN"); - Target target = (Target) proxy(new TestTarget(), advisor); - target.send(new StringMessage("test")); - } - - @Test(expected = AccessDeniedException.class) - public void testBlockingTargetSendAdvised() { - TargetSecuringAdvisor advisor = new TargetSecuringAdvisor(new AlwaysDenyAccessDecisionManager(), "ROLE_ADMIN"); - Target target = (Target) proxy(new BlockingTestTarget(), advisor); - target.send(new StringMessage("test")); - } - - @Test(expected = AccessDeniedException.class) - public void testBlockingTargetSendWithTimeoutAdvised() { - TargetSecuringAdvisor advisor = new TargetSecuringAdvisor(new AlwaysDenyAccessDecisionManager(), "ROLE_ADMIN"); - BlockingTarget target = (BlockingTarget) proxy(new BlockingTestTarget(), advisor); - target.send(new StringMessage("test"), 10l); - } - - @Test - public void testTargetSendNotFromTargetInterface() { - TargetSecuringAdvisor advisor = new TargetSecuringAdvisor(new AlwaysDenyAccessDecisionManager(), "ROLE_ADMIN"); - OtherSend target = (OtherSend) proxy(new TestTarget(), advisor); - target.send(10l); - } - - static interface OtherSend { - - public void send(long l); - } - - static class AlwaysDenyAccessDecisionManager implements AccessDecisionManager { - - public void decide(Authentication authentication, Object object, ConfigAttributeDefinition config) - throws AccessDeniedException, InsufficientAuthenticationException { - throw new AccessDeniedException("dave"); - } - - public boolean supports(ConfigAttribute attribute) { - return true; - } - - @SuppressWarnings("unchecked") - public boolean supports(Class clazz) { - return true; - } - - } - - static class TestTarget implements Target, OtherSend { - - boolean invoked; - - public boolean send(Message message) { - invoked = true; - return false; - } - - public void send(long a) { - - } - - } - - static class BlockingTestTarget implements BlockingTarget { - - boolean invoked; - - public boolean send(Message message) { - invoked = true; - return false; - } - - public void send() { - } - - public boolean send(Message message, long timeout) { - return false; - } - - } - -} diff --git a/org.springframework.integration.security/src/test/java/org/springframework/integration/security/target/TargetSecuringInterceptorTests.java b/org.springframework.integration.security/src/test/java/org/springframework/integration/security/target/TargetSecuringInterceptorTests.java deleted file mode 100644 index 3112986173..0000000000 --- a/org.springframework.integration.security/src/test/java/org/springframework/integration/security/target/TargetSecuringInterceptorTests.java +++ /dev/null @@ -1,110 +0,0 @@ -/* - * 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.target; - -import java.util.ArrayList; -import java.util.List; - -import org.junit.Before; -import org.junit.Test; -import org.springframework.aop.framework.ProxyFactory; -import org.springframework.integration.message.Message; -import org.springframework.integration.message.StringMessage; -import org.springframework.integration.message.Target; -import org.springframework.integration.security.SecurityContextUtils; -import org.springframework.integration.security.config.SecurityTestUtil; -import org.springframework.integration.security.target.TargetSecuringInterceptor; -import org.springframework.security.AccessDecisionManager; -import org.springframework.security.AccessDeniedException; -import org.springframework.security.ConfigAttributeDefinition; -import org.springframework.security.context.SecurityContext; -import org.springframework.security.vote.AccessDecisionVoter; -import org.springframework.security.vote.AuthenticatedVoter; -import org.springframework.security.vote.RoleVoter; -import org.springframework.security.vote.UnanimousBased; -import org.springframework.util.StringUtils; - -/** - * - * @author Jonas Partner - * - */ -public class TargetSecuringInterceptorTests { - - - UnanimousBased accessDecisionManager; - - @Before - public void setup(){ - accessDecisionManager = new UnanimousBased(); - List voterList = new ArrayList(); - voterList.add(new AuthenticatedVoter()); - voterList.add(new RoleVoter()); - accessDecisionManager.setDecisionVoters(voterList); - } - - - - public Object createProxy(Object target,String securityAttributes, AccessDecisionManager accessDecisionManager){ - TargetSecuringInterceptor interceptor = new TargetSecuringInterceptor(new ConfigAttributeDefinition(StringUtils.tokenizeToStringArray(securityAttributes,",")), accessDecisionManager); - ProxyFactory factory = new ProxyFactory(target); - factory.addAdvice(interceptor); - return factory.getProxy(); - } - - @Test(expected=AccessDeniedException.class) - public void testAccessDenied(){ - Target proxiedTarget = (Target) createProxy(new TestTarget(), "IS_AUTHENTICATED_FULLY, ROLE_ADMIN", accessDecisionManager); - SecurityContext sctx = SecurityTestUtil.createContext("bob", "password", "IS_AUTHENTICATED_ANONYMOUSLY", "ROLE_USER"); - StringMessage message = new StringMessage("test"); - SecurityContextUtils.setSecurityContextHeader(sctx, message); - proxiedTarget.send(message); - } - - @Test - public void testAccessGranted(){ - Target proxiedTarget = (Target) createProxy(new TestTarget(), "IS_AUTHENTICATED_FULLY, ROLE_ADMIN", accessDecisionManager); - SecurityContext sctx = SecurityTestUtil.createContext("bob", "password", "IS_AUTHENTICATED_ANONYMOUSLY", "ROLE_USER", "ROLE_ADMIN"); - StringMessage message = new StringMessage("test"); - SecurityContextUtils.setSecurityContextHeader(sctx, message); - proxiedTarget.send(message); - } - - - @Test(expected=RuntimeException.class) - public void testNotAuthenticated(){ - Target proxiedTarget = (Target) createProxy(new TestTarget(), "IS_AUTHENTICATED_FULLY, ROLE_ADMIN", accessDecisionManager); - StringMessage message = new StringMessage("test"); - proxiedTarget.send(message); - } - - - static class TestTarget implements Target{ - - boolean invoked; - - public boolean send(Message message) { - invoked = true; - return false; - } - - public void send(long l) { - // TODO Auto-generated method stub - - } - } - -}