Hi,
Thanks again for replying.
What I've done is below (this is just to test):
I subclassed WebIniSecurityManagerFactory like this.
public static class WebIniSecurityManagerFactoryMine extends
WebIniSecurityManagerFactory {
public WebIniSecurityManagerFactoryMine() {
super();
}
public WebIniSecurityManagerFactoryMine(Ini init) {
super(init);
}
@Override
protected SecurityManager createDefaultInstance() {
final SecurityManager securityManager =
PulseBindings.<PulseSecurity>security().getSecurityManager();
return securityManager;
}
@Override
protected SecurityManager createInstance(Ini ini) {
super.createInstance(ini);
final SecurityManager securityManager =
PulseBindings.<PulseSecurity>security().getSecurityManager();
return securityManager;
}
}
Then I subclassed IniShiroFilter like this:
@Override
protected Map<String, ?> applySecurityManager(Ini ini) {
WebIniSecurityManagerFactory factory;
if (CollectionUtils.isEmpty(ini)) {
factory = new WebIniSecurityManagerFactoryMine();
} else {
factory = new WebIniSecurityManagerFactoryMine(ini);
}
// Create the security manager and check that it implements
WebSecurityManager.
// Otherwise, it can't be used with the filter.
SecurityManager securityManager = factory.getInstance();
if (!(securityManager instanceof WebSecurityManager)) {
String msg = "The configured security manager is not an instance
of WebSecurityManager, so " +
"it can not be used with the Shiro servlet filter.";
throw new ConfigurationException(msg);
}
setSecurityManager((WebSecurityManager) securityManager);
return factory.getBeans();
}
So it can use my factory that not creates an instance but uses the already
running one.
Then I subclassed UserFilter like:
@Override
protected Subject getSubject(ServletRequest request, ServletResponse
response) {
Subject sub;
final String jsessionId = request.getParameter(JSESSIONID_KEY);
if (jsessionId != null) {
sub = new
Subject.Builder().sessionId(jsessionId).buildSubject();
} else {
sub = super.getSubject(request, response);
}
request.setAttribute("subject", sub);
return sub;
}
So the idea is, if JSESSIONID is sent in the parameters it is possible that
a session is already in use and I try to get the subject using the session,
if not I use your implementation.
I really don't know why (and I'm sure only one SessionManager is in use as
well as SecurityManager because I ran the application with a profiler and
only on instance of each is in use) but I'm getting this error when I try to
use Subject.Builder().sessionId(...):
java.lang.IllegalArgumentException: SessionKey must be an HTTP compatible
implementation.
at
org.apache.shiro.web.session.mgt.ServletContainerSessionManager.getSession(ServletContainerSessionManager.java:70)
at
org.apache.shiro.mgt.SessionsSecurityManager.getSession(SessionsSecurityManager.java:125)
at
org.apache.shiro.mgt.DefaultSecurityManager.resolveContextSession(DefaultSecurityManager.java:394)
at
org.apache.shiro.mgt.DefaultSecurityManager.resolveSession(DefaultSecurityManager.java:380)
at
org.apache.shiro.mgt.DefaultSecurityManager.createSubject(DefaultSecurityManager.java:329)
at
org.apache.shiro.subject.Subject$Builder.buildSubject(Subject.java:829)
at
filter.DistributedSessionFilter.getSubject(DistributedSessionFilter.java:37)
at
org.apache.shiro.web.filter.authc.UserFilter.isAccessAllowed(UserFilter.java:53)
at
org.apache.shiro.web.filter.AccessControlFilter.onPreHandle(AccessControlFilter.java:162)
at
org.apache.shiro.web.filter.PathMatchingFilter.preHandle(PathMatchingFilter.java:177)
at
org.apache.shiro.web.servlet.AdviceFilter.doFilterInternal(AdviceFilter.java:131)
at
org.apache.shiro.web.servlet.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:81)
at
org.apache.shiro.web.servlet.ProxiedFilterChain.doFilter(ProxiedFilterChain.java:66)
at
org.apache.shiro.web.servlet.AbstractShiroFilter.executeChain(AbstractShiroFilter.java:359)
at
org.apache.shiro.web.servlet.AbstractShiroFilter$1.call(AbstractShiroFilter.java:275)
at
org.apache.shiro.subject.support.SubjectCallable.doCall(SubjectCallable.java:90)
at
org.apache.shiro.subject.support.SubjectCallable.call(SubjectCallable.java:83)
at
org.apache.shiro.subject.support.DelegatingSubject.execute(DelegatingSubject.java:344)
at
org.apache.shiro.web.servlet.AbstractShiroFilter.doFilterInternal(AbstractShiroFilter.java:272)
at
org.apache.shiro.web.servlet.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:81)
at
org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1187)
at
org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:421)
at
org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:119)
at
org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:456)
at
org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:226)
at
org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:924)
at
org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:358)
at
org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:183)
at
org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:860)
at
org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:117)
at
org.eclipse.jetty.server.handler.ContextHandlerCollection.handle(ContextHandlerCollection.java:245)
at
org.eclipse.jetty.server.handler.HandlerCollection.handle(HandlerCollection.java:126)
at
org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:113)
at
org.eclipse.jetty.server.Server.handle(Server.java:335)
at
org.eclipse.jetty.server.HttpConnection.handleRequest(HttpConnection.java:588)
at
org.eclipse.jetty.server.HttpConnection$RequestHandler.headerComplete(HttpConnection.java:1029)
at
org.eclipse.jetty.http.HttpParser.parseNext(HttpParser.java:549)
at
org.eclipse.jetty.http.HttpParser.parseAvailable(HttpParser.java:211)
at
org.eclipse.jetty.server.HttpConnection.handle(HttpConnection.java:418)
at
org.eclipse.jetty.io.nio.SelectChannelEndPoint.run(SelectChannelEndPoint.java:489)
at
org.eclipse.jetty.util.thread.QueuedThreadPool$2.run(QueuedThreadPool.java:436)
at java.lang.Thread.run(Thread.java:662)
Do you have any clue why this is happening?
Thanks in advance,
--
Rui
On Tue, Aug 2, 2011 at 8:18 PM, Les Hazlewood <[email protected]> wrote:
> Also note that the [urls] INI section is really there to configure
> filter chains on a Shiro FilterChainManager instance. You could
> configure your own FilterChainManager (and create filter chains as
> necessary) yourself by invoking methods on it directly (see the
> DefaultFilterChainManager class).
>
> So, in summary:
>
> The [main] section configures the SecurityManager and its object
> graph, including realms.
>
> The [urls] section configures filter chains which are set on a
> FilterChainManager. At runtime, a FilterChainResolver asks the
> FilterChainManager for a filter chain to execute for the corresponding
> request/response. If the FilterChainManager returns one, that is
> executed. If it doesn't, the original chain provided by the servlet
> container is executed.
>
> If you didn't want to use INI, you could subclass the
> AbstractShiroFilter and provide your own means (code, DI, whatever) of
> providing the SecurityManager and FilterChainResolver instances.
>
> HTH,
>
> Les
>
> On Tue, Aug 2, 2011 at 12:03 PM, Les Hazlewood <[email protected]>
> wrote:
> > The SecurityManager is an object graph with nested components (some of
> > which are Realms). You can instantiate a SecurityManager and call
> > setter methods on it or any of its internal components just fine.
> >
> > The INI [main] section is just a text-based way of configuring the
> > Security manager object graph. I often call it 'poor man's Dependency
> > Injection' since it works like Spring or Guice, just not quite as
> > powerful. You don't have to use it however - you can call the methods
> > you want via standard Java code or reflection if you like (or use
> > something like Spring or Guice which does this for you).
> >
> > Cheers,
> >
> > Les
>