FELIX-3984 - Use default application/realm name of 'other' if none specified

Adding support for defaulting to realmName of 'other' (unless overridden by config) if the LoginModule does not specify one

git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@1459204 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/jaas/src/main/java/org/apache/felix/jaas/LoginContextFactory.java b/jaas/src/main/java/org/apache/felix/jaas/LoginContextFactory.java
index 59e1143..431a8e6 100644
--- a/jaas/src/main/java/org/apache/felix/jaas/LoginContextFactory.java
+++ b/jaas/src/main/java/org/apache/felix/jaas/LoginContextFactory.java
@@ -25,9 +25,31 @@
 import javax.security.auth.login.LoginException;
 
 
+/**
+ * A factory for creating {@link LoginContext} instances.
+ *
+ * <p>Instead of directly creating {@link LoginContext} this factory can be used. It takes care of
+ * locating the {@link javax.security.auth.login.Configuration} instance and switching of Thread's context
+ * classloader.
+ */
 public interface LoginContextFactory
 {
-
+    /**
+     * Instantiate a new <code>LoginContext</code> object with a name, a <code>Subject</code> to be authenticated,
+     * and a <code>CallbackHandler</code> object.
+     *
+     * @param realm realm or application name
+     * @param subject the <code>Subject</code> to authenticate.
+     * @param handler  the <code>CallbackHandler</code> object used by
+     *		LoginModules to communicate with the user.
+     *
+     * @return created LoginContext
+     *
+     * @exception LoginException if the caller-specified <code>name</code>  does not appear in
+     *          the <code>Configuration</code>  and there is no <code>Configuration</code> entry
+     *          for "<i>other</i>", or if the caller-specified <code>subject</code> is <code>null</code>,
+     *		    or if the caller-specified <code>callbackHandler</code> is <code>null</code>.
+     */
     LoginContext createLoginContext(String realm, Subject subject, CallbackHandler handler) throws LoginException;
 
 }
diff --git a/jaas/src/main/java/org/apache/felix/jaas/LoginModuleFactory.java b/jaas/src/main/java/org/apache/felix/jaas/LoginModuleFactory.java
index d613791..8c3ea01 100644
--- a/jaas/src/main/java/org/apache/felix/jaas/LoginModuleFactory.java
+++ b/jaas/src/main/java/org/apache/felix/jaas/LoginModuleFactory.java
@@ -22,7 +22,7 @@
 import javax.security.auth.spi.LoginModule;
 
 /**
- * 
+ * A factory for creating {@link LoginModule} instances.
  */
 public interface LoginModuleFactory
 {
diff --git a/jaas/src/main/java/org/apache/felix/jaas/internal/ConfigSpiOsgi.java b/jaas/src/main/java/org/apache/felix/jaas/internal/ConfigSpiOsgi.java
index 671342b..960e039 100644
--- a/jaas/src/main/java/org/apache/felix/jaas/internal/ConfigSpiOsgi.java
+++ b/jaas/src/main/java/org/apache/felix/jaas/internal/ConfigSpiOsgi.java
@@ -73,7 +73,13 @@
 
     private final Logger log;
 
-    private static final String DEFAULT_REALM_NAME = "default";
+    /**
+     * This is the name of application/realm used by LoginContext if no
+     * AppConfigurationEntry is found for the appName which is passed while constructing it.
+     *
+     * In case it does not find any config it looks for config entry for an app named 'other'
+     */
+    private static final String DEFAULT_REALM_NAME = "other";
 
     @Property
     private static final String JAAS_DEFAULT_REALM_NAME = "jaas.defaultRealmName";
@@ -134,11 +140,6 @@
     public LoginContext createLoginContext(String realm, Subject subject,
         CallbackHandler handler) throws LoginException
     {
-        if (realm == null)
-        {
-            realm = defaultRealmName;
-        }
-
         final Thread currentThread = Thread.currentThread();
         final ClassLoader cl = currentThread.getContextClassLoader();
         try
diff --git a/jaas/src/test/java/org/apache/felix/jaas/integration/ITJaasWithConfigBasedLoginModule.java b/jaas/src/test/java/org/apache/felix/jaas/integration/ITJaasWithConfigBasedLoginModule.java
index b67fc67..0c37424 100644
--- a/jaas/src/test/java/org/apache/felix/jaas/integration/ITJaasWithConfigBasedLoginModule.java
+++ b/jaas/src/test/java/org/apache/felix/jaas/integration/ITJaasWithConfigBasedLoginModule.java
@@ -30,6 +30,7 @@
 import java.util.Dictionary;
 import java.util.Hashtable;
 import java.util.List;
+import java.util.Properties;
 
 import javax.inject.Inject;
 import javax.security.auth.Subject;
@@ -217,4 +218,46 @@
 
     }
 
+    @Test
+    public void testJaasConfigWithEmptyRealm() throws Exception {
+        String realmName = name.getMethodName();
+        createConfigSpiConfig();
+
+        //Scenario 1 - Create a config with no realm name set. So its default name would
+        //be set to the defaultRealmName setting of ConfigurationSpi. Which defaults to 'other'
+        org.osgi.service.cm.Configuration config =
+                ca.createFactoryConfiguration("org.apache.felix.jaas.Configuration.factory",null);
+        Dictionary<String,Object> dict = new Hashtable<String, Object>();
+        dict.put("jaas.classname", "org.apache.felix.jaas.integration.sample1.ConfigLoginModule");
+
+        config.update(dict);
+        delay();
+
+        CallbackHandler handler = new SimpleCallbackHandler("foo","foo");
+
+        Subject s = new Subject();
+        LoginContext lc = loginContextFactory.createLoginContext(realmName, s, handler);
+        lc.login();
+
+        assertFalse(s.getPrincipals().isEmpty());
+
+
+        //Scenario 2 - Now we change the default realm name to 'default' and we do not have any login module which
+        //is bound to 'other' as they get part of 'default'. In this case login should fail
+        org.osgi.service.cm.Configuration config2 = ca.getConfiguration("org.apache.felix.jaas.ConfigurationSpi",null);
+        Properties p2 = new Properties();
+        p2.setProperty("jaas.defaultRealmName","default");
+        config2.update(p2);
+        delay();
+
+        try{
+            Subject s2 = new Subject();
+            LoginContext lc2 = loginContextFactory.createLoginContext(realmName, s2, handler);
+            lc2.login();
+            fail("Should have failed as no LoginModule bound with 'other'");
+        }catch(LoginException e){
+
+        }
+    }
+
 }