[jboss-cvs] JBossAS SVN: r109516 - projects/security/security-negotiation/branches/dlofthouse/SECURITY-132/jboss-negotiation-spnego/src/main/java/org/jboss/security/negotiation/spnego.

jboss-cvs-commits at lists.jboss.org jboss-cvs-commits at lists.jboss.org
Sat Nov 27 13:52:54 EST 2010


Author: darran.lofthouse at jboss.com
Date: 2010-11-27 13:52:54 -0500 (Sat, 27 Nov 2010)
New Revision: 109516

Modified:
   projects/security/security-negotiation/branches/dlofthouse/SECURITY-132/jboss-negotiation-spnego/src/main/java/org/jboss/security/negotiation/spnego/SPNEGOLoginModule.java
Log:
Add implementation to SPNEGO Login Module to delegate to additional domain.

Modified: projects/security/security-negotiation/branches/dlofthouse/SECURITY-132/jboss-negotiation-spnego/src/main/java/org/jboss/security/negotiation/spnego/SPNEGOLoginModule.java
===================================================================
--- projects/security/security-negotiation/branches/dlofthouse/SECURITY-132/jboss-negotiation-spnego/src/main/java/org/jboss/security/negotiation/spnego/SPNEGOLoginModule.java	2010-11-27 18:00:06 UTC (rev 109515)
+++ projects/security/security-negotiation/branches/dlofthouse/SECURITY-132/jboss-negotiation-spnego/src/main/java/org/jboss/security/negotiation/spnego/SPNEGOLoginModule.java	2010-11-27 18:52:54 UTC (rev 109516)
@@ -30,6 +30,7 @@
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
+import java.util.Set;
 
 import javax.security.auth.Subject;
 import javax.security.auth.callback.CallbackHandler;
@@ -42,7 +43,6 @@
 import org.ietf.jgss.GSSManager;
 import org.ietf.jgss.Oid;
 import org.jboss.security.SimpleGroup;
-import org.jboss.security.auth.spi.AbstractServerLoginModule;
 import org.jboss.security.negotiation.NegotiationMessage;
 import org.jboss.security.negotiation.common.CommonLoginModule;
 import org.jboss.security.negotiation.common.NegotiationContext;
@@ -60,17 +60,42 @@
 public class SPNEGOLoginModule extends CommonLoginModule
 {
 
-   private static final String SPNEGO = "SPNEGO";
+   /*
+    * Configuration Option Constants 
+    */
 
+   // If true drop the @REALM from the identity.
    private static final String REMOVE_REALM_FROM_PRINCIPAL = "removeRealmFromPrincipal";
 
+   // The security domain to authenticate to obtain the servers identity.
+   private static final String SERVER_SECURITY_DOMAIN = "serverSecurityDomain";
+
+   // The security domain to delegate username/password authentication to.
+   private static final String USERNAME_PASSWORD_DOMAIN = "usernamePasswordDomain";
+
+   /*
+    *  General Constants
+    */
+
+   private static final String SPNEGO = "SPNEGO";
+
    private static final Oid kerberos = KERBEROS_V5;
 
+   /*
+    * Configuration Options
+    */
+
+   private boolean removeRealmFromPrincipal;
+
    // TODO - Pick a name for a default domain?
    private String serverSecurityDomain;
 
-   private boolean removeRealmFromPrincipal;
+   private String usernamePasswordDomain;
 
+   /*
+    * Module State
+    */
+
    private LoginContext serverLoginContext = null;
 
    @Override
@@ -80,15 +105,21 @@
       super.initialize(subject, callbackHandler, sharedState, options);
       String temp;
       // Which security domain to authenticate the server.
-      serverSecurityDomain = (String) options.get("serverSecurityDomain");
-      if (log.isDebugEnabled())
-         log.debug("serverSecurityDomain=" + serverSecurityDomain);
+      serverSecurityDomain = (String) options.get(SERVER_SECURITY_DOMAIN);
+      // Which security domain to delegate username/password authentication to.
+      usernamePasswordDomain = (String) options.get(USERNAME_PASSWORD_DOMAIN);
       temp = (String) options.get(REMOVE_REALM_FROM_PRINCIPAL);
       removeRealmFromPrincipal = Boolean.valueOf(temp);
       if (removeRealmFromPrincipal == false && principalClassName == null)
       {
          principalClassName = KerberosPrincipal.class.getName();
       }
+      if (log.isDebugEnabled())
+      {
+         log.debug("removeRealmFromPrincipal=" + removeRealmFromPrincipal);
+         log.debug("serverSecurityDomain=" + serverSecurityDomain);
+         log.debug("usernamePasswordDomain=" + usernamePasswordDomain);
+      }
    }
 
    @Override
