Resolved the problem, sharing with others.

First of all: Les, you were right. Yes, it's not a good idea to bind
SecurityManager as singleton, using SecurityUtils.setSecurityManager.
MMO and web servers should have 2 different security managers. And you told
the solution - bind to threads.

Second: I thought there was 1 bug in shiro, but there were 2 bugs in mine
application :)

   1. Incorrect set of spring parent context in web application. You can
   compare difference in gist - https://gist.github.com/1222182 . Context's
   BeanFactory is already initialized in customizeContext() and setParent
   doesn't update it. The bug was, that bean definitions were correctly read,
   but bean singletons weren't merged with parent context (because BeanFactory
   didn't know anything about parent)
   2. DefaultWebSecurityManager behavior, when session mode is changed. It
   simply ignores, the session manager, set by setSessionManager() method and
   creates a new one. Take a look at this portion of DefaultWebSecurityManager
   - https://gist.github.com/1222206

So the conclusion is that it's impossible to inject own session manager, if
session mode is non-default. For myself I've created such a dirty hack -
https://gist.github.com/122221 . Very ugly, I know :)

As another solution: check session mode on setting session manager and check
session manager on setting session mode. Throw exception if session mode
doesn't correspond to session manager or vice versa, instead of silently
recreating session manager instance.

In Spring it can be done even easily - implement InitializingBean and check
session mode and session manager in afterPropertiesSet() method.

Les, what do you think about solutions?

Thanks,
Alex

2011/9/7 Les Hazlewood <[email protected]>

> On Wed, Sep 7, 2011 at 11:06 AM, Alex Vasilenko <[email protected]>
> wrote:
> > Hello Les,
> > I've added shiro filter setup, that I've missed previous time. First I've
> > tried using #1 approach only for web application. But it didn't work.
> Hybrid
> > #1 with #2 works.
> > However #1 worked ok (correct realm, correct credentials matcher, etc),
> > until I figured out, that security manager was different. It was weird.
> > Because if it was using parent security manager then it had different
> realm
> > and different credentials matcher. But there were only 2 differences -
> > DefaultSecurityManager instance instead of DefaultWebSecurityManager and
> > different session DAO.
> > That is why I've posted it here, thought #1 and #2 should be combined by
> > default.
>
> If you use the ShiroFilterFactoryBean in spring.xml, you inject it
> with the DefaultWebSecurityManager bean.  Once you do this, there is
> no need to call SecurityUtils.setSecurityManager because the filter
> will have the injected one and use it for all requests.
>
> Or is it possible that SmartFox invokes things asynchronously that are
> not triggered in the request thread?  If yes, calling
> SecurityUtils.setSecurityManager may be your best option.
>
> However, if SmartFox does do things asynchronously (out of the request
> thread), and it does so by using an ExecutorService, you can configure
> one of Shiro's SubjectAware* ExecutorService implementations to
> automate subject 'handoff' across threads.  This is the only way at
> the moment to ensure a Subject 'follows' threads related to
> subject-initiated invocations.
>
> > For Smartfox I'm using something similar to what you have already
> described.
> > There's something similar to Servlet Filters, where I bind subject to
> > current thread - https://gist.github.com/1201270 .
> > It's impossible to unbind later, because Smartfox doesn't provider
> > post-filter. But it works ok, because I bind or clear subject on each
> > request.
>
> Hrm - too bad you can't use Subject.Builder and subject.execute.
> Subject.execute will automatically unbind the Subject instance after
> the invocation completes (or errors).  But the ThreadState mechanism
> is fine if you can't - it's just a tad more work.
>
> Cheers,
>
> Les
>

Reply via email to