Hi,
On Tue, Feb 11, 2014 at 1:14 AM, Jukka Zitting <[email protected]> wrote:
> On Mon, Feb 10, 2014 at 8:35 PM, Tobias Bocanegra <[email protected]> wrote:
>> I'd rather offer it via a Callback.
>
> Callbacks are not really meant for such use. Their purpose is to allow
> the authentication component to "interact with the application to
> retrieve specific authentication data, such as usernames and
> passwords, or to display certain information, such as error and
> warning messages", not to access the rest of the runtime environment.
>
> What we should do instead is to pass context information via the
> options map passed to LoginModule.initialize() method.
Right, this might be better :-) I just followed the pattern already
there with all the other callbacks :-)
> For example the
> Karaf JAAS implementation passes the BundleContext through the options
> map. The LoginModule class would then look into the options map for
> any dependencies it has. Something like this:
>
> abstract class MyLoginModule implements LoginModule {
>
> private LoginBackend backend;
>
> protected abstract LoginBackend getLoginBackend(Map<String, ?>
> options);
>
> @Override
> public initialize(...,Map<String,?> options) {
> this.backend = getLoginBackend(options);
> }
>
> }
>
> Subclasses can specialize the lookup method to work with different
> runtime environments. For example in an OSGi/Karaf environment this
> could be (omitting error handling and details like handling of service
> reference counts):
>
> class MyOsgiLoginModule extends MyLoginModule {
> @Override
> protected LoginBackend getLoginBackend(Map<String, ?> options) {
> BundleContext context = (BundleContext)
> options.get(BundleContext.class.getName());
> return getLoginBackend(context); // OSGi service lookup
> }
> }
>
> Or in a plain old Java environment:
>
> class MyJavaLoginModule extends MyLoginModule {
> @Override
> protected LoginBackend getLoginBackend(Map<String, ?> options) {
> return (LoginBackend) options.get(LoginBackend.class.getName());
> }
> }
>
> ... with the following bootstrapping code:
>
> LoginBackend backend = new LoginBackend(...);
> Map<String, ?> options =
> singletonMap(LoginBackend.class.getName(), backend);
> Configuration.setConfiguration(new
> ConfigurationExtender(Configuration.getConfiguration(), options));
>
> (The ConfigurationExtender class would decorate the given default
> configuration with the given extra options.)
>
> Note how none of this requires a dependency to the Whiteboard. We of
> course *can* depend on the Whiteboard if the login code needs stuff
> like dynamic service registration or lookups, but there's no inherent
> need for that dependency.
True, but if we want to write LoginModules what work in both worlds,
then we need to offer a common interface to access to services - and
that's currently the whiteboard.
Regards, Toby