@@ -103,7 +134,94 @@
 
       super.loginOk = false;
 
+      Object result = innerLogin();
+
+      if (TRACE)
+         log.trace("Result - " + result);
+
+      if (result instanceof Boolean)
+      {
+         if (Boolean.TRUE.equals(result))
+         {
+            super.loginOk = true;
+            if (getUseFirstPass() == true)
+            {
+               Principal identity = getIdentity();
+               String userName = identity.getName();
+               if (log.isDebugEnabled())
+                  log.debug("Storing username '" + userName + "' and empty password");
+               // Add the username and a null password to the shared state map
+               sharedState.put("javax.security.auth.login.name", identity);
+               sharedState.put("javax.security.auth.login.password", "");
+            }
+         }
+      }
+      else if (result instanceof Exception)
+      {
+         Exception e = (Exception) result;
+         log.error("Unable to authenticate", e);
+         throw new LoginException("Unable to authenticate - " + e.getMessage());
+      }
+
+      if (TRACE)
+         log.trace("super.loginOk " + super.loginOk);
+      if (super.loginOk == true)
+      {
+         return true;
+      }
+      else
+      {
+         throw new LoginException("Continuation Required.");
+      }
+
+   }
+
+   protected Object innerLogin() throws LoginException
+   {
       NegotiationContext negotiationContext = NegotiationContext.getCurrentNegotiationContext();
+
+      if (negotiationContext == null)
+      {
+         if (usernamePasswordDomain == null)
+         {
+            throw new LoginException("No NegotiationContext and no usernamePasswordDomain defined.");
+         }
+
+         return usernamePasswordLogin();
+      }
+      else
+      {
+         return spnegoLogin(negotiationContext);
+      }
+
+   }
+
+   private Object usernamePasswordLogin() throws LoginException
+   {
+      log.debug("Falling back to username/password authentication");
+
+      LoginContext lc = new LoginContext(usernamePasswordDomain, callbackHandler);
+      lc.login();
+
+      Subject userSubject = lc.getSubject();
+      Set principals = userSubject.getPrincipals();
+      if (principals.isEmpty())
+      {
+         throw new LoginException("No principal returned after login.");
+      }
+      else if (principals.size() > 1)
+      {
+         log.warn("Multiple principals returned, using first principal in set.");
+      }
+
+      Principal identity = (Principal) principals.iterator().next();
+      setIdentity(identity);
+
+      return Boolean.TRUE;
+   }
+
+   private Object spnegoLogin(NegotiationContext negotiationContext) throws LoginException
+   {
       NegotiationMessage requestMessage = negotiationContext.getRequestMessage();
       if (requestMessage instanceof SPNEGOMessage == false)
       {
@@ -118,33 +236,7 @@
          AcceptSecContext action = new AcceptSecContext(negotiationContext);
          Object result = Subject.doAs(server, action);
 
-         if (TRACE)
-            log.trace("Result - " + result);
-
-         if (result instanceof Boolean)
-         {
-            if (Boolean.TRUE.equals(result))
-            {
-               super.loginOk = true;
-               if (getUseFirstPass() == true)
-               {
-                  Principal identity = getIdentity();
-                  String userName = identity.getName();
-                  if (log.isDebugEnabled())
-                     log.debug("Storing username '" + userName + "' and empty password");
-                  // Add the username and a null password to the shared state map
-                  sharedState.put("javax.security.auth.login.name", identity);
-                  sharedState.put("javax.security.auth.login.password", "");
-               }
-            }
-         }
-         else if (result instanceof Exception)
-         {
-            Exception e = (Exception) result;
-            log.error("Unable to authenticate", e);
-            throw new LoginException("Unable to authenticate - " + e.getMessage());
-         }
-
+         return result;
       }
       finally
       {
@@ -155,18 +247,8 @@
          }
       }
 
-      if (TRACE)
-         log.trace("super.loginOk " + super.loginOk);
-      if (super.loginOk == true)
-      {
-         return true;
-      }
-      else
-      {
-         throw new LoginException("Continuation Required.");
-      }
-
    }
+   
 
    @Override
    protected Principal createIdentity(final String username) throws Exception



More information about the jboss-cvs-commits mailing list