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