WIP:Osigification
This pull request is the first phase of adding full OSGi support to shiro. Currently, only Shiro-Core has been covered. I wanted to get peoples reactions to my direction, before going over Shiro-Web as well. Note that this Pull Request is NOT indicative of the final product, even for Shiro-Core. I still have a second review of the POM files, as well as javadoc and a few refactorings to do. This is purely meant to give everyone a chance to comment before i completely wreck your beautiful product :D
The following segment is a copy-paste from the mail i sent to the shiro dev mailing list. I am placing it here to keep everything together.
Design Choice: The mission was to create a "Pure OSGi" approach for configuring Shiro. The idea is that each component (SecurityManager, SessionManager, Cache and so on) exists as seperate bundles. Configuring Shiro in OSGi is therefore not done via Shiro.ini, but is instead done by installing the bundles that make up the desired Shiro runtime. Any configuration needed by the components is done through the ConfigurationAdmin, or through container specific deployment methods, such as the Karaf Feature. Besides being a very "OSGi-like" way of configuring applications, it also allows us to run Shiro in for example, a Karaf Cellar Cluster, as the SecurityManager can actually exist in several Karafs at once, as long as the cache and session managers are synchronized.
Steps i have taken: A few changes has been made to the existing Shiro code. I have really tired to keep it to an absolute minimum, to illustrate how few changes to the existing code is actually needed. I even opted to create my own Karaf-Feature file (which will be merged with the existing one later) Here is a quick summary: Shiro Core is now a Declarative Service, which injects the SecurityUtils.SecurityManager, ensuring that "Normal" shiro applications will also work in the OSGi-based Shiro. Delegating subject now has a SecurityManagerSource, instead of a reference to an actual SecurityManager, to allow the SubjectFactory control over where to find the SecurityManager for its subjects. ThreadState now has more control over what exactly is saved in ThreadLocal, allowing the SubjectFactory control over what to save and what NOT to save. I updated a few tests, as the mocks needed to refresh the new reality. I changed and added dependencies in the root-POM (only related to OSGi)
New additions: The support module now contains a new OSGi submodule, which contains DeclarativeService enabled versions of the normal Shiro-Core components. A new Realm has also been created, allowing subjects and roles to be configured via the ConfigurationAdmin. I have added a new Feature File and an Integration Test. (Also in support/OSGi)
I added a couple minor comments, from a quick glance, but I'll pull the code in a bit and take a closer look.
Thanks again for taking this on!
Brian: Would it be ok if i created a couple of constructors in DefaultSecurityManager and DefaultWebSecurityManager, to control what objects gets injected at contruction? Right now SessionDAOs, SessionsManagers and the like are forcefully injected, but i just need all of them to be null. In the interest of "Least impact", i have simply set these to null in my subclasses, but they are still created (and then thrown away). It works, but it is not the prettiest code i have ever written.
I will leave functionality of the no-arg constructors intact.
I've been thinking about adding constructors for injecting as well.
Right, i will create injector-friendly constructors and let the default constructors extend from them, while leaving the default constructors functionally intact. I will run through the securitymanager subclasses first, but if you want me to take a look somewhere else as well, let me know.
Hi guys. Sorry for the long absence, i have been drowning at my actual work, and haven't found enough time for both open source and sleeping. But things are looking better now!
I have been looking into making a simply way to do something along the lines of org.apache.shiro.web.servlet.ShiroFilter. It does seem to be slated towards large singular applications, and the OSGi containers are also slightly obstructive, for example by locking each bundle in their own servletcontext.
So i was wondering what your take on the problem is. I still have faith in the core implementation of OSGi Shiro. The question is whether i should polish the Shiro Core stuff first? I could then look into trying to figure out a way to handle Web later on. That would mean that only Shiro Core would have actual OSGi support.
What do you guys think?
@mnybon I believe there is no traction on this PR since your last comment in august. I am interested in contributing here and move this forward to completion. Let me know your thoughts.
@rakeshk15 I would welcome help, not least for a second opinion. I have hit a brick wall with implementing shiro-web in an OSGi context. The main problem is that i don't see any way to get past a restriction in pax-web, which i think we need to support. The problem is that servletcontexts are bound to bundlecontext for each bundle, so you cannot register cross-bundle filters.
@mnybon true that there is a concept of per bundle context/http service but you can very well register servlets,filters for all the contexts present, this way they are suppose to be called of each context.
Using OSGi HttpService Whiteboard specification's following properties a filter can be registered for all the contexts present.
osgi.http.whiteboard.filter.pattern = "/*"
osgi.http.whiteboard.context.select="*" // Means for all contexts
osgi.http.whiteboard.filter.dispatcher = specify where this filter should intercept by declaring one or many [REQUEST,FORWARD,INCLUDE,ASYNC,ERROR] can be of type String[] or Collection of String
There is one caveat though - the Filter lifecycle method e.g init is called as many times as number of contexts available which may not be desirable in case of ShiroFilter as generally we would want one instance per application. But due to "per bundle context" it makes more sense having a context having its own filter registry and so each context manages the ShiroFilter lifecycle seperately.
Edit: same applies to ServletContextListener as well, means the life cycle methods(contextInitialized(), contextDestroyed()) will be called for each context.
A ServletContextListener can be registered for all the contexts present like this.
osgi.http.whiteboard.listener = "true"
osgi.http.whiteboard.context.select="*" // Means for all contexts
In case of Shiro most of the initialisation happens in [EnvironmentLoaderListener] therefore initialisation will happen for each context and which is what ShiroFilter needs so we are covered here.
Please let me know your thoughts.
Thanks, Rakesh