shiro-user mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Anders Hammar" <and...@hammar.net>
Subject Re: AbstractLdapRealm and the LdapContextFactory
Date Fri, 17 Oct 2008 06:27:00 GMT
Thanks for your response Les. Sorry if I wasn't clear enough, I'll try
to clearify.

What trying to do is to implement an LDAP auth realm to be used with
the Sonatype Nexus application. So, I'm not using the grails plugin.
When I say 'default behavior', I mean the behavior inherited from the
AbstractLdapRealm (which I'm subclassing). I'm using JSecurity
0.9.0-RC2.

Trying to clarify, I'll take you trough the steps of my (novice) usage
of JSecurity:
Basically, what I'm currently looking for is to implement a auth realm
to be used with Nexus. I see that there is an abstract
'AbstractLdapRealm' class shipped with JSecurity that should fit my
needs. I'm creating a subclass and by reading the javadoc for
AbstractLdapRealm I understand that I need to implement the
queryForAuthenticationInfo() and the queryForAuthorizationInfo()
methods.
As I'm not looking for authz support, my queryForAuthorizationInfo()
methods just returns null. No problem. I implement the
queryForAuthenticationInfo() method very similar to the implementation
found in ActiveDirectoryRealm (shipped with JSecurity).
As Nexus uses Plexus, I have an initialization method that gets
called. In this method I call setUrl(), setPrincipalSuffix(),
setSearchBase(), and init().
However, when running this code, the LdapContextFactory passed in to
queryForAuthenticationInfo() is null! And this is my issue. Why is
this? In the class javadoc for AbstractLdapRealm I read this:
"By default, this implementation will create an instance of
DefaultLdapContextFactory to use for creating LDAP connections using
the principalSuffix, searchBase, url, systemUsername, and
systemPassword properties specified on the realm. The remaining
settings use the defaults of DefaultLdapContextFactory, which are
usually sufficient."
Thus, an instance of DefaultLdapContextFactory should (according to my
understanding of the javadoc) be passed in. But it isn't. Only by
setting a CacheManager (calling setCacheManager()) will an instance of
DefaultLdapContextFactory be created and used. But the javadoc does
not mention that a cache manager has to be used. Is that required?
Reading the javadoc for the CachingRealm class (and more specifically
the setCacheManager() method), I see that "This property is null by
default, indicating that caching is turned off". My understanding of
this is that it should be possible to run without a CacheManager.
However, when doing that the DefaultLdapContextFactory is not being
created.

Where is the problem; my interpretation, the javadoc, or the
implementation? (Or possibly how Nexus uses JSecurity?)

Regards,
/Anders

On Fri, Oct 17, 2008 at 12:26 AM, Les Hazlewood <les@hazlewood.com> wrote:
>> I have a problem extending the AbstractLdapRealm class for
>> authentication. It's my understanding based on reading the javadoc
>> that a default implementation of LdapContextFactory
>> (DefaultLdapContextFactory) is being used if I don't change the
>> default behavior.
>
> Default behavior of what? (I'm a little confused).  JSecurity does not
> enable a default LDAP realm by default - it expects you to configure
> realms explicitly.  Is this related to the Grails plugin perhaps?
>
> However, when implementing a subclass of
>> AbstractLdapRealm for authentication (implementing the
>> queryForAuthenticationInfo method) the LdapContextFactory being passed
>> in is null. Checking the source, it seems as DefaultLdapContextFactory
>> is set when afterAuthorizationCacheSet() is called.
>
> I'm still not sure what you mean by 'DefaultLdapContextFactory is set"
> - JSecurity does not do this automatically.  Again, is this possibly a
> Grails plugin related issue?
>
>> Who is responsible for calling afterAuthorizationCacheSet()? Should
>> the application using JSecurity do that? Or should my subclass do
>> that?
>
> This method is called automatically when a CacheManager is set on any
> Realm that extends CachingRealm (AbstractLdapRealm is one of these).
> Here is the setCacheManager implementation:
>
> public void setCacheManager(CacheManager cacheManager) {
>    this.cacheManager = cacheManager;
>    afterCacheManagerSet();
> }
>
> afterCacheManagerSet() is overridden in the AuthorizingRealm subclass
> (which is also a parent of AbstractLdapRealm) to automatically
> initialize a cache for AuthorizationInfo instances to reduce
> round-trip lookups for better performance.
>
> the setCacheManager() method is called when a CacheManager is set on
> the SecurityManager or when a realm is added to the SecurityManager.
> That is, if you call defaultSecurityManager.setCacheManager(
> cacheManager ), this cache manager instance will propagate down to all
> CachingRealm instances that exist, which in turn calls
> afterCacheManagerSet() on each one of them, allowing each to use the
> injected CacheManager to initialize their own cache.
>
> Similarly, If you have an already-initialized SecurityManager - that
> is, the securityManager already has an internal CacheManager injected
> and ready-to-go - and you then call securityManager.setRealm( aRealm)
> or securityManager.setRealms( Collection<Realm> ), then the realms
> will still be injected with the SecurityManager's CacheManager so they
> can use it to create caches.
>
> So, in summary, if you call securityManager.setCacheManager _or_
> securityManager.setRealm(s), you can rest assured any CachingRealm
> subclass instances will receive that CacheManager so they can
> initialize a cache if they need to.
>
> Does that help?
>

Mime
View raw message