Shiro documentation says,
"Shiro acquires Subject data based on the currently executing Thread via its own framework integration code, and this is the preferred way to use Shiro"
If Shiro is getting subject from currently executing thread and Netty handles more than 1 requests using 1 thread. So, how get subject method will return subject information for a given request? And if Shiro is not handling this situation, do I need to add extra mechanism to achieve this?
Thanks.
I don't know how netty works, but if you can configure it using Filters, shiro will make sure the threadlocal info is cleaned at the end of a request.
If you cannot use filters, you can probably hook in your own handling of putting/remove the subject on/from the thread.
Shiro uses the class ThreadContext for this:
http://shiro.apache.org/static/1.2.3/apidocs/org/apache/shiro/util/ThreadContext.html
The methods ThreadContext.bind(securityManager) and ThreadContext.bind(subject) are the key methods. When a thread is done, call ThreadCOntext.remove().
If you check out this page, you'll see the thread stuff in action during a unit test: http://shiro.apache.org/testing.html
Related
I want to introduce effective logging with in my Spring Integration implementation. I already have global wire-tap which logs the payload and headers. However we have lots service activators which has lots of business logic. I want to log important information like user id, request id in every log. We are using SLF4J. The spring integration flow has number of thread pool executors which are managed by Spring integration.
Should I go for AOP where before every method call, I retrieve the userid and request id from message headers and set it in SLF4J MDC? and then clear it once the method execution is over. It would have clearing logic in finally block. Is this a right approach or this would create performance bottle neck? Not sure why this has not been discussed much as in multithreaded SI flow, it would become very difficult to debug logs without user information.
If there is a better approach, please suggest.
See the SecurityContextPropagationChannelInterceptor introduced in 4.2.
Notice that it is a subclass of ThreadStatePropagationChannelInterceptor.
You could use a similar technique to propagate/clean up the MDC when a message is passed off to another thread. It would be less overhead than doing it on every call made by that thread.
Notice how the information to be propagated is wrapped in a lightweight message wrapper, along with the message. You could also store the information in message headers.
If you come up with a generic implementation, consider contributing it to the framework.
I developing a stateless REST API that makes use of token based authentication, where I'm manually adding an Authentication object to the security context by calling SecurityContextHolder.getContext().setAuthentication(authentication) from within a custom security filter. I've been experiencing problems with the context not being set correctly which I believe is due to this :
Storing the SecurityContext between requests
In an application which receives concurrent requests in a single session, the same SecurityContext instance will be shared between threads. Even though a ThreadLocal is being used, it is the same instance that is retrieved from the HttpSession for each thread. This has implications if you wish to temporarily change the context under which a thread is running. If you just use SecurityContextHolder.getContext(), and call setAuthentication(anAuthentication) on the returned context object, then the Authentication object will change in all concurrent threads which share the same SecurityContext instance. ...
You can customize the behaviour of SecurityContextPersistenceFilter to create a completely new SecurityContext for each request, preventing changes in one thread from affecting another.
So the question is - how do you change the behaviour of the SecurityContextPersistenceFilter?
I'd like the security context to not be associated with the http session, but don't want to set the session creation policy to stateless, because I still want to implement CSRF protection etc.
I had this exact question this afternoon, and this open question matched my search exactly, so I thought I would add the little I learned.
We had threads that were accessing the same SecurityContext. I was unable to figure out how to customize the behavior of the SecurityContextPersistenceFilter directly (and in the pattern of the framework), however there were two ways that I could get it to be thread safe.
The first solution was to ensure that an empty context was created in our main authentication filter. This covered all of our authenticated requests, so it would work for our solution.
SecurityContextHolder.createEmptyContext();
The second thing that worked for me was to change our WebSecurityConfig to be stateless, which I know doesn't work for the OP, but added here for completeness.
http.authorizeRequests()
.anyRequest().authenticated()
.and()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
...
Both these solutions work independently for our particular configuration. I'm certain there is a 3rd solution that would read better, but I don't know what it is but would like to.
This is my first time posting. I welcome any feedback.
Dear Spring Cache project community,
currently I'm implementing an Apache CXF-based Spring (version 4.1.5) web service endpoint using the contract 1st approach. Here, I observe when annotating a public method within my web service class, the Spring cache annotations "#Cachable" are ignored each time I call this method in a self-invoked way within the same bean. This could be proven when taking a look on the cache repository (via JMX) of the underlying cache provider (here: EhCache). There, no filling of the cache takes place.
After taking a look on the current Spring documentation below
Enable caching annotations and
The dispatcher servlet I assume it might be due to the fact that:
<cache:annotation-driven/> only looks for #Cacheable/#CachePut/#CacheEvict/#Caching on beans in the same application context it is defined in. This means that, if you put in a WebApplicationContext for a DispatcherServlet, it only checks for beans in your controllers, and not your services. See Section 17.2, “The DispatcherServlet” for more information.
Currently, an Apache CXF "CXFServlet" registered within the "web.xml" deployment descriptor is starting a Spring WebApplicationContext using the "cxf-servlet.xml" Spring application context file by default. There, the <cache:annotation-driven/> is located.
Or is it maybe due to the fact that I'm calling the #Cacheable annotated method from within the same Spring bean so that the generated Spring proxy is bypassed? Details can be found in the "Proxy mechanisms" chapter (9.6) of the Spring documentation as well.
But I do not know how to change the behaviour so that my method results are being cached. Do you have any ideas? Or are my assumptions I posted above incorrect?
Dear Spring community,
I found the important comment within the Spring documentation that approves my assumption:
In proxy mode (which is the default), only external method calls coming in through the proxy are intercepted. This means that self-invocation, in effect, a method within the target object calling another method of the target object, will not lead to an actual caching at runtime even if the invoked method is marked with #Cacheable - considering using the aspectj mode in this case. Also, the proxy must be fully initialized to provide the expected behaviour so you should not rely on this feature in your initialization code, i.e. #PostConstruct.
In consequence this means refactoring the code when relying on Spring AOP and its proxy mode technique or switching the mode from "proxy" to "aspectj" <cache:annotation-driven mode="aspectj"/>. This allows using self-invoking methods within the same class as AOP does static respectively dynamic weaving and so manipulates the byte code directly.
I want to write a row in a db every time a user logs into my application (that uses spring security), and to add the logout time to that row when he logs out, in order to register the number of access and the duration of the session.
I thought there was some Post-Authentication Filter, but I checked the documentation and couldn't find any reference of it.
Is too invasive to write a filter and add it to the spring security filter chain?
Is there some another workaround?
Assuming You're using Spring Security 3.0.x and securing a web application, check out:
AuthenticationSuccessHandler used by AuthenticationProcessingFilter for actions on successful login.
And LogoutSuccessHandler used by LogoutFilter for actions on successful logout.
Ive some questions about Spring Security 3.0.5 and the SecurityContext. First of all, Ill try to conclude what I know:
SecurityContextHolder stores SecurityContext
Between Request, SecurityContext is stored in HttpSession
Begin of Request: SecurityContextHolder gets SecurityContext from HttpSession
End of Request: SecurityContextHolder puts SecurityContext in HttpSession
During the Request, on the server, SecurityContextHolder uses a ThreadLocal. Everywhere in the application (same request), the SecurityContext can be accessed
Now my question....
--> Two Requests: the SecurityContext-instance will be shared
How does this work? I mean, SecurityContextHolder uses a ThreadLocal for Each Request.
2 Request = 2 ThreadLocals
Each request does: getSessionAttribute (SecurityContext) from HttpSession
What happens if they work on the SecurityContext? Is the SecurityContext changed in all ThreadLocals?
As far as I know: yes (??)
How does this work? How can they work on the same instance? I mean, I really cant imagine how two different threads with two different ThreadLocals can work on the same instance?
API (ThreadLocal):
This class provides thread-local variables. These variables differ from their normal counterparts in that each thread that accesses one (via its get or set method) has its own, independently initialized copy of the variable.
I mean, thats it: copy! maybe Im wrong and its not possible for two threads to work on the same SecurityContext? But Spring Security Documentation says so!
Would be great if someone could explain that to me :-) Thank you!
Each thread has its own value of ThreadLocal, but nothing prevents these values from being equal. So, in this case multiple thread would have references to the same instance of SecurityContext.
Usually it's not a problem, but if you want to modify security context, you can enable defensive copying, see SEC-356.