You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@felix.apache.org by ch...@apache.org on 2013/11/18 15:41:56 UTC
svn commit: r1543042 -
/felix/site/trunk/content/documentation/subprojects/apache-felix-jaas.mdtext
Author: chetanm
Date: Mon Nov 18 14:41:56 2013
New Revision: 1543042
URL: http://svn.apache.org/r1543042
Log:
FELIX-3980 - Add documentation related to usage of Felix JAAS Bundle
Work in progress
Modified:
felix/site/trunk/content/documentation/subprojects/apache-felix-jaas.mdtext
Modified: felix/site/trunk/content/documentation/subprojects/apache-felix-jaas.mdtext
URL: http://svn.apache.org/viewvc/felix/site/trunk/content/documentation/subprojects/apache-felix-jaas.mdtext?rev=1543042&r1=1543041&r2=1543042&view=diff
==============================================================================
--- felix/site/trunk/content/documentation/subprojects/apache-felix-jaas.mdtext (original)
+++ felix/site/trunk/content/documentation/subprojects/apache-felix-jaas.mdtext Mon Nov 18 14:41:56 2013
@@ -10,6 +10,8 @@ img {
Work in progress as part of FELIX-3980
</div>
+[TOC]
+
Apache Felix JAAS support aims to simplify usage of JAAS in OSGi.
It supports following features
@@ -46,22 +48,21 @@ to create the instance. This approach fa
3. Even if an implementation class was exported, importing this class in a consumer bundle would bind it to the specific
implementation package provided, which violates the principle of loose coupling.
-## Making it work
-
-In order to make JAAS work under OSGi following
-
## Usage
The JAAS support involves following parts
-1. LoginContext Creation - Refers to the client code which constructs the LoginContext and then perform login operation
-2. LoginModule Registration - Mechanism by which LoginModule is registered with a given `realm`.
+1. LoginModule Registration - Mechanism by which LoginModule is registered with a given `realm`.
+2. LoginContext Creation - Refers to the client code which constructs the LoginContext and then perform login operation
+
+In section below we would first provide details on various ways by which a `LoginModule` would be configured so that
+it can participate in JAAS flow and then about various ways in which the client code can invoke the JAAS logic
### LoginModule registration
The login modules can be registered via two mechanism
-* OSGi Configuration
-* LoginModuleFactory registered with the OSGi ServiceRegistry
+* OSGi Configuration - LoginModule are registered via OSGi configuration
+* LoginModuleFactory - LoginModule are registered with the OSGi ServiceRegistry via `LoginModuleFactory`
#### A - OSGi Configuration
LoginModules can also be configured via configuration which is somewhat similar to the file based configuration. It consist of two parts
@@ -90,7 +91,7 @@ Configuration properties
is bound to a 'other' realm
* `jaas.ranking` - Ranking for the LoginModule. It would be used to order the various login modules
-For an example refer to [Sample Confiuration][4]. It configures a SampleConfigLoginModule for `sample` realm
+For an example refer to [Sample Configuration][4]. It configures a SampleConfigLoginModule for `sample` realm
#### B - LoginModuleFactory
@@ -138,82 +139,115 @@ Interface
Refer to [JdbcLoginModuleFactory][1] for one example of its usage. It constructs a JdbcLoginModule based on the
configuration and passes on the datasource.
-### JAAS Configuration SPI Settings
+### LoginContext creation patterns
-There are various ways in which LoginContext can be created depending on the usage mode. The JAAS support exposes
-following properties
+There are various ways through which a JAAS Client can invoke the JAAS login.
-<img src="jaas-spi-config.png" align="center" />
+#### LoginContextFactory Mode
-* `Default JAAS Realm` - Name of the realm to use in case a LoginModule does not provide an explicit realmName.
- This is useful for single application mode where all LoginModule in an OSGi container are to be used. Usage of realm
- help in global settings because same config file is used to capture settings for all applications running on same JVM
-* `JAAS Config Provider name` - Name against which the Configuration SPI provider should register
-* `Configuration Policy` - This would be explained in next section
+In this mode the client logic obtains a reference to the `org.apache.felix.jaas.LoginContextFactory` service
+and then creates a `LoginContext` instance
+
+ :java
+ LoginContextFactory loginContextFactory = ...
+ CallbackHandler handler = ...;
+ Subject subject = new Subject();
+ try
+ {
+ LoginContext lc = loginContextFactory.createLoginContext("sample",subject,handler);
+ lc.login();
+ ...
+ }
+ catch (LoginException e)
+ {
+ handleAuthenticationFailure(e);
+ }
+
+Refer to [FactoryDemoServlet][6] for an example. Following points to be noted for this usage pattern
-#### Configuration Policy and Invocation Mode
+* Client code needs to depend on Apache Felix JAAS Support API
+* No need to manage Thread Context Classloader while invoking `LoginContext`
+* No need to import LoginModule related packages
-##### Default
+#### Configuration SPI with Default Policy Mode
-Under this mode the global JAAS configuration would not be touched so client code would need to fetch the Configuration
-and pass it explicitly
+In this mode the client logic explicitly fetch the JAAS Configuration and then pass it on to the LoginContext. In this
+mode the [JAAS Configuration Policy](#configuration-spi) is set to `Default`.
:::java
- import javax.security.auth.Subject;
- import javax.security.auth.callback.CallbackHandler;
- import javax.security.auth.login.Configuration;
- import javax.security.auth.login.LoginContext;
- import javax.security.auth.login.LoginException;
- import javax.security.auth.spi.LoginModule;
+ CallbackHandler handler = ...;
- Configuration config = Configuration.getInstance('JavaLoginConfig', //Algorithm name
- null, //Extra params to be passed. For this impl its null
- 'FelixJaasProvider' //Name of the config provider
- );
+ Subject subject = new Subject();
+ final ClassLoader cl = Thread.currentThread().getContextClassLoader();
+ try
+ {
+ Configuration config = Configuration.getInstance(
+ 'JavaLoginConfig', //Algorithm name
+ null, //Extra params to be passed. For this impl its null
+ 'FelixJaasProvider' //Name of the config provider
+ );
+ Thread.currentThread().setContextClassLoader(getClass().getClassLoader());
+ LoginContext lc = new LoginContext("sample", subject, handler, config);
+ lc.login();
-Following points need to be considered this mode
+ ...
+ }
+ finally
+ {
+ Thread.currentThread().setContextClassLoader(cl);
+ }
+
+In above flow the `Configuration` instance is explicitly fetched and passed on to the
+
+Refer to [TCCLDemoServlet][3] for an example. Following points to be noted for this usage pattern
* Client code needs to be aware of the name of the config provider.
-* Client bundle would need to have an import for package 'org.apache.felix.jaas.boot'. Refer to 'Boot classpath' section
- for more details
+* Client bundle would need to have an import for package `org.apache.felix.jaas.boot`.
+ Refer to [Boot classpath](#boot-classpath) section for more details
* Global configuration is not modified so other users of JAAS are not affected
-Refer to [TCCLDemoServlet][3] for an example
-
-#### Replace Global Configuration
+#### Replace Global Configuration Mode
In this mode the JAAS bundle would replace the Global configuration through Configuration.setConfiguration call. In this
-mode the client code would use the normal LoginContext creation
+mode the client code would use the normal LoginContext creation and the [JAAS Configuration Policy](#configuration-spi)
+is set to `Replace Global Configuration`.
:::java
- // let the LoginContext instantiate a new Subject
- LoginContext lc = new LoginContext("appName");
- lc.login();
+ final ClassLoader cl = Thread.currentThread().getContextClassLoader();
+ try
+ {
+ Thread.currentThread().setContextClassLoader(getClass().getClassLoader());
+
+ // let the LoginContext instantiate a new Subject
+ LoginContext lc = new LoginContext("appName");
+ lc.login();
+ }
+ finally
+ {
+ Thread.currentThread().setContextClassLoader(cl);
+ }
Following points need to be considered this mode
* Client code is not aware of the provider name
-* Client bundle would need to have an import for package 'org.apache.felix.jaas.boot'. Refer to 'Boot classpath' section
- for more details
+* Client bundle would need to have an import for package `org.apache.felix.jaas.boot`.
+ Refer to [Boot classpath](#boot-classpath) section for more details
* Global configuration is modified. So it might cause issue while running in co deployed scenarios like Application Server.
Refer to [GlobalConfigDemoServlet][2] for an example
-####Proxy Global Configuration
-
-Similar to previous one but it saves the default configuration and does a fallback check on that also. This should
-minimize any disruption in shared mode
-
-### Boot classpath
-Due to constraints in the JAAS specification, one class has to be available for all bundles. This class is called `ProxyLoginModule`
-and is a LoginModule that acts as a proxy for an OSGi defines LoginModule. If you plan to integrate this feature into
-another OSGi runtime, this class must be made available from the system classloader and the related package be part of the
-boot delegation classpath (or be deployed as a fragment attached to the system bundle).
+#### <a name="boot-classpath"></a>Modified Boot Classpath Mode
-This is similar to support provided in Karaf.
-
-The other approach involves adding the import for `org.apache.felix.jaas.boot` package to the client bundle i.e. bundle
-which invokes LoginContext and then switch the Thread's Context Classloader (TCCL)
+In previous modes (except the LoginContextFactory mode) the client code needs to switch the Thread Context Classloader (TCCL).
+This is due the way JAAS logic instantiates the `LoginModule`. The Felix JAAS Support provides a `ProxyLoginModule` which
+takes care of routing the LoginModule calls properly. However for this class to be visible to JAAS logic one of the
+two approaches can be used
+
+*Manage TCCL Explicitly*
+
+The client bundle would need to
+1. Have an explicit import for `org.apache.felix.jaas.boot` package and
+2. Manage TCCL explicitly which making JAAS related calls.
:::java
final Thread current = Thread.currentThread();
@@ -225,7 +259,40 @@ which invokes LoginContext and then swit
current.setContextClassLoader(orig);
}
-In this mode you need not modify the boot classpath or fragment
+Note that in above flow the TCCL is managed explicitly
+
+*Modify Boot Classpath*
+
+Another way would involve modifying the boot classpath.
+
+1. Place the `org.apache.felix.jaas-xxx-boot.jar` in the boot classpath via `-Xbootclasspath:bootclasspath` option
+2. Make the `org.apache.felix.jaas.boot` part of boot delegation list
+
+ :::java
+ LoginContext lc = new LoginContext("sample", subject, handler);
+ lc.login();
+
+Note that in above code we do not have to manage TCCL and neither add an import to `org.apache.felix.jaas.boot` package
+
+Refer to [BootClasspathDemoServlet][7] for code sample
+
+### <a name="configuration-spi"></a>JAAS Configuration SPI Settings
+
+There are various ways in which LoginContext can be created depending on the usage mode. The JAAS support exposes
+following properties
+
+<img src="jaas-spi-config.png" align="center" />
+
+* `Default JAAS Realm` - Name of the realm to use in case a LoginModule does not provide an explicit realmName.
+ This is useful for single application mode where all LoginModule in an OSGi container are to be used. Usage of realm
+ help in global settings because same config file is used to capture settings for all applications running on same JVM
+* `JAAS Config Provider name` - Name against which the Configuration SPI provider should register
+* `Configuration Policy` - This would be explained in next section
+ ** `Default` - Global configuration is not touched. Client code are expected to use the Configuration Spi mode
+ ** `Replace Global Configuration` - In this the global configuration is replaced with OSGi configuration. Client code
+ need not perform any special configuration handling. At most they need to switch the Thread Context Classloader
+ ** `Proxy Global Configuration` - Similar to previous one but it saves the default configuration and does a fallback
+ check on that also. This should minimize any disruption in shared mode
## WebConsole Plugin
@@ -242,4 +309,6 @@ The runtime JAAS realm is exposed via a
[2]: http://svn.apache.org/repos/asf/felix/trunk/examples/jaas/app/src/main/java/org/apache/felix/example/jaas/app/internal/GlobalConfigDemoServlet.java
[3]: http://svn.apache.org/repos/asf/felix/trunk/examples/jaas/app/src/main/java/org/apache/felix/example/jaas/app/internal/TCCLDemoServlet.java
[4]: http://svn.apache.org/repos/asf/felix/trunk/examples/jaas/launcher/src/main/config/org.apache.felix.jaas.Configuration.factory-simple.cfg
-[5]: http://svn.apache.org/repos/asf/felix/trunk/jaas/src/main/java/org/apache/felix/jaas/LoginModuleFactory.java
\ No newline at end of file
+[5]: http://svn.apache.org/repos/asf/felix/trunk/jaas/src/main/java/org/apache/felix/jaas/LoginModuleFactory.java
+[6]: http://svn.apache.org/repos/asf/felix/trunk/examples/jaas/app/src/main/java/org/apache/felix/example/jaas/app/internal/FactoryDemoServlet.java
+[7]: http://svn.apache.org/repos/asf/felix/trunk/examples/jaas/app/src/main/java/org/apache/felix/example/jaas/app/internal/BootClasspathDemoServlet.java
\ No newline at end of file