AbstractLdapRealm and the LdapContextFactory

classic Classic list List threaded Threaded
6 messages Options
Reply | Threaded
Open this post in threaded view
|

AbstractLdapRealm and the LdapContextFactory

Anders Hammar
Hi,

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. 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.
Who is responsible for calling afterAuthorizationCacheSet()? Should
the application using JSecurity do that? Or should my subclass do
that?

Regards,
/Anders
Reply | Threaded
Open this post in threaded view
|

Re: AbstractLdapRealm and the LdapContextFactory

Anders Hammar
Digging deeper I've found that setting a CacheManager will result in afterAuthorizationCacheSet() being called. But, nothing about this is mentioned in the javadoc for AbstractLdapRealm. Is a subclass (of AbstractLdapRealm) required to use a CacheManager?

/Anders
Anders Hammar wrote
Hi,

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. 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.
Who is responsible for calling afterAuthorizationCacheSet()? Should
the application using JSecurity do that? Or should my subclass do
that?

Regards,
/Anders
Reply | Threaded
Open this post in threaded view
|

Re: AbstractLdapRealm and the LdapContextFactory

Les Hazlewood
Administrator
In reply to this post by Anders Hammar
> 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?
Reply | Threaded
Open this post in threaded view
|

Re: AbstractLdapRealm and the LdapContextFactory

Anders Hammar
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 <[hidden email]> 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?
>
Reply | Threaded
Open this post in threaded view
|

Re: AbstractLdapRealm and the LdapContextFactory

Anders Hammar
I've filed JSEC-131 (http://issues.jsecurity.org/browse/JSEC-131) regarding this. IMHO it's a bug.

Regards,
/Anders

Anders Hammar wrote
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?
>
Reply | Threaded
Open this post in threaded view
|

Re: AbstractLdapRealm and the LdapContextFactory

Les Hazlewood
Administrator
Hi Anders,

I was out of town for quite a while and just got back - thanks very
much, we'll look into it asap.

On Wed, Oct 22, 2008 at 1:23 AM, Anders Hammar <[hidden email]> wrote:

>
> I've filed JSEC-131 (http://issues.jsecurity.org/browse/JSEC-131) regarding
> this. IMHO it's a bug.
>
> Regards,
> /Anders
>
>
> Anders Hammar wrote:
>>
>> 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 <[hidden email]> 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?
>>>
>>
>>
>
> --
> View this message in context: http://n2.nabble.com/AbstractLdapRealm-and-the-LdapContextFactory-tp1340535p1362881.html
> Sent from the JSecurity User mailing list archive at Nabble.com.
>
>