Closed spring-operator closed 9 years ago
Artem Bilan commented
It was the first strategy. The second strategy is: to produce some custom header element inside header-enricher like correlation-id or reply-channel with some attribute fromSecurityContextHolder=true/false. Plus other abilities for header-enricher.
Gary Russell commented
Further to the conversation on #7009, there is clearly interest in propagating the security context in SI apps that use async handoffs. But, as Artem pointed out on the other JIRA, there could be undesirable side-effects of doing it unconditionally in the framework.
Therefore it would need to use an "opt-in" policy - such as an attribute on the \
There are other things to consider too...
I added Rob to the watch list in case he has any pearls of wisdom to add.
Mark Fisher commented
I added Luke as a watcher also since he and I discussed this way back in 2008, and at that time he raised enough issues to scare me from going down this path at all.
Rob Winch commented
I spoke with Gary a bit offline and it appears this is already being looked into, but one option might be to try to leverage the Async support that will be available in Spring Security 3.2. For those not familiar, please refer to the blog post about the support introduced in Spring Security 3.2 M1.
Damien Hollis commented
Has there been any progress on this issue? We are using spring integration in our project and we are keen to have security propagated across async calls - in our particular case we are using jms channels, so specific support for that use case would be appreciated. I'm happy to contribute (depending on how much work is involved) if somebody wants to point me in the right direction.
Artem Bilan commented
Hi, Damien!
Thank you for attention to this.
We still decide to keep out of this implementation in the framework.
What is a problem to use in your case suggested workaround in face of <channel-interceptor>
?
Damien Hollis commented
Hi Artem,
The problem with \
Is there a solution to this problem that I'm not aware of?
Regards, Damien
Artem Bilan commented
Well, what you need is here:
<channel-interceptor>
to propagate SecurityContext
for non-direct channelsTaskExecutor
for Executor Channels with DelegatingSecurityContextExecutor
from Spring Security: https://spring.io/blog/2012/12/17/spring-security-3-2-m1-highlights-servlet-3-api-supportSecurityContextCleanInterceptor
, because <poller>
has the advice-chain
attrbiute:public class SecurityContextCleanInterceptor implements MethodInterceptor {
public Object invoke(MethodInvocation invocation) throws Throwable {
try {
return invocation.proceed();
}
finally {
SecurityContextHolder.clearContext();
}
}
}
Is it reasonable for you?
Damien Hollis commented
Hi Artem,
I think your suggests would work for Executor and Queue Channels. However, I couldn't see how to make either work for a Jms Channel. So instead I implemented a MessageHandler and configured it at the beginning of a chain of handlers:
public class ContextPropagatingMessageHandler extends AbstractMessageHandler implements MessageProducer {
private final MessagingTemplate messagingTemplate = new MessagingTemplate();
private MessageChannel outputChannel;
@Override
public void setOutputChannel(MessageChannel outputChannel) {
this.outputChannel = outputChannel;
}
@Override
protected void handleMessageInternal(Message<?> message) throws Exception {
SecurityContext securityContext = (SecurityContext) message.getHeaders().get(ContextPropagatingChannelInterceptor.SECURITY_CONTEXT_KEY);
if (securityContext == null) {
sendMessage(message);
}
else {
try {
SecurityContextHolder.setContext(securityContext);
sendMessage(message);
}
finally {
SecurityContextHolder.clearContext();
}
}
}
private void sendMessage(Message<?> message) {
messagingTemplate.send(outputChannel, message);
}
}
Can you recommend a better solution?
Artem Bilan commented
Hi, Damien!
Sorry for delay.
However this issue is very specific and has a lot of places for the imagination ;)
Instead of coding a MessageHandler
you can build some gereric Advice
and use it withing <request-handler-advice-chain>
: http://docs.spring.io/spring-integration/docs/2.2.6.RELEASE/reference/html/messaging-endpoints-chapter.html#message-handler-advice-chain
And, as you noticed, provided solution isn't robust and it doesn't cover all use-cases. There is still a window for involving an end-user to achieve the real solution.
That's why I said that it shouldn't be provided by framework by default.
SecurityContext
is very simple and even Serializable
object and Srping Security provides enough tools to work with it in the application with Spring infrastructure.
Thanks
Christopher Smith commented
I would like to voice support for built-in (or at least packaged-in-an-extension) support for propagating the SecurityContext
, as is found in Spring Remoting. While Spring Security does make the tools available to implement propagation, it's a fairly cookie-cutter requirement, and both DRY and security principles suggest it should be handled in a general-purpose library.
Even if there is more than one protocol for how to propagate the context (and I can only think of the one where the context follows the message), it seems that they should be limited enough to be enumerated and supported in-library. What other propagation protocol(s) do you think users would want?
Christopher Smith commented
For whatever it's worth, I've written an example project demonstrating the behavior of thread-local data under various combinations of channel types and synchronous/asynchronous invocation. I will note that as a client of a gateway interface, the differing behavior based on a runtime configuration option is surprising in a bad way, and a policy of "all information needs to be written into the API" without some sort of magic summoning-from-the-context like Spring MVC does with controller invocations means that every gateway interface needing security information will have to have its own wrapper that does nothing but propagate the context.
Dave Syer commented
I think the fact that it is boilerplate tells me we should have something in the framework. The main concern for me is the clean up. You want to be double sure that background threads do not have ThreadLocals with SecurityContext in them after a message has been processed.
Artem Bilan commented
Anyone who is interested, please, take a look to the PR on the matter: https://github.com/spring-projects/spring-integration/pull/1493
Artem Bilan opened INT-2166 and commented
There are a lot of cases when it is necessary to use the SecurityContext in async mesage flow inside Web application. The principal is appeared in HttpRequest from springSecurityFilterChain and stored in the ThreadLocal holder. So, at first, I propose to add supoprt of some global ChannelInterceptor which can propagetes that securityContext to async mesasge flow. This is my solution. Sorry for Groovy code.
In this case the end-programmer can use
As well as always in any place of his application.
Issue Links:
7009 SecurityContext is not propagated by asynchronous endpoints
("is duplicated by")
Referenced from: pull request https://github.com/spring-projects/spring-integration/pull/1493
2 votes, 10 watchers