interceptor for securing endpoints based on new endpoint interception model
namespace support to follow
This commit is contained in:
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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<String> processPatterns(NodeList patternList) {
|
||||
@@ -85,19 +83,6 @@ public class SecuredChannelsParser extends AbstractSingleBeanDefinitionParser {
|
||||
patterns.add(patternElement.getTextContent());
|
||||
}
|
||||
return patterns;
|
||||
|
||||
}
|
||||
|
||||
protected void setPropagation(boolean propagation, List<String> 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,
|
||||
@@ -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<Pattern> channelsToInclude = new ArrayList<Pattern>();
|
||||
private final OrderedIncludeExcludeList includeExcludeList;
|
||||
|
||||
private List<Pattern> channelsToExclude = new ArrayList<Pattern>();
|
||||
|
||||
public boolean isPropagateByDefault() {
|
||||
return this.propagateByDefault;
|
||||
}
|
||||
|
||||
public void setPropagateByDefault(boolean propagateByDefault) {
|
||||
this.propagateByDefault = propagateByDefault;
|
||||
}
|
||||
|
||||
public List<Pattern> getChannelsToInclude() {
|
||||
return this.channelsToInclude;
|
||||
}
|
||||
|
||||
public void setChannelsToInclude(List<Pattern> channelsToInclude) {
|
||||
this.channelsToInclude = channelsToInclude;
|
||||
}
|
||||
|
||||
public List<Pattern> getChannelsToExclude() {
|
||||
return this.channelsToExclude;
|
||||
}
|
||||
|
||||
public void setChannelsToExclude(List<Pattern> 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<Pattern> patterns, String str) {
|
||||
for (Pattern pattern : patterns) {
|
||||
if (pattern.matcher(str).matches()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -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<IncludeExcludePattern> patterns = new ArrayList<IncludeExcludePattern>();
|
||||
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);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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.
|
||||
|
||||
@@ -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<PatternHolder> patternHolders;
|
||||
|
||||
public JdkRegExpOrderedIncludeExcludeList(List<IncludeExcludePattern> patterns){
|
||||
|
||||
public JdkRegExpOrderedIncludeExcludeList(List<IncludeExcludePattern> patterns) {
|
||||
this(true, patterns);
|
||||
}
|
||||
|
||||
|
||||
public JdkRegExpOrderedIncludeExcludeList(boolean includeByDefault, List<IncludeExcludePattern> patterns) {
|
||||
super();
|
||||
this.includeByDefault = includeByDefault;
|
||||
List<PatternHolder> patternHolders = new ArrayList<PatternHolder>();
|
||||
for(int i = 0 ; i <patterns.size(); i++){
|
||||
patternHolders.add(new PatternHolder(Pattern.compile(patterns.get(i).getPattern()), patterns.get(i)) );
|
||||
for (int i = 0; i < patterns.size(); i++) {
|
||||
patternHolders.add(new PatternHolder(Pattern.compile(patterns.get(i).getPattern()), patterns.get(i)));
|
||||
}
|
||||
this.patternHolders = Collections.unmodifiableList(patternHolders);
|
||||
}
|
||||
|
||||
public boolean isIncluded(String name) {
|
||||
for(int i = 0; i < patternHolders.size(); i++){
|
||||
if(patternHolders.get(i).compiledPattern.matcher(name).matches()){
|
||||
for (int i = 0; i < patternHolders.size(); i++) {
|
||||
if (patternHolders.get(i).compiledPattern.matcher(name).matches()) {
|
||||
return (patternHolders.get(i).includeExcludePattern.isIncludePattern());
|
||||
}
|
||||
}
|
||||
return includeByDefault;
|
||||
}
|
||||
|
||||
private static class PatternHolder{
|
||||
|
||||
|
||||
private static class PatternHolder {
|
||||
|
||||
private final Pattern compiledPattern;
|
||||
|
||||
|
||||
private final IncludeExcludePattern includeExcludePattern;
|
||||
|
||||
public PatternHolder(Pattern compiledPattern, IncludeExcludePattern includeExcludePattern) {
|
||||
@@ -46,11 +62,6 @@ public class JdkRegExpOrderedIncludeExcludeList implements OrderedIncludeExclude
|
||||
this.includeExcludePattern = includeExcludePattern;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
|
||||
@@ -1,93 +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.config;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
import org.springframework.beans.factory.config.RuntimeBeanNameReference;
|
||||
import org.springframework.beans.factory.parsing.BeanComponentDefinition;
|
||||
import org.springframework.beans.factory.support.RootBeanDefinition;
|
||||
import org.springframework.beans.factory.xml.ParserContext;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
|
||||
/**
|
||||
* Helper to configure the per {@link ApplicationContext}
|
||||
* {@link SecurityPropagatingBeanPostProcessor} which determines
|
||||
* {@link SecurityContext} propagation.
|
||||
*
|
||||
* @author Jonas Partner
|
||||
*/
|
||||
public class SecurityPropagatingBeanPostProcessorDefinitionHelper {
|
||||
|
||||
private static final String CHANNELS_TO_INCLUDE = "channelsToInclude";
|
||||
|
||||
private static final String CHANNELS_TO_EXCLUDE = "channelsToExclude";
|
||||
|
||||
private static final String PROPAGATE_BY_DEFAULT = "propagateByDefault";
|
||||
|
||||
public static void setPropagationDefault(boolean valueForPropagationDefault, ParserContext context) {
|
||||
BeanDefinition beanDefintion = getOrCreateSecurityPropagatingBeanPostProcessor(context);
|
||||
beanDefintion.getPropertyValues().addPropertyValue(PROPAGATE_BY_DEFAULT,
|
||||
Boolean.valueOf(valueForPropagationDefault));
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static void addToExcludeChannelList(String channelName, ParserContext context) {
|
||||
BeanDefinition beanDefintion = getOrCreateSecurityPropagatingBeanPostProcessor(context);
|
||||
List channelsToExclude;
|
||||
if (beanDefintion.getPropertyValues().contains(CHANNELS_TO_EXCLUDE)) {
|
||||
channelsToExclude = (List) beanDefintion.getPropertyValues().getPropertyValue(CHANNELS_TO_EXCLUDE)
|
||||
.getValue();
|
||||
}
|
||||
else {
|
||||
channelsToExclude = new ArrayList<RuntimeBeanNameReference>();
|
||||
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<RuntimeBeanNameReference>();
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -24,7 +24,6 @@
|
||||
<xsd:attribute name="receive-access" type="xsd:string" />
|
||||
<xsd:attribute name="send-access" type="xsd:string" />
|
||||
<xsd:attribute name="access-decision-manager" type="xsd:string" default="accessDecisionManager"/>
|
||||
<xsd:attribute name="propagate" type="xsd:boolean" default="true" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
|
||||
@@ -49,14 +48,26 @@
|
||||
|
||||
<xsd:element name="security-propagating-channels">
|
||||
<xsd:complexType>
|
||||
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
Defines a bean post processor which propagates the
|
||||
security context.
|
||||
security context by registering interceptors with channels.
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
<xsd:attribute name="propagate" type="xsd:boolean" default="true" />
|
||||
<xsd:sequence>
|
||||
<xsd:element name="propagation-patterns" type="propagationPatternType" maxOccurs="1" minOccurs="0"/>
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="propagate-by-default" type="xsd:boolean" default="true" />
|
||||
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
|
||||
<xsd:complexType name="propagationPatternType">
|
||||
<xsd:choice maxOccurs="unbounded" minOccurs="0">
|
||||
<xsd:element name="includePattern" type="xsd:string"/>
|
||||
<xsd:element name="excludePattern" type="xsd:string"/>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
|
||||
</xsd:schema>
|
||||
@@ -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) {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -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) {
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
Reference in New Issue
Block a user