I have some perplexity about the SecurityContext propagation in Spring Integration.
Here is the point of the documentation:
http://docs.spring.io/spring-integration/reference/htmlsingle/#security-context-propagation
My perplexity are the following:
(1) To be sure that our interaction with the application is secure,
according to its security system rules, we should supply some security
context with an authentication (principal) object. The Spring
Security project provides a flexible, canonical mechanism to
authenticate our application clients over HTTP, WebSocket or SOAP
protocols (as can be done for any other integration protocol with a
simple Spring Security extension) and it provides a SecurityContext
for further authorization checks on the application objects, such as
message channels. By default, the SecurityContext is tied with the
current Thread's execution state using the
(ThreadLocalSecurityContextHolderStrategy). It is accessed by an AOP
interceptor on secured methods to check if that principal of the
invocation has sufficent permissions to call that method, for example.
This works well with the current thread, but often, processing logic
can be performed on another thread or even on several threads, or on
to some external system(s).
This means that the SecurityContext (normally) is accessible only for the current Thread. Right?
So, how to make it accessible for another thread of another application (integrated with Spring Integration) ?
(2) Standard thread-bound behavior is easy to configure if our application is built on the Spring Integration components and its
message channels. In this case, the secured objects may be any
service activator or transformer, secured with a
MethodSecurityInterceptor in their
(see Section 8.8, “Adding Behavior to Endpoints”) or even
MessageChannel (see Section D.2, “Securing channels” above). When
using DirectChannel communication, the SecurityContext is available
automatically, because the downstream flow runs on the current thread.
But in case of the QueueChannel, ExecutorChannel and
PublishSubscribeChannel with an Executor, messages are transferred
from one thread to another (or several) by the nature of those
channels. In order to support such scenarios, we can either transfer
an Authentication object within the message headers and extract and
authenticate it on the other side before secured object access.
Or, we can propagate the SecurityContext to the thread receiving the
transferred message.
This means that we have to extract the Principal manually? If yes, how?
Or it's enough to use the propagation aspect, from 4.2 version?
(3) Starting with version 4.2 SecurityContext propagation has been
introduced. It is implemented as a
SecurityContextPropagationChannelInterceptor, which can simply be
added to any MessageChannel or configured as a
#GlobalChannelInterceptor. The logic of this interceptor is based on
the SecurityContext extraction from the current thread from the
preSend() method, and its populating to another thread from the
postReceive() (beforeHandle()) method. Actually, this interceptor
is an extension of the more generic
ThreadStatePropagationChannelInterceptor, which wraps the
message-to-send together with the state-to-propagate in an internal
Message extension - MessageWithThreadState, - on one side and
extracts the original message back and state-to-propagate on another.
The ThreadStatePropagationChannelInterceptor can be extended for any
context propagation use-case and
SecurityContextPropagationChannelInterceptor is a good sample on the
matter.
"Starting with version 4.2 SecurityContext propagation has been introduced." => Ok, very well.
But: "It is implemented as a SecurityContextPropagationChannelInterceptor, which can simply be added to any MessageChannel or configured as a #GlobalChannelInterceptor."
What does it mean? I have to implement an interceptor that extends "SecurityContextPropagationChannelInterceptor" ?
What I have to "add" in my <int:channel> configuration?
And if I use <int:channel-interceptor> (the same of #GlobalChannelInterceptor), it's different from using <int:interceptors> ?
Other perplexity:
"The logic of this interceptor is based on the SecurityContext extraction from the current thread from the preSend() method, and its populating to another thread from the postReceive()
(beforeHandle()) method."
But why there are a "obtainPropagatingContext" method and a "populatePropagatedContext" method in the SecurityContextPropagationChannelInterceptor class?
Where is made the propagation? In the preSend() / postReceive() methods, or in those two methods?
Furthermore, I tried to propagate the SecurityContext to an external application, without success...
Any explanations about this argument would be appreciated.
You have a lot of questions here, but let me try to answer to them.
What does it mean? I have to implement an interceptor that extends "SecurityContextPropagationChannelInterceptor" ?
No, there is such an interceptor in the Framework out-of-the-box. What you have to do to understand how to add interceptor to MessageChannel: http://docs.spring.io/spring-integration/reference/html/messaging-channels-section.html#channel-configuration-interceptors.
Or like this:
#Bean
#GlobalChannelInterceptor(patterns = {
"#{'queueChannel'}",
"${security.channel:executorChannel}",
"publishSubscribeChannel" })
public ChannelInterceptor securityContextPropagationInterceptor() {
return new SecurityContextPropagationChannelInterceptor();
}
See their JavaDocs for more information.
But why there are a "obtainPropagatingContext" method and a "populatePropagatedContext" method in the SecurityContextPropagationChannelInterceptor class?
SecurityContextPropagationChannelInterceptor extends ThreadStatePropagationChannelInterceptor<Authentication> , where obtainPropagatingContext and populatePropagatedContext are just generic method to extract some current State in the preSend() (on Thread) and provide that State for population/manipulation in the postReceive(), which may happen in the different Thread.
Yes, SecurityContext is thread-bound in Spring Security and the logic to be sure that we can perform a secured function is fully based on the ThreadLocal variable. That's why we have to transfer it that way. The "propagation" is a process not state.
Not sure what you mean about "external application", but there is only one mechanism to do that: send credentials together with the request to that application.
Related
In the Jersey documentation, Example 16.2 shows an example of injecting a SecurityContext into a Jersey resource singleton.
Surely the docs are correct, and the example given is indeed thread safe.
I suspect that the injection of the SecurityContext happens exactly once, and when getUserPrincipal() is called, perhaps it picks up user data from some structure that is attached to the thread itself (maybe a ThreadLocal object?). That's the only way I can see that the correct user info be served to the end user when there are a ton of threads competing.
Can anyone confirm this behavior, or otherwise explain the thread safety of the Jersey example?
Dynamic Proxies are used with a ThrealLocal backing. This is kinda explained in the JAX-RS spec, in regards to some request scoped injectable objects (See this post for spec quote)
I suspect that the injection of the SecurityContext happens exactly once
Yes this is true, but what's injected is actually a proxy. You can print out the class name and you will see that it is actually a Proxy. The first link in this post explains how it works. When you call methods on the proxy, it delegate the calls to the thread local security context.
See also:
Dynamic Proxies and Dependency Injection.
I have an application exporting web services, with a configured Spring Security SecurityFilterChain (with SecurityContextPersistenceFilter among others, which is required for the rest).
My application also uses Spring Security to secure method invocations.
I have following error when method security is triggered:
org.springframework.security.authentication.AuthenticationCredentialsNotFoundException: An Authentication object was not found in the SecurityContext
The 2nd part requires an Authentication in SecurityContextHolder as showed in org.springframework.security.access.intercept.AbstractSecurityInterceptor (line 195):
SecurityContextHolder.getContext().getAuthentication();
But, SecurityContextPersistenceFilter removes it before method invocation is triggered, as shown in
org.springframework.security.web.context.SecurityContextPersistenceFilter (line 84)
SecurityContextHolder.clearContext();
What can I do to have this object in SecurityContextHolder when method invocation is triggered?
Thank you in advance.
I'm using Spring Security 3.0.8-RELEASE
SecurityContextHolder.clearContext() will be called only after request processing completion. So normally all your application logic code will be executed before this line, and there is no problem at all. But the problem may be present if you execute some new thread in your code (by default security context will be not propogated). If this is your case then you can try to force context propogation to child thread. If you use only one thread then make sure that all your code is covered by spring security filter chain (may be you have some custom filter that executed around spring security filter chain?).
OK, my application is placed over Apache CXF DOSGi 1.4 to generate REST endpoints. Apache CXF interceptors cause an unexpected behaviour and SecurityContextHolder.clearContext() is called before finishing the request processing.
More information about this bug can be found here.
I am new to spring and want to implement long polling for a website to display admin message immediately when it becomes available to all clients,i searched google for hours and could only find out deferredresult(spring 3.2) can be used to implement it.my question is how i can achieve long polling with deferredresult, I would appreciate it if anyone could refer me to such a tutorial.
Another option is to use AsyncContext. This will keep the initial GET request "open" and enable you to send multiple messages as part of the response, unlike DeferredResult which allows to send only ONE response message. Here is a good-link that explains how !
Straight from the horses mouth.
You have two basic options: Option 1 is a Callable
, where the Callable returns the String view name (you may also be able to use #ResponseBody or some of the other normal Spring return types like ModelAndView, but I have never investigated that).
Option two is to return DeferredResult, which is like Callable. except you can pass that off to a separate thread and fill in the results there. Again, not sure if you can return a ModelAndView or use #ResponseBody to return XML/JSON, but I am sure you can.
Short background about DeferredResult:
Your controller is eventually a function executed by the servlet container (for that matter, let's assume that the server container is Tomcat) worker thread. Your service flow start with Tomcat and ends with Tomcat. Tomcat gets the request from the client, holds the connection, and eventually returns a response to the client. Your code (controller or servlet) is somewhere in the middle.
Consider this flow:
Tomcat get client request.
Tomcat executes your controller.
Release Tomcat thread but keep the client connection (don't return response) and run heavy processing on different thread.
When your heavy processing complete, update Tomcat with its response and return it to the client (by Tomcat).
Because the servlet (your code) and the servlet container (Tomcat) are different entities, then to allow this flow (releasing tomcat thread but keep the client connection) we need to have this support in their contract, the package javax.servlet, which introduced in Servlet 3.0 . Spring MVC use this new Servlet 3.0 capability when the return value of the controller is DeferredResult or Callable, although they are two different things. Callable is an interface that is part of java.util, and it is an improvement for the Runnable interface. DeferredResult is a class designed by Spring to allow more options (that I will describe) for asynchronous request processing in Spring MVC, and this class just holds the result (as implied by its name) while your Callable implementation holds the async code. So it means you can use both in your controller, run your async code with Callable and set the result in DeferredResult, which will be the controller return value. So what do you get by using DeferredResult as the return value instead of Callable? DeferredResult has built-in callbacks like onError, onTimeout, and onCompletion. It makes error handling very easy. In addition, as it is just the result container, you can choose any thread (or thread pool) to run on your async code. With Callable, you don't have this choice.
Here you can find a simple working examples I created with both options, Callable and DeferredResult.
In my spring-3 application I have an AuthenticationInterceptor (which is basically an interceptor) that checks for the privileges for a user. I am using a Spring's MultipartResolver to try an upload a file to the server.
The problem that I now face is that I wish to perform different actions based on user privileges, in case of a MaxUploadSizeExceededException.
However I see that this exception is occurring at the DispatcherServlet level and is caught by HandlerExceptionResolver
I want to be able to call my AuthenticationInterceptor before any of this happens?
Is there a straightforward way.
The problem is that the exception occurs BEFORE the request is dispatched to a controller and because of that, your interceptor also never fires. I guess you have that part figured out already.
Want to get around that...
For starters, I would move the authentication mechanism out IN FRONT of the servlet by using servlet filters. This being said, it makes little or no sense to roll your own solution in that space when a great product like Spring Security can do that for you.
Once you transition to Spring Security (or similar), the user's SecurityContext (roles, permissions, etc.) will have been resolved by the time the exception occurs and is caught.
Now, if I'm reading your question correctly, it seems you might like to respond to the exception differently based on the user's roles, permissions, etc. That should be possible at this point. You'd implement a custom HandlerExceptionResolver that inspects the SecurityContext to see if the user has a certain role or permission and then respond accordingly.
Hope that helps!
There are two basic ways to handle doing something in-stream before the Handler code gets called:
Implement the HandlerInterceptor interface, and code the code you want to run in the preHandle method
Create an Aspect using #Aspect and configure a pointcut to run #Before the method call
In either case, you could check the logged-in user's Roles using SecurityContextHolder.getContext().getAuthentication().getAuthorities() and then decide what to do based on Role membership.
HandlerInterceptors in Spring can now be configured to be invoked only on certain URLs using <mvc:interceptors>.
Servlet Filters can achieve same functionality (logging, security etc). So which one should be used?
I think with Interceptors, one can use ModelAndView object to work with Models so it has more advantages. Can anyone draw out scenarios where Filters or Interceptors have advantages over the other?
The org.springframework.web.servlet.HanderInterceptor Interface JavaDoc itself has a two paragraphs that discuss this question:
HandlerInterceptor is basically similar to a Servlet 2.3 Filter, but
in contrast to the latter it just allows custom pre-processing with
the option of prohibiting the execution of the handler itself, and
custom post-processing. Filters are more powerful, for example they
allow for exchanging the request and response objects that are handed
down the chain. Note that a filter gets configured in web.xml, a
HandlerInterceptor in the application context.
As a basic guideline, fine-grained handler-related preprocessing tasks
are candidates for HandlerInterceptor implementations, especially
factored-out common handler code and authorization checks. On the
other hand, a Filter is well-suited for request content and view
content handling, like multipart forms and GZIP compression. This
typically shows when one needs to map the filter to certain content
types (e.g. images), or to all requests.
Spring Handler interceptors allow you to hook into more parts of the request lifecycle, and get access to more information in the process. They're often more intimately coupled to the request/response cycle than filters.
Filters are more suitable when treating your request/response as a black box system. They'll work regardless of how the servlet is implemented.
If you're using Spring MVC, there's little reason to write new logic as a servlet filter. Everything filters can do, interceptors can do more easily and more elegantly.
Remember also, servlet filters have been around for much longer than interceptors.
With a Spring interceptor, you have access to the Handler which may be useful. Also, with a Spring interceptor, you have access to execute logic before the view renders and after the view is rendered.
Servlet Filter:
A filter as the name suggests is a Java class executed by the servlet container for each incoming http request and for each http response. This way, is possible to manage HTTP incoming requests before them reach the resource, such as a JSP page, a servlet or a simple static page; in the same way is possible to manage HTTP outbound response after resource execution.
This behaviour allow to implement common functionality reused in many different contexts.
As shown in the figure above, the filter runs in the web container so its definition will also be contained in the web.xml file.
The filter include three main methods:
init: Executed to initialize filter using init-param element in
filter definition.
doFilter: Executed for all HTTP incoming request that satisfy
"url-pattern".
destroy: Release resources used by the filter.
Interceptor:
Spring Interceptors are similar to Servlet Filters but they acts in Spring Context so are many powerful to manage HTTP Request and Response but they can implement more sofisticated behaviour because can access to all Spring context.
The Spring interceptor are execute in SpringMVC context so they have be defined in rest-servlet.xml file:
The interceptor include three main methods:
preHandle: Executed before the execution of the target resource.
afterCompletion: Executed after the execution of the target resource
(after rendering the view).
postHandle: Intercept the execution of a handler.