You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@shiro.apache.org by lh...@apache.org on 2009/05/30 02:42:30 UTC

svn commit: r780154 - in /incubator/jsecurity/trunk: core/src/main/java/org/apache/ki/authc/ core/src/main/java/org/apache/ki/mgt/ core/src/main/java/org/apache/ki/realm/ core/src/main/java/org/apache/ki/realm/activedirectory/ core/src/main/java/org/ap...

Author: lhazlewood
Date: Sat May 30 00:42:29 2009
New Revision: 780154

URL: http://svn.apache.org/viewvc?rev=780154&view=rev
Log:
Began preparing for new Factory style methods - added SessionManager#createSession(Map) and adjusted SessionFactory to support this.  Current behavior is retained, just implemented in a different way.  Added AuthorizingRealm#getAvailablePrincipal utility method to eliminate duplicate code used across many realms.  Cleaned up much JavaDoc.

Modified:
    incubator/jsecurity/trunk/core/src/main/java/org/apache/ki/authc/Account.java
    incubator/jsecurity/trunk/core/src/main/java/org/apache/ki/mgt/SecurityManager.java
    incubator/jsecurity/trunk/core/src/main/java/org/apache/ki/mgt/SessionsSecurityManager.java
    incubator/jsecurity/trunk/core/src/main/java/org/apache/ki/realm/AuthorizingRealm.java
    incubator/jsecurity/trunk/core/src/main/java/org/apache/ki/realm/SimpleAccountRealm.java
    incubator/jsecurity/trunk/core/src/main/java/org/apache/ki/realm/activedirectory/ActiveDirectoryRealm.java
    incubator/jsecurity/trunk/core/src/main/java/org/apache/ki/realm/jdbc/JdbcRealm.java
    incubator/jsecurity/trunk/core/src/main/java/org/apache/ki/session/Session.java
    incubator/jsecurity/trunk/core/src/main/java/org/apache/ki/session/mgt/AbstractSessionManager.java
    incubator/jsecurity/trunk/core/src/main/java/org/apache/ki/session/mgt/AbstractValidatingSessionManager.java
    incubator/jsecurity/trunk/core/src/main/java/org/apache/ki/session/mgt/DefaultSessionManager.java
    incubator/jsecurity/trunk/core/src/main/java/org/apache/ki/session/mgt/ImmutableProxiedSession.java
    incubator/jsecurity/trunk/core/src/main/java/org/apache/ki/session/mgt/SessionFactory.java
    incubator/jsecurity/trunk/core/src/main/java/org/apache/ki/session/mgt/SessionManager.java
    incubator/jsecurity/trunk/core/src/main/java/org/apache/ki/session/mgt/SimpleSession.java
    incubator/jsecurity/trunk/core/src/main/java/org/apache/ki/session/mgt/SimpleSessionFactory.java
    incubator/jsecurity/trunk/core/src/main/java/org/apache/ki/subject/DelegatingSubject.java
    incubator/jsecurity/trunk/samples/standalone/src/main/java/MyRealm.java
    incubator/jsecurity/trunk/web/src/main/java/org/apache/ki/web/session/ServletContainerSessionManager.java

Modified: incubator/jsecurity/trunk/core/src/main/java/org/apache/ki/authc/Account.java
URL: http://svn.apache.org/viewvc/incubator/jsecurity/trunk/core/src/main/java/org/apache/ki/authc/Account.java?rev=780154&r1=780153&r2=780154&view=diff
==============================================================================
--- incubator/jsecurity/trunk/core/src/main/java/org/apache/ki/authc/Account.java (original)
+++ incubator/jsecurity/trunk/core/src/main/java/org/apache/ki/authc/Account.java Sat May 30 00:42:29 2009
@@ -22,10 +22,10 @@
 
 /**
  * An <tt>Account</tt> is a convenience interface that extends both {@link AuthenticationInfo} and
- * {@link org.apache.ki.authz.AuthorizationInfo} and represents authentication and authorization for a <em>single account</em> in a
+ * {@link AuthorizationInfo} and represents authentication and authorization for a <em>single account</em> in a
  * <em>single Realm</em>.
  * <p/>
- * This interface can be useful when an Realm implementation finds it more convenient to use a single object to
+ * This interface can be useful when a Realm implementation finds it more convenient to use a single object to
  * encapsulate both the authentication and authorization information used by both authc and authz operations.
  * <p/>
  * <b>Please Note</b>:  Since Ki sometimes logs account operations, please ensure your Account's <code>toString()</code>

Modified: incubator/jsecurity/trunk/core/src/main/java/org/apache/ki/mgt/SecurityManager.java
URL: http://svn.apache.org/viewvc/incubator/jsecurity/trunk/core/src/main/java/org/apache/ki/mgt/SecurityManager.java?rev=780154&r1=780153&r2=780154&view=diff
==============================================================================
--- incubator/jsecurity/trunk/core/src/main/java/org/apache/ki/mgt/SecurityManager.java (original)
+++ incubator/jsecurity/trunk/core/src/main/java/org/apache/ki/mgt/SecurityManager.java Sat May 30 00:42:29 2009
@@ -30,30 +30,30 @@
 /**
  * A <tt>SecurityManager</tt> executes all security operations for <em>all</em> Subjects (aka users) across a
  * single application.
- *
+ * <p/>
  * <p>The interface itself primarily exists as a convenience - it extends the {@link org.apache.ki.authc.Authenticator},
  * {@link Authorizer}, and {@link SessionManager} interfaces, thereby consolidating
  * these behaviors into a single point of reference.  For most Ki usages, this simplifies configuration and
  * tends to be a more convenient approach than referencing <code>Authenticator</code>, <code>Authorizer</code>, and
  * <code>SessionManager</code> instances seperately;  instead one only needs to interact with a
  * single <tt>SecurityManager</tt> instance.</p>
- *
+ * <p/>
  * <p>In addition to the above three interfaces, three unique methods are provided by this interface by itself,
  * {@link #login}, {@link #logout} and {@link #getSubject}.  A {@link org.apache.ki.subject.Subject Subject} executes
  * authentication, authorization, and session operations for a <em>single</em> user, and as such can only be
  * managed by <tt>A SecurityManager</tt> which is aware of all three functions.  The three parent interfaces on the
  * other hand do not 'know' about <tt>Subject</tt>s to ensure a clean separation of concerns.
- *
+ * <p/>
  * <p><b>Usage Note</b>: In actuality the large majority of application programmers won't interact with a SecurityManager
  * very often, if at all.  <em>Most</em> application programmers only care about security operations for the currently
  * executing user.
- *
+ * <p/>
  * <p>In that case, the application programmer can call the
  * {@link #getSubject() getSubject()} method and then use that returned instance for continued interaction with
  * Ki.  If your application code does not have a direct handle to the application's
  * <code>SecurityManager</code>, you can use {@link org.apache.ki.SecurityUtils SecurityUtils} anywhere in your code
  * to achieve the same result.
- *
+ * <p/>
  * <p>Framework developers on the other hand might find working with an actual SecurityManager useful.
  *
  * @author Les Hazlewood
@@ -75,14 +75,15 @@
      *
      * @param authenticationToken the token representing the Subject's principal(s) and credential(s)
      * @return an authenticated Subject upon a successful attempt
-     * @throws org.apache.ki.authc.AuthenticationException if the login attempt failed.
+     * @throws org.apache.ki.authc.AuthenticationException
+     *          if the login attempt failed.
      * @since 0.9
      */
     Subject login(AuthenticationToken authenticationToken) throws AuthenticationException;
 
     /**
      * Logs out the specified Subject from the system.
-     *
+     * <p/>
      * <p>Note that most application developers should not call this method unless they have a good reason for doing
      * so.  The preferred way to logout a Subject is to call <code>{@link org.apache.ki.subject.Subject#logout Subject.logout()}</code>, not
      * the <code>SecurityManager</code> directly.
@@ -102,4 +103,10 @@
      * @since 0.9
      */
     Subject getSubject();
+
+    /*Subject getSubject(Map initData);
+
+    Subject getSubjectBySessionId(Serializable sessionId);
+
+    Subject getSubject(PrincipalCollection principals);*/
 }

Modified: incubator/jsecurity/trunk/core/src/main/java/org/apache/ki/mgt/SessionsSecurityManager.java
URL: http://svn.apache.org/viewvc/incubator/jsecurity/trunk/core/src/main/java/org/apache/ki/mgt/SessionsSecurityManager.java?rev=780154&r1=780153&r2=780154&view=diff
==============================================================================
--- incubator/jsecurity/trunk/core/src/main/java/org/apache/ki/mgt/SessionsSecurityManager.java (original)
+++ incubator/jsecurity/trunk/core/src/main/java/org/apache/ki/mgt/SessionsSecurityManager.java Sat May 30 00:42:29 2009
@@ -18,7 +18,7 @@
  */
 package org.apache.ki.mgt;
 
-import org.apache.ki.authz.HostUnauthorizedException;
+import org.apache.ki.authz.AuthorizationException;
 import org.apache.ki.cache.CacheManagerAware;
 import org.apache.ki.session.InvalidSessionException;
 import org.apache.ki.session.Session;
@@ -33,6 +33,7 @@
 import java.net.InetAddress;
 import java.util.Collection;
 import java.util.Date;
+import java.util.Map;
 
 
 /**
@@ -310,10 +311,14 @@
                 ((SessionListenerRegistrar) this.sessionManager).remove(listener);
     }
 
-    public Serializable start(InetAddress originatingHost) throws HostUnauthorizedException, IllegalArgumentException {
+    public Serializable start(InetAddress originatingHost) throws AuthorizationException {
         return this.sessionManager.start(originatingHost);
     }
 
+    public Serializable start(Map initData) throws AuthorizationException {
+        return this.sessionManager.start(initData);
+    }
+
     public Date getStartTimestamp(Serializable sessionId) {
         return this.sessionManager.getStartTimestamp(sessionId);
     }

Modified: incubator/jsecurity/trunk/core/src/main/java/org/apache/ki/realm/AuthorizingRealm.java
URL: http://svn.apache.org/viewvc/incubator/jsecurity/trunk/core/src/main/java/org/apache/ki/realm/AuthorizingRealm.java?rev=780154&r1=780153&r2=780154&view=diff
==============================================================================
--- incubator/jsecurity/trunk/core/src/main/java/org/apache/ki/realm/AuthorizingRealm.java (original)
+++ incubator/jsecurity/trunk/core/src/main/java/org/apache/ki/realm/AuthorizingRealm.java Sat May 30 00:42:29 2009
@@ -18,22 +18,8 @@
  */
 package org.apache.ki.realm;
 
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
 import org.apache.ki.authc.credential.CredentialsMatcher;
-import org.apache.ki.authz.AuthorizationException;
-import org.apache.ki.authz.AuthorizationInfo;
-import org.apache.ki.authz.AuthorizingAccount;
-import org.apache.ki.authz.Permission;
-import org.apache.ki.authz.UnauthorizedException;
+import org.apache.ki.authz.*;
 import org.apache.ki.authz.permission.PermissionResolver;
 import org.apache.ki.authz.permission.PermissionResolverAware;
 import org.apache.ki.authz.permission.WildcardPermissionResolver;
@@ -41,18 +27,22 @@
 import org.apache.ki.cache.CacheManager;
 import org.apache.ki.subject.PrincipalCollection;
 import org.apache.ki.util.Initializable;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.*;
 
 
 /**
  * An <tt>AuthorizingRealm</tt> extends the <tt>AuthenticatingRealm</tt>'s capabilities by adding Authorization
  * (access control) support.
- *
- * <p>This implementation will perform all role and permission checks automatically (and subclasses do not have to
+ * <p/>
+ * This implementation will perform all role and permission checks automatically (and subclasses do not have to
  * write this logic) as long as the
  * {@link #getAuthorizationInfo(org.apache.ki.subject.PrincipalCollection)} method returns an
  * {@link AuthorizationInfo}.  Please see that method's JavaDoc for an in-depth explanation.
- *
- * <p>If you find that you do not want to utilize the {@link AuthorizationInfo AuthorizationInfo} construct,
+ * <p/>
+ * If you find that you do not want to utilize the {@link AuthorizationInfo AuthorizationInfo} construct,
  * you are of course free to subclass the {@link AuthenticatingRealm AuthenticatingRealm} directly instead and
  * implement the remaining Realm interface methods directly.  You might do this if you want have better control
  * over how the Role and Permission checks occur for your specific data source.  However, using AuthorizationInfo
@@ -144,8 +134,8 @@
     ============================================*/
     /**
      * Initializes this realm and potentially enables a cache, depending on configuration.
-     *
-     * <p>When this method is called, the following logic is executed:
+     * <p/>
+     * When this method is called, the following logic is executed:
      * <ol>
      * <li>If the {@link #setAuthorizationCache cache} property has been set, it will be
      * used to cache the AuthorizationInfo objects returned from {@link #getAuthorizationInfo}
@@ -217,35 +207,33 @@
      * or <tt>null</tt> if no account could be found.  The resulting <code>AuthorizationInfo</code> object is used
      * by the other method implementations in this class to automatically perform access control checks for the
      * corresponding <code>Subject</code>.
-     *
-     * <p>This implementation obtains the actual <code>AuthorizationInfo</code> object from the subclass's
+     * <p/>
+     * This implementation obtains the actual <code>AuthorizationInfo</code> object from the subclass's
      * implementation of
      * {@link #doGetAuthorizationInfo(org.apache.ki.subject.PrincipalCollection) doGetAuthorizationInfo}, and then
      * caches it for efficient reuse if caching is enabled (see below).
-     *
-     * <p>Invocations of this method should be thought of as completely orthogonal to acquiring
+     * <p/>
+     * Invocations of this method should be thought of as completely orthogonal to acquiring
      * {@link #getAuthenticationInfo(org.apache.ki.authc.AuthenticationToken) authenticationInfo}, since either could
      * occur in any order.
-     *
-     * <p>For example, in &quot;Remember Me&quot; scenarios, the user identity is remembered (and
+     * <p/>
+     * For example, in &quot;Remember Me&quot; scenarios, the user identity is remembered (and
      * assumed) for their current session and an authentication attempt during that session might never occur.
      * But because their identity would be remembered, that is sufficient enough information to call this method to
      * execute any necessary authorization checks.  For this reason, authentication and authorization should be
      * loosely coupled and not depend on each other.
-     *
      * <h4>Caching</h4>
-     *
-     * <p>The <code>AuthorizationInfo</code> values returned from this method are cached for performant reuse
+     * The <code>AuthorizationInfo</code> values returned from this method are cached for performant reuse
      * if caching is enabled.  Caching is enabled automatically when a <code>CacheManager</code> has been
      * {@link #setCacheManager injected} and then the realm is {@link #init initialized}.  It can also be enabled by explictly
      * calling {@link #initAuthorizationCache() initAuthorizationCache()}.
-     *
-     * <p>If caching is enabled, the authorization cache will be checked first and if found, will return the cached
+     * <p/>
+     * If caching is enabled, the authorization cache will be checked first and if found, will return the cached
      * <code>AuthorizationInfo</code> immediately.  If caching is disabled, or there is a cache miss from the cache
      * lookup, the authorization info will be looked up from the underlying data store via the
      * {@link #doGetAuthorizationInfo(org.apache.ki.subject.PrincipalCollection)} method, which must be implemented by subclasses.
-     *
-     * <p><b>Please note:</b>  If caching is enabled and if any authorization data for an account is changed at
+     * <p/>
+     * <b>Please note:</b>  If caching is enabled and if any authorization data for an account is changed at
      * runtime, such as adding or removing roles and/or permissions, the subclass imlementation should clear the
      * cached AuthorizationInfo for that account via the
      * {@link #clearCachedAuthorizationInfo(org.apache.ki.subject.PrincipalCollection) clearCachedAuthorizationInfo}
@@ -258,7 +246,7 @@
      * @return the authorization information for the account associated with the specified <code>principals</code>,
      *         or <tt>null</tt> if no account could be found.
      */
-    public AuthorizationInfo getAuthorizationInfo(PrincipalCollection principals) {
+    protected AuthorizationInfo getAuthorizationInfo(PrincipalCollection principals) {
 
         if (principals == null) {
             return null;
@@ -322,7 +310,7 @@
      * @param principals the principals of the account for which to clear the cached AuthorizationInfo.
      */
     protected void clearCachedAuthorizationInfo(PrincipalCollection principals) {
-        if ( principals == null ) {
+        if (principals == null) {
             return;
         }
 
@@ -627,4 +615,42 @@
     public void onLogout(PrincipalCollection principals) {
         clearCachedAuthorizationInfo(principals);
     }
+
+    /**
+     * A utility method for subclasses that returns the first available principal of interest to this particular realm.
+     * The heuristic used to acquire the principal is as follows:
+     * <p/>
+     * <ul>
+     * <li>Attempt to get <em>this particular Realm's</em> 'primary' principal in the {@code PrincipalCollection} via a
+     * <code>principals.{@link PrincipalCollection#fromRealm(String) fromRealm}( {@link #getName() getName()} )</code>
+     * call.</li>
+     * <li>If the previous call does not result in any principals, attempt to get the overall 'primary' principal
+     * from the PrincipalCollection via a <code>principals.{@link PrincipalCollection#asList() asList()}.iterator().next()</code>
+     * call.</li>
+     * <li>If there are no principals from that call (or the PrincipalCollection argument was null to begin with),
+     * return {@code null}</li>
+     *
+     * @param principals the PrincipalCollection holding all principals (from all realms) assocatied with a single Subject.
+     * @return the 'primary' principal attributed to this particular realm, or the fallback 'master' principal if it
+     *         exists, or if not {@code null}.
+     * @since 1.0
+     */
+    protected Object getAvailablePrincipal(PrincipalCollection principals) {
+        if (principals == null || principals.isEmpty()) {
+            return null;
+        }
+        Object primary = null;
+        Collection thisPrincipals = principals.fromRealm(getName());
+        if (thisPrincipals != null && !thisPrincipals.isEmpty()) {
+            primary = thisPrincipals.iterator().next();
+        } else {
+            //no principals attributed to this particular realm.  Fall back to the 'master' primary, that which
+            //is returned as the first from all principals:
+            Collection allPrincipals = principals.asList();
+            if (allPrincipals != null && !allPrincipals.isEmpty()) {
+                primary = allPrincipals.iterator().next();
+            }
+        }
+        return primary;
+    }
 }

Modified: incubator/jsecurity/trunk/core/src/main/java/org/apache/ki/realm/SimpleAccountRealm.java
URL: http://svn.apache.org/viewvc/incubator/jsecurity/trunk/core/src/main/java/org/apache/ki/realm/SimpleAccountRealm.java?rev=780154&r1=780153&r2=780154&view=diff
==============================================================================
--- incubator/jsecurity/trunk/core/src/main/java/org/apache/ki/realm/SimpleAccountRealm.java (original)
+++ incubator/jsecurity/trunk/core/src/main/java/org/apache/ki/realm/SimpleAccountRealm.java Sat May 30 00:42:29 2009
@@ -18,32 +18,25 @@
  */
 package org.apache.ki.realm;
 
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-
-import org.apache.ki.authc.Account;
-import org.apache.ki.authc.AuthenticationException;
-import org.apache.ki.authc.AuthenticationInfo;
-import org.apache.ki.authc.AuthenticationToken;
-import org.apache.ki.authc.ExpiredCredentialsException;
-import org.apache.ki.authc.LockedAccountException;
-import org.apache.ki.authc.SimpleAccount;
-import org.apache.ki.authc.UsernamePasswordToken;
+import org.apache.ki.authc.*;
 import org.apache.ki.authz.AuthorizationInfo;
 import org.apache.ki.authz.SimpleAuthorizingAccount;
 import org.apache.ki.authz.SimpleRole;
 import org.apache.ki.subject.PrincipalCollection;
 import org.apache.ki.util.CollectionUtils;
 
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
 
 /**
  * <p>A simple implementation of the {@link Realm Realm} interface that
  * uses a set of configured user accounts and roles to support authentication and authorization.  Each account entry
  * specifies the username, password, and roles for a user.  Roles can also be mapped
  * to permissions and associated with users.</p>
- *
+ * <p/>
  * <p>User accounts and roles are stored in two {@link org.apache.ki.cache.Cache cache}s, so it is the Cache manager implementation that
  * determines if this class stores all data in memory or spools to disk or clusters it, etc based on the
  * Caches it creates.
@@ -93,7 +86,7 @@
     }
 
     public void addAccount(String username, String password) {
-        addAccount(username, password, (String[])null);
+        addAccount(username, password, (String[]) null);
     }
 
     public void addAccount(String username, String password, String... roles) {
@@ -147,7 +140,7 @@
         UsernamePasswordToken upToken = (UsernamePasswordToken) token;
         SimpleAccount account = (SimpleAccount) getAuthorizationCache().get(upToken.getUsername());
 
-        if( account != null ) {
+        if (account != null) {
 
             if (account.isLocked()) {
                 throw new LockedAccountException("Account [" + account + "] is locked.");
@@ -156,7 +149,7 @@
                 String msg = "The credentials for account [" + account + "] are expired";
                 throw new ExpiredCredentialsException(msg);
             }
-            
+
         }
 
         return account;
@@ -167,6 +160,6 @@
     }
 
     protected Object getAuthorizationCacheKey(PrincipalCollection principals) {
-        return principals.fromRealm(getName()).iterator().next(); //returns the username
+        return getAvailablePrincipal(principals); //returns the username, being the only principal from this Realm
     }
 }
\ No newline at end of file

Modified: incubator/jsecurity/trunk/core/src/main/java/org/apache/ki/realm/activedirectory/ActiveDirectoryRealm.java
URL: http://svn.apache.org/viewvc/incubator/jsecurity/trunk/core/src/main/java/org/apache/ki/realm/activedirectory/ActiveDirectoryRealm.java?rev=780154&r1=780153&r2=780154&view=diff
==============================================================================
--- incubator/jsecurity/trunk/core/src/main/java/org/apache/ki/realm/activedirectory/ActiveDirectoryRealm.java (original)
+++ incubator/jsecurity/trunk/core/src/main/java/org/apache/ki/realm/activedirectory/ActiveDirectoryRealm.java Sat May 30 00:42:29 2009
@@ -18,22 +18,6 @@
  */
 package org.apache.ki.realm.activedirectory;
 
-import java.util.Collection;
-import java.util.HashSet;
-import java.util.LinkedHashSet;
-import java.util.Map;
-import java.util.Set;
-import javax.naming.NamingEnumeration;
-import javax.naming.NamingException;
-import javax.naming.directory.Attribute;
-import javax.naming.directory.Attributes;
-import javax.naming.directory.SearchControls;
-import javax.naming.directory.SearchResult;
-import javax.naming.ldap.LdapContext;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
 import org.apache.ki.authc.AuthenticationInfo;
 import org.apache.ki.authc.AuthenticationToken;
 import org.apache.ki.authc.SimpleAuthenticationInfo;
@@ -45,13 +29,24 @@
 import org.apache.ki.realm.ldap.LdapContextFactory;
 import org.apache.ki.realm.ldap.LdapUtils;
 import org.apache.ki.subject.PrincipalCollection;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.naming.NamingEnumeration;
+import javax.naming.NamingException;
+import javax.naming.directory.Attribute;
+import javax.naming.directory.Attributes;
+import javax.naming.directory.SearchControls;
+import javax.naming.directory.SearchResult;
+import javax.naming.ldap.LdapContext;
+import java.util.*;
 
 
 /**
- * <p>An {@link Realm} that authenticates with an active directory LDAP
+ * A {@link Realm} that authenticates with an active directory LDAP
  * server to determine the roles for a particular user.  This implementation
  * queries for the user's groups and then maps the group names to roles using the
- * {@link #groupRolesMap}.</p>
+ * {@link #groupRolesMap}.
  *
  * @author Tim Veil
  * @author Jeremy Haile
@@ -94,11 +89,11 @@
 
 
     /**
-     * <p>Builds an {@link AuthenticationInfo} object by querying the active directory LDAP context for the
+     * Builds an {@link AuthenticationInfo} object by querying the active directory LDAP context for the
      * specified username.  This method binds to the LDAP server using the provided username and password -
-     * which if successful, indicates that the password is correct.</p>
-     *
-     * <p>This method can be overridden by subclasses to query the LDAP server in a more complex way.</p>
+     * which if successful, indicates that the password is correct.
+     * <p/>
+     * This method can be overridden by subclasses to query the LDAP server in a more complex way.
      *
      * @param token              the authentication token provided by the user.
      * @param ldapContextFactory the factory used to build connections to the LDAP server.
@@ -126,14 +121,14 @@
 
 
     /**
-     * <p>Builds an {@link org.apache.ki.authz.AuthorizationInfo} object by querying the active directory LDAP context for the
+     * Builds an {@link org.apache.ki.authz.AuthorizationInfo} object by querying the active directory LDAP context for the
      * groups that a user is a member of.  The groups are then translated to role names by using the
-     * configured {@link #groupRolesMap}.</p>
-     *
-     * <p>This implementation expects the <tt>principal</tt> argument to be a String username.
-     *
-     * <p>Subclasses can override this method to determine authorization data (roles, permissions, etc) in a more
-     * complex way.  Note that this default implementation does not support permissions, only roles.</p>
+     * configured {@link #groupRolesMap}.
+     * <p/>
+     * This implementation expects the <tt>principal</tt> argument to be a String username.
+     * <p/>
+     * Subclasses can override this method to determine authorization data (roles, permissions, etc) in a more
+     * complex way.  Note that this default implementation does not support permissions, only roles.
      *
      * @param principals         the principal of the Subject whose account is being retrieved.
      * @param ldapContextFactory the factory used to create LDAP connections.
@@ -142,10 +137,7 @@
      */
     protected AuthorizationInfo queryForAuthorizationInfo(PrincipalCollection principals, LdapContextFactory ldapContextFactory) throws NamingException {
 
-        String username;
-
-
-        username = (String) principals.fromRealm(getName()).iterator().next();
+        String username = (String) getAvailablePrincipal(principals);
 
         // Perform context search
         LdapContext ldapContext = ldapContextFactory.getSystemLdapContext();
@@ -173,7 +165,7 @@
         searchCtls.setSearchScope(SearchControls.SUBTREE_SCOPE);
 
         String userPrincipalName = username;
-        if( principalSuffix != null ) {
+        if (principalSuffix != null) {
             userPrincipalName += principalSuffix;
         }
 
@@ -241,5 +233,4 @@
         return roleNames;
     }
 
-
 }

Modified: incubator/jsecurity/trunk/core/src/main/java/org/apache/ki/realm/jdbc/JdbcRealm.java
URL: http://svn.apache.org/viewvc/incubator/jsecurity/trunk/core/src/main/java/org/apache/ki/realm/jdbc/JdbcRealm.java?rev=780154&r1=780153&r2=780154&view=diff
==============================================================================
--- incubator/jsecurity/trunk/core/src/main/java/org/apache/ki/realm/jdbc/JdbcRealm.java (original)
+++ incubator/jsecurity/trunk/core/src/main/java/org/apache/ki/realm/jdbc/JdbcRealm.java Sat May 30 00:42:29 2009
@@ -18,6 +18,17 @@
  */
 package org.apache.ki.realm.jdbc;
 
+import org.apache.ki.authc.*;
+import org.apache.ki.authz.AuthorizationException;
+import org.apache.ki.authz.AuthorizationInfo;
+import org.apache.ki.authz.SimpleAuthorizationInfo;
+import org.apache.ki.realm.AuthorizingRealm;
+import org.apache.ki.subject.PrincipalCollection;
+import org.apache.ki.util.JdbcUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.sql.DataSource;
 import java.sql.Connection;
 import java.sql.PreparedStatement;
 import java.sql.ResultSet;
@@ -25,43 +36,19 @@
 import java.util.Collection;
 import java.util.LinkedHashSet;
 import java.util.Set;
-import javax.sql.DataSource;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import org.apache.ki.authc.AccountException;
-import org.apache.ki.authc.AuthenticationException;
-import org.apache.ki.authc.AuthenticationInfo;
-import org.apache.ki.authc.AuthenticationToken;
-import org.apache.ki.authc.SimpleAuthenticationInfo;
-import org.apache.ki.authc.UnknownAccountException;
-import org.apache.ki.authc.UsernamePasswordToken;
-import org.apache.ki.authz.AuthorizationException;
-import org.apache.ki.authz.AuthorizationInfo;
-import org.apache.ki.authz.SimpleAuthorizationInfo;
-import org.apache.ki.realm.AuthorizingRealm;
-import org.apache.ki.subject.PrincipalCollection;
-import org.apache.ki.util.JdbcUtils;
 
 
 /**
- * <p>
  * Realm that allows authentication and authorization via JDBC calls.  The default queries suggest a potential schema
  * for retrieving the user's password for authentication, and querying for a user's roles and permissions.  The
  * default queries can be overridden by setting the query properties of the realm.
- * </p>
- *
- * <p>
+ * <p/>
  * If the default implementation
  * of authentication and authorization cannot handle your schema, this class can be subclassed and the
  * appropriate methods overridden. (usually {@link #doGetAuthenticationInfo(org.apache.ki.authc.AuthenticationToken)},
  * {@link #getRoleNamesForUser(java.sql.Connection,String)}, and/or {@link #getPermissions(java.sql.Connection,String,java.util.Collection)}
- * </p>
- *
- * <p>
+ * <p/>
  * This realm supports caching by extending from {@link org.apache.ki.realm.AuthorizingRealm}.
- * </p>
  *
  * @author Jeremy Haile
  * @since 0.2
@@ -149,16 +136,15 @@
     }
 
     /**
-     * <p>
      * Overrides the default query used to retrieve a user's permissions during authorization.  When using the default
      * implementation, this query must take a role name as the single parameter and return a row
      * per permission with three columns containing the fully qualified name of the permission class, the permission
      * name, and the permission actions (in that order).  If you require a solution that does not match this query
      * structure, you can override {@link #doGetAuthorizationInfo(org.apache.ki.subject.PrincipalCollection)} or just
      * {@link #getPermissions(java.sql.Connection,String,java.util.Collection)}</p>
-     *
-     * <p><b>Permissions are only retrieved if you set {@link #permissionsLookupEnabled} to true.  Otherwise,
-     * this query is ignored.</b></p>
+     * <p/>
+     * <b>Permissions are only retrieved if you set {@link #permissionsLookupEnabled} to true.  Otherwise,
+     * this query is ignored.</b>
      *
      * @param permissionsQuery the query to use for retrieving permissions for a role.
      * @see #DEFAULT_PERMISSIONS_QUERY
@@ -262,7 +248,7 @@
      * This implementation of the interface expects the principals collection to return a String username keyed off of
      * this realm's {@link #getName() name}
      *
-     * @see AuthorizingRealm#getAuthorizationInfo(org.apache.ki.subject.PrincipalCollection)
+     * @see #getAuthorizationInfo(org.apache.ki.subject.PrincipalCollection)
      */
     @Override
     protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
@@ -272,7 +258,7 @@
             throw new AuthorizationException("PrincipalCollection method argument cannot be null.");
         }
 
-        String username = (String) principals.fromRealm(getName()).iterator().next();
+        String username = (String) getAvailablePrincipal(principals);
 
         Connection conn = null;
         Set<String> roleNames = null;
@@ -282,7 +268,7 @@
 
             // Retrieve roles and permissions from database
             roleNames = getRoleNamesForUser(conn, username);
-            if( permissionsLookupEnabled ) {
+            if (permissionsLookupEnabled) {
                 permissions = getPermissions(conn, username, roleNames);
             }
 
@@ -299,7 +285,7 @@
         }
 
         SimpleAuthorizationInfo info = new SimpleAuthorizationInfo(roleNames);
-        info.setStringPermissions( permissions );
+        info.setStringPermissions(permissions);
         return info;
 
     }

Modified: incubator/jsecurity/trunk/core/src/main/java/org/apache/ki/session/Session.java
URL: http://svn.apache.org/viewvc/incubator/jsecurity/trunk/core/src/main/java/org/apache/ki/session/Session.java?rev=780154&r1=780153&r2=780154&view=diff
==============================================================================
--- incubator/jsecurity/trunk/core/src/main/java/org/apache/ki/session/Session.java (original)
+++ incubator/jsecurity/trunk/core/src/main/java/org/apache/ki/session/Session.java Sat May 30 00:42:29 2009
@@ -24,13 +24,13 @@
 import java.util.Date;
 
 /**
- * A <tt>Session</tt> is a stateful data context associated with a single Subject (user, 3rd party process,
+ * A {@code Session} is a stateful data context associated with a single Subject (user, 3rd party process,
  * etc) who interacts with a software system over a period of time.
- *
- * <p>A <tt>Session</tt> is intended to be managed by the business tier and accessible via other
+ * <p/>
+ * A {@code Session} is intended to be managed by the business tier and accessible via other
  * tiers without being tied to any given client technology.  This is a <em>great</em> benefit to Java
  * systems, since until now, the only viable session mechanisms were the
- * {@link javax.servlet.http.HttpSession HttpSession} or Stateful Session EJB's, which many times
+ * {@code javax.servlet.http.HttpSession} or Stateful Session EJB's, which many times
  * unnecessarily coupled applications to web or ejb technologies.
  *
  * @author Les Hazlewood
@@ -40,9 +40,9 @@
 
     /**
      * Returns the unique identifier assigned by the system upon session creation.
-     *
-     * <p>All return values from this method are expected to have proper <code>toString()</code>,
-     * <code>equals()</code>, and <code>hashCode()</code> implementations. Good candiadates for such
+     * <p/>
+     * All return values from this method are expected to have proper {@code toString()},
+     * {@code equals()}, and {@code hashCode()} implementations. Good candiadates for such
      * an identifier are {@link java.util.UUID UUID}s, {@link java.lang.Integer Integer}s, and
      * {@link java.lang.String String}s.
      *
@@ -67,62 +67,64 @@
 
     /**
      * Returns the time in milliseconds that the session session may remain idle before expiring.
-     *
      * <ul>
      * <li>A negative return value means the session will never expire.</li>
      * <li>A non-negative return value (0 or greater) means the session expiration will occur if idle for that
      * length of time.</li>
      * </ul>
+     * <b>*Note:</b> if you are used to the {@code HttpSession}'s {@code getMaxInactiveInterval()} method, the scale on
+     * this method is different: Ki Sessions use millisecond values for timeout whereas
+     * {@code HttpSession.getMaxInactiveInterval} uses seconds.  Always use millisecond values with Ki sessions.
      *
      * @return the time in milliseconds the session may remain idle before expiring.
-     * @throws InvalidSessionException
-     *          if the session has been stopped or expired prior to calling this method.
+     * @throws InvalidSessionException if the session has been stopped or expired prior to calling this method.
      * @since 0.2
      */
     long getTimeout() throws InvalidSessionException;
 
     /**
      * Sets the time in milliseconds that the session may remain idle before expiring.
-     *
      * <ul>
      * <li>A negative return value means the session will never expire.</li>
      * <li>A non-negative return value (0 or greater) means the session expiration will occur if idle for that
      * length of time.</li>
      * </ul>
+     * <p/>
+     * <b>*Note:</b> if you are used to the {@code HttpSession}'s {@code getMaxInactiveInterval()} method, the scale on
+     * this method is different: Ki Sessions use millisecond values for timeout whereas
+     * {@code HttpSession.getMaxInactiveInterval} uses seconds.  Always use millisecond values with Ki sessions.
      *
      * @param maxIdleTimeInMillis the time in milliseconds that the session may remain idle before expiring.
-     * @throws InvalidSessionException
-     *          if the session has been stopped or expired prior to calling this method.
+     * @throws InvalidSessionException if the session has been stopped or expired prior to calling this method.
      * @since 0.2
      */
     void setTimeout(long maxIdleTimeInMillis) throws InvalidSessionException;
 
-
     /**
-     * Returns the <tt>InetAddress</tt> of the host that originated this session, or <tt>null</tt>
+     * Returns the {@code InetAddress} of the host that originated this session, or {@code null}
      * if the host address is unknown.
      *
-     * @return the <tt>InetAddress</tt> of the host that originated this session, or <tt>null</tt>
+     * @return the {@code InetAddress} of the host that originated this session, or {@code null}
      *         if the host address is unknown.
      * @see org.apache.ki.session.mgt.SessionManager#start(java.net.InetAddress)
      */
     InetAddress getHostAddress();
 
     /**
-     * Explicitly updates the {@link #getLastAccessTime() lastAccessTime} of this session.  This
-     * method can be used to ensure a session does not time out.
-     *
-     * <p>Most programmers won't use this method explicitly and will instead rely calling the other Session methods
+     * Explicitly updates the {@link #getLastAccessTime() lastAccessTime} of this session to the current time when
+     * this method is invoked.  This method can be used to ensure a session does not time out.
+     * <p/>
+     * Most programmers won't use this method explicitly and will instead rely calling the other Session methods
      * to update the time transparently, or on a framework during a remote procedure call or upon a web request.
-     *
-     * <p>This method is particularly useful however when supporting rich-client applications such as
+     * <p/>
+     * This method is particularly useful however when supporting rich-client applications such as
      * Java Web Start appp, Java or Flash applets, etc.  Although rare, it is possible in a rich-client
      * environment that a user continuously interacts with the client-side application without a
      * server-side method call ever being invoked.  If this happens over a long enough period of
      * time, the user's server-side session could time-out.  Again, such cases are rare since most
      * rich-clients frequently require server-side method invocations.
-     *
-     * <p>In this example though, the user's session might still be considered valid because
+     * <p/>
+     * In this example though, the user's session might still be considered valid because
      * the user is actively &quot;using&quot; the application, just not communicating with the
      * server. But because no server-side method calls are invoked, there is no way for the server
      * to know if the user is sitting idle or not, so it must assume so to maintain session
@@ -130,8 +132,8 @@
      * times to ensure that the next time a server-side method is invoked, the invocation will not
      * throw an {@link ExpiredSessionException ExpiredSessionException}.  In short terms, it could be used periodically
      * to ensure a session does not time out.
-     *
-     * <p>How often this rich-client &quot;maintenance&quot; might occur is entirely dependent upon
+     * <p/>
+     * How often this rich-client &quot;maintenance&quot; might occur is entirely dependent upon
      * the application and would be based on variables such as session timeout configuration,
      * usage characteristics of the client application, network utilization and application server
      * performance.
@@ -143,17 +145,17 @@
 
     /**
      * Explicitly stops (invalidates) this session and releases all associated resources.
-     *
-     * <p>If this session has already been authenticated (i.e. the <code>Subject</code> that
+     * <p/>
+     * If this session has already been authenticated (i.e. the {@code Subject} that
      * owns this session has logged-in), calling this method explicitly might have undesired side effects:
      * <p/>
-     * It is common for a <code>Subject</code> implementation to retain authentication state in the
-     * <code>Session</code>.  If the session
+     * It is common for a {@code Subject} implementation to retain authentication state in the
+     * {@code Session}.  If the session
      * is explicitly stopped by application code by calling this method directly, it could clear out any
-     * authentication state that might exist, thereby effectively &quot;unauthenticating&quot; the <code>Subject</code>.
+     * authentication state that might exist, thereby effectively &quot;unauthenticating&quot; the {@code Subject}.
      * <p/>
      * As such, you might consider {@link org.apache.ki.subject.Subject#logout logging-out} the 'owning'
-     * <code>Subject</code> instead of manually calling this method, as a log out is expected to stop the
+     * {@code Subject} instead of manually calling this method, as a log out is expected to stop the
      * corresponding session automatically, and also allows framework code to execute additional cleanup logic.
      *
      * @throws InvalidSessionException if this session has stopped or expired prior to calling this method.
@@ -173,10 +175,10 @@
 
     /**
      * Returns the object bound to this session identified by the specified key.  If there is no
-     * object bound under the key, <tt>null</tt> is returned.
+     * object bound under the key, {@code null} is returned.
      *
      * @param key the unique name of the object bound to this session
-     * @return the object bound under the specified <tt>key</tt> name or <tt>null</tt> if there is
+     * @return the object bound under the specified {@code key} name or {@code null} if there is
      *         no object bound under that name.
      * @throws InvalidSessionException if this session has stopped or expired prior to calling
      *                                 this method.
@@ -184,14 +186,14 @@
     Object getAttribute(Object key) throws InvalidSessionException;
 
     /**
-     * Binds the specified <tt>value</tt> to this session, uniquely identified by the specifed
-     * <tt>key</tt> name.  If there is already an object bound under the <tt>key</tt> name, that
-     * existing object will be replaced by the new <tt>value</tt>.
-     *
-     * <p>If the <tt>value</tt> parameter is null, it has the same effect as if
-     * <tt>removeAttribute(key)</tt> was called.
+     * Binds the specified {@code value} to this session, uniquely identified by the specifed
+     * {@code key} name.  If there is already an object bound under the {@code key} name, that
+     * existing object will be replaced by the new {@code value}.
+     * <p/>
+     * If the {@code value} parameter is null, it has the same effect as if
+     * {@link #removeAttribute(Object) removeAttribute} was called.
      *
-     * @param key   the name under which the <tt>value</tt> object will be bound in this session
+     * @param key   the name under which the {@code value} object will be bound in this session
      * @param value the object to bind in this session.
      * @throws InvalidSessionException if this session has stopped or expired prior to calling
      *                                 this method.
@@ -199,11 +201,11 @@
     void setAttribute(Object key, Object value) throws InvalidSessionException;
 
     /**
-     * Removes (unbinds) the object bound to this session under the specified <tt>key</tt> name.
+     * Removes (unbinds) the object bound to this session under the specified {@code key} name.
      *
      * @param key the name uniquely identifying the object to remove
-     * @return the object removed or <tt>null</tt> if there was no object bound under the name
-     *         <tt>key</tt>.
+     * @return the object removed or {@code null} if there was no object bound under the name
+     *         {@code key}.
      * @throws InvalidSessionException if this session has stopped or expired prior to calling
      *                                 this method.
      */

Modified: incubator/jsecurity/trunk/core/src/main/java/org/apache/ki/session/mgt/AbstractSessionManager.java
URL: http://svn.apache.org/viewvc/incubator/jsecurity/trunk/core/src/main/java/org/apache/ki/session/mgt/AbstractSessionManager.java?rev=780154&r1=780153&r2=780154&view=diff
==============================================================================
--- incubator/jsecurity/trunk/core/src/main/java/org/apache/ki/session/mgt/AbstractSessionManager.java (original)
+++ incubator/jsecurity/trunk/core/src/main/java/org/apache/ki/session/mgt/AbstractSessionManager.java Sat May 30 00:42:29 2009
@@ -18,6 +18,7 @@
  */
 package org.apache.ki.session.mgt;
 
+import org.apache.ki.authz.AuthorizationException;
 import org.apache.ki.authz.HostUnauthorizedException;
 import org.apache.ki.session.*;
 import org.slf4j.Logger;
@@ -25,9 +26,7 @@
 
 import java.io.Serializable;
 import java.net.InetAddress;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Date;
+import java.util.*;
 
 
 /**
@@ -42,7 +41,9 @@
     protected static final long MILLIS_PER_MINUTE = 60 * MILLIS_PER_SECOND;
     protected static final long MILLIS_PER_HOUR = 60 * MILLIS_PER_MINUTE;
 
-    /** Default main session timeout value, equal to {@code 30} minutes. */
+    /**
+     * Default main session timeout value, equal to {@code 30} minutes.
+     */
     public static final long DEFAULT_GLOBAL_SESSION_TIMEOUT = 30 * MILLIS_PER_MINUTE;
 
     private static final Logger log = LoggerFactory.getLogger(AbstractSessionManager.class);
@@ -90,11 +91,7 @@
     }
 
     public void setSessionListeners(Collection<SessionListener> listeners) {
-        if (listeners == null) {
-            this.listeners = new ArrayList<SessionListener>();
-        } else {
-            this.listeners = listeners;
-        }
+        this.listeners = listeners != null ? listeners : new ArrayList<SessionListener>();
     }
 
     public void add(SessionListener listener) {
@@ -105,8 +102,17 @@
         return this.listeners.remove(listener);
     }
 
-    public Serializable start(InetAddress originatingHost) throws HostUnauthorizedException, IllegalArgumentException {
-        Session session = createSession(originatingHost);
+    public Serializable start(InetAddress originatingHost) throws AuthorizationException {
+        Map<String, InetAddress> initData = null;
+        if (originatingHost != null) {
+            initData = new HashMap<String, InetAddress>();
+            initData.put(SessionFactory.ORIGINATING_HOST_KEY, originatingHost);
+        }
+        return start(initData);
+    }
+
+    public Serializable start(Map initData) throws AuthorizationException {
+        Session session = createSession(initData);
         onStart(session);
         notifyStart(session);
         return session.getId();
@@ -265,17 +271,17 @@
     protected abstract Session doGetSession(Serializable sessionId) throws InvalidSessionException;
 
     /**
-     * Creates a new {@code Session Session} instance based on the specified (possibly {@code null}) originating host.
-     * Implementing classes must manage the persistent state of this session such that it could be acquired
-     * via the {@link #getSession(java.io.Serializable)} method.
+     * Creates a new {@code Session Session} instance based on the specified (possibly {@code null})
+     * initialization data.  Implementing classes must manage the persistent state of the returned session such that it
+     * could later be acquired via the {@link #getSession(java.io.Serializable)} method.
      *
-     * @param originatingHost the originating host InetAddress of the external party
-     *                        (user, 3rd party product, etc) that is attempting to initiate the session, or
-     *                        {@code null} if not known.
-     * @return a new {@code Session} instance.
-     * @throws HostUnauthorizedException if the specified host is not allowed to initiate a new session.
-     * @throws IllegalArgumentException  if the argiment is invalid, for example, if the underlying implementation
-     *                                   requires non-{@code null} values and the argument is {@code null}.
+     * @param initData the initialization data that can be used by the implementation or underlying
+     *                 {@link SessionFactory} when instantiating the internal {@code Session} instance.
+     * @return the new {@code Session} instance.
+     * @throws HostUnauthorizedException if the system access control policy restricts access based
+     *                                   on client location/IP and the specified hostAddress hasn't been enabled.
+     * @throws AuthorizationException    if the system access control policy does not allow the currently executing
+     *                                   caller to start sessions.
      */
-    protected abstract Session createSession(InetAddress originatingHost) throws HostUnauthorizedException, IllegalArgumentException;
+    protected abstract Session createSession(Map initData) throws AuthorizationException;
 }

Modified: incubator/jsecurity/trunk/core/src/main/java/org/apache/ki/session/mgt/AbstractValidatingSessionManager.java
URL: http://svn.apache.org/viewvc/incubator/jsecurity/trunk/core/src/main/java/org/apache/ki/session/mgt/AbstractValidatingSessionManager.java?rev=780154&r1=780153&r2=780154&view=diff
==============================================================================
--- incubator/jsecurity/trunk/core/src/main/java/org/apache/ki/session/mgt/AbstractValidatingSessionManager.java (original)
+++ incubator/jsecurity/trunk/core/src/main/java/org/apache/ki/session/mgt/AbstractValidatingSessionManager.java Sat May 30 00:42:29 2009
@@ -18,21 +18,21 @@
  */
 package org.apache.ki.session.mgt;
 
-import java.io.Serializable;
-import java.net.InetAddress;
-import java.util.Collection;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import org.apache.ki.authz.HostUnauthorizedException;
+import org.apache.ki.authz.AuthorizationException;
 import org.apache.ki.session.ExpiredSessionException;
 import org.apache.ki.session.InvalidSessionException;
-import org.apache.ki.session.Session;
 import org.apache.ki.session.ReplacedSessionException;
+import org.apache.ki.session.Session;
 import org.apache.ki.util.Destroyable;
 import org.apache.ki.util.LifecycleUtils;
 import org.apache.ki.util.ThreadContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.Serializable;
+import java.net.InetAddress;
+import java.util.Collection;
+import java.util.Map;
 
 
 /**
@@ -43,7 +43,7 @@
  * @since 0.1
  */
 public abstract class AbstractValidatingSessionManager extends AbstractSessionManager
-    implements ValidatingSessionManager, Destroyable {
+        implements ValidatingSessionManager, Destroyable {
 
     //TODO - complete JavaDoc
 
@@ -56,7 +56,9 @@
     public static final long DEFAULT_SESSION_VALIDATION_INTERVAL = MILLIS_PER_HOUR;
 
     protected boolean sessionValidationSchedulerEnabled = true; //default
-    /** Scheduler used to validate sessions on a regular basis. */
+    /**
+     * Scheduler used to validate sessions on a regular basis.
+     */
     protected SessionValidationScheduler sessionValidationScheduler = null;
 
     protected long sessionValidationInterval = DEFAULT_SESSION_VALIDATION_INTERVAL;
@@ -100,10 +102,10 @@
      * frequently session should be validated (to check for orphans).  The default value is
      * {@link #DEFAULT_SESSION_VALIDATION_INTERVAL}.
      * <p/>
-     * <p>If you override the default scheduler, it is assumed that overriding instance 'knows' how often to
+     * If you override the default scheduler, it is assumed that overriding instance 'knows' how often to
      * validate sessions, and this attribute will be ignored.
      * <p/>
-     * <p>Unless this method is called, the default value is {@link #DEFAULT_SESSION_VALIDATION_INTERVAL}.
+     * Unless this method is called, the default value is {@link #DEFAULT_SESSION_VALIDATION_INTERVAL}.
      *
      * @param sessionValidationInterval the time in milliseconds between checking for valid sessions to reap orphans.
      */
@@ -144,7 +146,7 @@
      * method invocations.
      *
      * @param autoCreateWhenInvalid if this session manager should automatically create a new session when an
-     *                                    invalid session is referenced
+     *                              invalid session is referenced
      */
     public void setAutoCreateWhenInvalid(boolean autoCreateWhenInvalid) {
         this.autoCreateWhenInvalid = autoCreateWhenInvalid;
@@ -172,8 +174,8 @@
                 }
                 Serializable newId = start(hostAddress);
                 String msg = "Session with id [" + sessionId + "] is invalid.  The SessionManager " +
-                    "has been configured to automatically re-create sessions upon invalidation.  Returnining " +
-                    "new session id [" + newId + "] with exception so the caller may react accordingly.";
+                        "has been configured to automatically re-create sessions upon invalidation.  Returnining " +
+                        "new session id [" + newId + "] with exception so the caller may react accordingly.";
                 throw new ReplacedSessionException(msg, ise, sessionId, newId);
             } else {
                 //propagate original exception:
@@ -182,8 +184,6 @@
         }
     }
 
-
-
     /**
      * Looks up a session from the underlying data store based on the specified {@code sessionId}.
      *
@@ -193,18 +193,18 @@
      */
     protected abstract Session retrieveSession(Serializable sessionId) throws InvalidSessionException;
 
-    protected final Session createSession(InetAddress originatingHost) throws HostUnauthorizedException, IllegalArgumentException {
+    protected Session createSession(Map initData) throws AuthorizationException {
         enableSessionValidationIfNecessary();
-        return doCreateSession(originatingHost);
+        return doCreateSession(initData);
     }
 
-    protected abstract Session doCreateSession(InetAddress originatingHost) throws HostUnauthorizedException, IllegalArgumentException;
+    protected abstract Session doCreateSession(Map initData) throws AuthorizationException;
 
     protected void validate(Session session) throws InvalidSessionException {
         try {
             doValidate(session);
         } catch (ExpiredSessionException ese) {
-            onExpiration(session);            
+            onExpiration(session);
             notifyExpiration(session);
             //propagate to caller:
             throw ese;
@@ -216,9 +216,9 @@
             ((ValidatingSession) session).validate();
         } else {
             String msg = "The " + getClass().getName() + " implementation only supports validating " +
-                "Session implementations of the " + ValidatingSession.class.getName() + " interface.  " +
-                "Please either implement this interface in your session implementation or override the " +
-                AbstractValidatingSessionManager.class.getName() + ".doValidate(Session) method to perform validation.";
+                    "Session implementations of the " + ValidatingSession.class.getName() + " interface.  " +
+                    "Please either implement this interface in your session implementation or override the " +
+                    AbstractValidatingSessionManager.class.getName() + ".doValidate(Session) method to perform validation.";
             throw new IllegalStateException(msg);
         }
     }
@@ -293,7 +293,9 @@
         disableSessionValidation();
     }
 
-    /** @see ValidatingSessionManager#validateSessions() */
+    /**
+     * @see ValidatingSessionManager#validateSessions()
+     */
     public void validateSessions() {
         if (log.isInfoEnabled()) {
             log.info("Validating all active sessions...");
@@ -311,7 +313,7 @@
                     if (log.isDebugEnabled()) {
                         boolean expired = (e instanceof ExpiredSessionException);
                         String msg = "Invalidated session with id [" + s.getId() + "]" +
-                            (expired ? " (expired)" : " (stopped)");
+                                (expired ? " (expired)" : " (stopped)");
                         log.debug(msg);
                     }
                     invalidCount++;

Modified: incubator/jsecurity/trunk/core/src/main/java/org/apache/ki/session/mgt/DefaultSessionManager.java
URL: http://svn.apache.org/viewvc/incubator/jsecurity/trunk/core/src/main/java/org/apache/ki/session/mgt/DefaultSessionManager.java?rev=780154&r1=780153&r2=780154&view=diff
==============================================================================
--- incubator/jsecurity/trunk/core/src/main/java/org/apache/ki/session/mgt/DefaultSessionManager.java (original)
+++ incubator/jsecurity/trunk/core/src/main/java/org/apache/ki/session/mgt/DefaultSessionManager.java Sat May 30 00:42:29 2009
@@ -30,10 +30,9 @@
 import org.slf4j.LoggerFactory;
 
 import java.io.Serializable;
-import java.net.InetAddress;
 import java.util.Collection;
 import java.util.Date;
-
+import java.util.Map;
 
 /**
  * Default business-tier implementation of a {@link ValidatingSessionManager}.  All session CRUD operations are
@@ -94,32 +93,17 @@
         }
     }
 
-    protected Session doCreateSession(InetAddress originatingHost) {
+    protected Session doCreateSession(Map initData) {
+        Session s = newSessionInstance(initData);
         if (log.isTraceEnabled()) {
-            log.trace("Creating session for originating host [" + originatingHost + "]");
+            log.trace("Creating session for host {}", s.getHostAddress());
         }
-        Session s = newSessionInstance(originatingHost);
         create(s);
         return s;
     }
 
-    protected Session newSessionInstance(InetAddress inetAddress) {
-        return createSessionFromFactory(inetAddress);
-    }
-
-    /**
-     * Creates a {@link Session} using the {@link #setSessionFactory(SessionFactory) configured} {@code SessionFactory}
-     * instance.
-     *
-     * @param originatingHost the originating host InetAddress of the external party
-     *                        (user, 3rd party product, etc) that is attempting to initiate the session, or
-     *                        {@code null} if not known.
-     * @return an new {@code Session} instance.
-     * @since 1.0
-     */
-    protected Session createSessionFromFactory(InetAddress originatingHost) {
-        SessionFactory factory = getSessionFactory();
-        return factory.createSession(originatingHost);
+    protected Session newSessionInstance(Map initData) {
+        return getSessionFactory().createSession(initData);
     }
 
     /**

Modified: incubator/jsecurity/trunk/core/src/main/java/org/apache/ki/session/mgt/ImmutableProxiedSession.java
URL: http://svn.apache.org/viewvc/incubator/jsecurity/trunk/core/src/main/java/org/apache/ki/session/mgt/ImmutableProxiedSession.java?rev=780154&r1=780153&r2=780154&view=diff
==============================================================================
--- incubator/jsecurity/trunk/core/src/main/java/org/apache/ki/session/mgt/ImmutableProxiedSession.java (original)
+++ incubator/jsecurity/trunk/core/src/main/java/org/apache/ki/session/mgt/ImmutableProxiedSession.java Sat May 30 00:42:29 2009
@@ -29,16 +29,13 @@
  * <p/>
  * The <code>Session</code> write operations are defined as follows.  A call to any of these methods on this
  * proxy will immediately result in an {@link InvalidSessionException} being thrown:
- *
  * <ul>
- * <li>{@link org.apache.ki.session.Session#setTimeout(long) Session.setTimeout(long)}</li>
+ * <li>{@link Session#setTimeout(long) Session.setTimeout(long)}</li>
  * <li>{@link Session#touch() Session.touch()}</li>
  * <li>{@link Session#stop() Session.stop()}</li>
  * <li>{@link Session#setAttribute(Object, Object) Session.setAttribute(key,value)}</li>
- * <li>{@link org.apache.ki.session.Session#removeAttribute(Object) Session.removeAttribute(key)}</li>
+ * <li>{@link Session#removeAttribute(Object) Session.removeAttribute(key)}</li>
  * </ul>
- *
- * <p/>
  * Any other method invocation not listed above will result in a corresponding call to the underlying <code>Session</code>.
  *
  * @author Les Hazlewood

Modified: incubator/jsecurity/trunk/core/src/main/java/org/apache/ki/session/mgt/SessionFactory.java
URL: http://svn.apache.org/viewvc/incubator/jsecurity/trunk/core/src/main/java/org/apache/ki/session/mgt/SessionFactory.java?rev=780154&r1=780153&r2=780154&view=diff
==============================================================================
--- incubator/jsecurity/trunk/core/src/main/java/org/apache/ki/session/mgt/SessionFactory.java (original)
+++ incubator/jsecurity/trunk/core/src/main/java/org/apache/ki/session/mgt/SessionFactory.java Sat May 30 00:42:29 2009
@@ -21,11 +21,14 @@
 import org.apache.ki.session.Session;
 
 import java.net.InetAddress;
+import java.util.Map;
 
 /**
- * A simple factory class that instantiates concrete {@link Session Session} instances.  This is mainly an
- * SPI mechanism to allow different concrete instances to be created at runtime if they need to be different the
- * defaults.  It is typically not used by end-users of the framework.
+ * A simple factory class that instantiates concrete {@link Session Session} instances.  This is mainly a
+ * mechanism to allow instances to be created at runtime if they need to be different the
+ * defaults.  It is not used by end-users of the framework, but rather those configuring Ki to work in an
+ * application, and is typically injected into the {@link org.apache.ki.mgt.SecurityManager SecurityManager} or a
+ * {@link SessionManager}.
  *
  * @author Les Hazlewood
  * @since 1.0
@@ -33,13 +36,19 @@
 public interface SessionFactory {
 
     /**
-     * Creates a new {@code Session} for the party with the given {@code originatinHost}.  The host argument may be
-     * {@code null} if unknown to the system.
+     * The key under which an originating host's {@link InetAddress InetAddress} may be found in the
+     * {@code initData} {@code Map} argument passed to the {@link #createSession(java.util.Map) createSession} method.
+     */
+    public static final String ORIGINATING_HOST_KEY = SessionFactory.class.getName() + ".originatingHost";
+
+    /**
+     * Creates a new {@code Session} instance based on the specified initialization data.  The originating host's
+     * IP (InetAddress}, if available, should be accessible in the {@code Map} under the
+     * {@link #ORIGINATING_HOST_KEY} key.  If not available, no value will be returned for that key ({@code null}).
      *
-     * @param originatingHost the originating host InetAddress of the external party
-     *                        (user, 3rd party product, etc) that is attempting to initiate the session, or
-     *                        {@code null} if not known.
-     * @return an new {@code Session} instance.
+     * @param initData the initialization data to be used during {@link Session} instantiation.
+     * @return a new {@code Session} instance.
+     * @since 1.0
      */
-    Session createSession(InetAddress originatingHost);
+    Session createSession(Map initData);
 }

Modified: incubator/jsecurity/trunk/core/src/main/java/org/apache/ki/session/mgt/SessionManager.java
URL: http://svn.apache.org/viewvc/incubator/jsecurity/trunk/core/src/main/java/org/apache/ki/session/mgt/SessionManager.java?rev=780154&r1=780153&r2=780154&view=diff
==============================================================================
--- incubator/jsecurity/trunk/core/src/main/java/org/apache/ki/session/mgt/SessionManager.java (original)
+++ incubator/jsecurity/trunk/core/src/main/java/org/apache/ki/session/mgt/SessionManager.java Sat May 30 00:42:29 2009
@@ -18,14 +18,15 @@
  */
 package org.apache.ki.session.mgt;
 
+import org.apache.ki.authz.AuthorizationException;
+import org.apache.ki.authz.HostUnauthorizedException;
+import org.apache.ki.session.InvalidSessionException;
+
 import java.io.Serializable;
 import java.net.InetAddress;
 import java.util.Collection;
 import java.util.Date;
-
-import org.apache.ki.authz.HostUnauthorizedException;
-import org.apache.ki.session.InvalidSessionException;
-
+import java.util.Map;
 
 /**
  * A SessionManager manages the creation, maintenance, and clean-up of all application
@@ -38,25 +39,25 @@
 
     /**
      * Starts a new session within the system for the host with the specified originating IP address.
-     *
-     * <p>An implementation of this interface may be configured to allow a <tt>null</tt> argument,
+     * <p/>
+     * An implementation of this interface may be configured to allow a {@code null} argument,
      * thereby indicating the originating IP is either unknown or has been
      * explicitly omitted by the caller.  However, if the implementation is configured to require
-     * a valid <tt>hostAddress</tt> and the argument is <tt>null</tt>, an
+     * a valid {@code hostAddress} and the argument is {@code null}, an
      * {@link IllegalArgumentException IllegalArgumentException} will be thrown.
-     *
-     * <p>In web-based systems, this InetAddress can be inferred from the
-     * {@link javax.servlet.ServletRequest#getRemoteAddr() javax.servlet.ServletRequest.getRemoteAddr()}
+     * <p/>
+     * In web-based systems, this InetAddress can be inferred from the incoming request, e.g.
+     * {@code javax.servlet.ServletRequest#getRemoteAddr()}
      * method, or in socket-based systems, it can be obtained via inspecting the socket
      * initiator's host IP.
-     *
-     * <p>Most secure environments <em>should</em> require that a valid, non-<tt>null</tt>
-     * <tt>hostAddress</tt> be specified, since knowing the <tt>hostAddress</tt> allows for more
+     * <p/>
+     * Most secure environments <em>should</em> require that a valid, non-{@code null}
+     * {@code hostAddress} be specified, since knowing the {@code hostAddress} allows for more
      * flexibility when securing a system: by requiring an InetAddress, access control policies
      * can also ensure access is restricted to specific client <em>locations</em> in
      * addition to user principals, if so desired.
-     *
-     * <p><b>Caveat</b> - if clients to your system are on a
+     * <p/>
+     * <b>Caveat</b> - if clients to your system are on a
      * public network (as would be the case for a public web site), odds are high the clients can be
      * behind a NAT (Network Address Translation) router or HTTP proxy server.  If so, all clients
      * accessing your system behind that router or proxy will have the same originating IP address.
@@ -69,16 +70,40 @@
      * @param originatingHost the originating host InetAddress of the external party
      *                        (user, 3rd party product, etc) that is attempting to interact with the system.
      * @return a handle to the newly created session.
-     * @throws org.apache.ki.authz.HostUnauthorizedException if the system access control policy restricts access based
+     * @throws HostUnauthorizedException if the system access control policy restricts access based
      *                                   on client location/IP and the specified hostAddress hasn't been enabled.
-     * @throws IllegalArgumentException  if the system is configured to require a valid,
-     *                                   non-<tt>null</tt> argument and the specified <tt>hostAddress</tt> is null.
+     * @throws AuthorizationException    if the system access control policy does not allow the currently executing
+     *                                   caller to start sessions.
      */
-    Serializable start(InetAddress originatingHost)
-            throws HostUnauthorizedException, IllegalArgumentException;
+    Serializable start(InetAddress originatingHost) throws AuthorizationException;
 
     /**
-     * Returns the time the Session identified by the specified <tt>sessionId</tt> was started
+     * Starts a new session based on the specified initialization data, which can be used by the underlying
+     * implementation to determine how exactly to create the internal Session instance.
+     * <p/>
+     * This method is mainly used in framework development, as the implementation will often relay the argument
+     * to an underlying {@link SessionFactory} which could use the {@code Map} to construct the internal Session
+     * instance in a specific manner.  This allows pluggable {@link org.apache.ki.session.Session Session} creation
+     * logic by simply injecting a {@code SessionFactory} into the {@code SecurityManager or SessionManager} instance.
+     * <p/>
+     * For example, Ki's default implementation of the
+     * {@link #start(InetAddress) start(InetAddress)} method merely adds the InetAddress to a Map instance and passes
+     * that Map into this method for delegation to an underlying {@link SessionFactory}.
+     *
+     * @param initData the initialization data that can be used by the implementation or underlying
+     *                 {@link SessionFactory} when instantiating the internal {@code Session} instance.
+     * @return the ID of the newly created session.
+     * @throws HostUnauthorizedException if the system access control policy restricts access based
+     *                                   on client location/IP and the specified hostAddress hasn't been enabled.
+     * @throws AuthorizationException    if the system access control policy does not allow the currently executing
+     *                                   caller to start sessions.
+     * @see SessionFactory#createSession(java.util.Map)
+     * @since 1.0
+     */
+    Serializable start(Map initData) throws AuthorizationException;
+
+    /**
+     * Returns the time the Session identified by the specified {@code sessionId} was started
      * in the system.
      *
      * @param sessionId the system identifier for the session of interest.
@@ -88,21 +113,21 @@
     Date getStartTimestamp(Serializable sessionId);
 
     /**
-     * Returns the time the <tt>Session</tt> identified by the specified <tt>sessionId</tt> last
+     * Returns the time the {@code Session} identified by the specified {@code sessionId} last
      * interacted with the system.
      *
      * @param sessionId the system identifier for the session of interest
-     * @return tye time the session last accessed the system
+     * @return time the session last accessed the system
      * @see org.apache.ki.session.Session#getLastAccessTime()
      * @see org.apache.ki.session.Session#touch()
      */
     Date getLastAccessTime(Serializable sessionId);
 
     /**
-     * Returns <tt>true</tt> if the session is valid (it exists and is not stopped nor expired), <tt>false</tt> otherwise.
+     * Returns {@code true} if the session is valid (it exists and is not stopped nor expired), {@code false} otherwise.
      *
      * @param sessionId the id of the session to check
-     * @return <tt>true</tt> if the session is valid (exists and is not stopped or expired), <tt>false</tt> otherwise.
+     * @return {@code true} if the session is valid (exists and is not stopped or expired), {@code false} otherwise.
      */
     boolean isValid(Serializable sessionId);
 
@@ -120,7 +145,6 @@
 
     /**
      * Returns the time in milliseconds that the specified session may remain idle before expiring.
-     *
      * <ul>
      * <li>A negative return value means the session will never expire.</li>
      * <li>A non-negative return value (0 or greater) means the session expiration will occur if idle for that
@@ -137,7 +161,6 @@
 
     /**
      * Sets the time in milliseconds that the specified session may remain idle before expiring.
-     *
      * <ul>
      * <li>A negative return value means the session will never expire.</li>
      * <li>A non-negative return value (0 or greater) means the session expiration will occur if idle for that
@@ -165,17 +188,17 @@
 
     /**
      * Returns the IP address of the host where the session was started, if known.  If
-     * no IP was specified when starting the session, this method returns <code>null</code>
+     * no IP was specified when starting the session, this method returns {@code null}
      *
      * @param sessionId the id of the session to query.
      * @return the ip address of the host where the session originated, if known.  If unknown,
-     *         this method returns <code>null</code>.
+     *         this method returns {@code null}.
      * @see #start(InetAddress originatingHost) init( InetAddress originatingHost )
      */
     InetAddress getHostAddress(Serializable sessionId);
 
     /**
-     * Explicitly stops the session identified by <tt>sessionId</tt>, thereby releasing all
+     * Explicitly stops the session identified by {@code sessionId}, thereby releasing all
      * associated resources.
      *
      * @param sessionId the system identfier of the system to destroy.
@@ -186,7 +209,7 @@
     void stop(Serializable sessionId) throws InvalidSessionException;
 
     /**
-     * Returns the keys of all the attributes stored under the session identified by <tt>sessionId</tt>.
+     * Returns the keys of all the attributes stored under the session identified by {@code sessionId}.
      * If there are no attributes, this returns an empty collection.
      *
      * @param sessionId the system identifier of the system to access.
@@ -200,11 +223,11 @@
 
     /**
      * Returns the object bound to the specified session identified by the specified key.  If there
-     * is noobject bound under the key for the given session, <tt>null</tt> is returned.
+     * is noobject bound under the key for the given session, {@code null} is returned.
      *
      * @param sessionId the system identifier of the session of interest
      * @param key       the unique name of the object bound to the specified session
-     * @return the object bound under the specified <tt>key</tt> name or <tt>null</tt> if there is
+     * @return the object bound under the specified {@code key} name or {@code null} if there is
      *         no object bound under that name.
      * @throws InvalidSessionException if the specified session has stopped or expired prior to calling this method.
      * @see org.apache.ki.session.Session#getAttribute(Object key)
@@ -212,15 +235,15 @@
     Object getAttribute(Serializable sessionId, Object key) throws InvalidSessionException;
 
     /**
-     * Binds the specified <tt>value</tt> to the specified session uniquely identified by the
-     * specifed <tt>key</tt> name.  If there is already an object bound under the <tt>key</tt>
-     * name, that existing object will be replaced by the new <tt>value</tt>.
-     *
-     * <p>If the <tt>value</tt> parameter is null, it has the same effect as if the
+     * Binds the specified {@code value} to the specified session uniquely identified by the
+     * specifed {@code key} name.  If there is already an object bound under the {@code key}
+     * name, that existing object will be replaced by the new {@code value}.
+     * <p/>
+     * If the {@code value} parameter is null, it has the same effect as if the
      * {@link #removeAttribute(Serializable sessionId, Object key)} method was called.
      *
      * @param sessionId the system identifier of the session of interest
-     * @param key       the name under which the <tt>value</tt> object will be bound in this session
+     * @param key       the name under which the {@code value} object will be bound in this session
      * @param value     the object to bind in this session.
      * @throws InvalidSessionException if the specified session has stopped or expired prior to calling this method.
      * @see org.apache.ki.session.Session#setAttribute(Object key, Object value)
@@ -228,12 +251,12 @@
     void setAttribute(Serializable sessionId, Object key, Object value) throws InvalidSessionException;
 
     /**
-     * Removes (unbinds) the object bound to this session under the specified <tt>key</tt> name.
+     * Removes (unbinds) the object bound to this session under the specified {@code key} name.
      *
      * @param sessionId the system identifier of the session of interest
      * @param key       the name uniquely identifying the object to remove
-     * @return the object removed or <tt>null</tt> if there was no object bound under the specified
-     *         <tt>key</tt> name.
+     * @return the object removed or {@code null} if there was no object bound under the specified
+     *         {@code key} name.
      * @throws InvalidSessionException if the specified session has stopped or expired prior to calling this method.
      * @see org.apache.ki.session.Session#removeAttribute(Object key)
      */

Modified: incubator/jsecurity/trunk/core/src/main/java/org/apache/ki/session/mgt/SimpleSession.java
URL: http://svn.apache.org/viewvc/incubator/jsecurity/trunk/core/src/main/java/org/apache/ki/session/mgt/SimpleSession.java?rev=780154&r1=780153&r2=780154&view=diff
==============================================================================
--- incubator/jsecurity/trunk/core/src/main/java/org/apache/ki/session/mgt/SimpleSession.java (original)
+++ incubator/jsecurity/trunk/core/src/main/java/org/apache/ki/session/mgt/SimpleSession.java Sat May 30 00:42:29 2009
@@ -26,13 +26,13 @@
 
 import java.io.Serializable;
 import java.net.InetAddress;
-import java.net.UnknownHostException;
 import java.text.DateFormat;
 import java.util.*;
 
 
 /**
- * Simple {@link org.apache.ki.session.Session} POJO implementation, intended to be used on the business/server tier.
+ * Simple {@link org.apache.ki.session.Session} JavaBeans-compatible POJO implementation, intended to be used on the
+ * business/server tier.
  *
  * @author Les Hazlewood
  * @since 0.1
@@ -58,23 +58,15 @@
     private Map<Object, Object> attributes = null;
 
     public SimpleSession() {
-        this(getLocalHost());
+        this.startTimestamp = new Date();
+        this.lastAccessTime = this.startTimestamp;
     }
 
     public SimpleSession(InetAddress hostAddress) {
-        this.startTimestamp = new Date();
-        this.lastAccessTime = startTimestamp;
+        this();
         this.hostAddress = hostAddress;
     }
 
-    private static InetAddress getLocalHost() {
-        try {
-            return InetAddress.getLocalHost();
-        } catch (UnknownHostException e) {
-            throw new IllegalStateException(e);
-        }
-    }
-
     public Serializable getId() {
         return this.id;
     }
@@ -184,7 +176,9 @@
         }
     }
 
-    /** @since 0.9 */
+    /**
+     * @since 0.9
+     */
     public boolean isValid() {
         return !isStopped() && !isExpired();
     }

Modified: incubator/jsecurity/trunk/core/src/main/java/org/apache/ki/session/mgt/SimpleSessionFactory.java
URL: http://svn.apache.org/viewvc/incubator/jsecurity/trunk/core/src/main/java/org/apache/ki/session/mgt/SimpleSessionFactory.java?rev=780154&r1=780153&r2=780154&view=diff
==============================================================================
--- incubator/jsecurity/trunk/core/src/main/java/org/apache/ki/session/mgt/SimpleSessionFactory.java (original)
+++ incubator/jsecurity/trunk/core/src/main/java/org/apache/ki/session/mgt/SimpleSessionFactory.java Sat May 30 00:42:29 2009
@@ -21,6 +21,7 @@
 import org.apache.ki.session.Session;
 
 import java.net.InetAddress;
+import java.util.Map;
 
 /**
  * {@code SessionFactory} implementation that generates {@link SimpleSession} instances.
@@ -42,4 +43,12 @@
     public Session createSession(InetAddress originatingHost) {
         return new SimpleSession(originatingHost);
     }
+
+    public Session createSession(Map initData) {
+        if (initData != null && initData.containsKey(SessionFactory.ORIGINATING_HOST_KEY)) {
+            InetAddress host = (InetAddress) initData.get(SessionFactory.ORIGINATING_HOST_KEY);
+            return new SimpleSession(host);
+        }
+        return new SimpleSession();
+    }
 }

Modified: incubator/jsecurity/trunk/core/src/main/java/org/apache/ki/subject/DelegatingSubject.java
URL: http://svn.apache.org/viewvc/incubator/jsecurity/trunk/core/src/main/java/org/apache/ki/subject/DelegatingSubject.java?rev=780154&r1=780153&r2=780154&view=diff
==============================================================================
--- incubator/jsecurity/trunk/core/src/main/java/org/apache/ki/subject/DelegatingSubject.java (original)
+++ incubator/jsecurity/trunk/core/src/main/java/org/apache/ki/subject/DelegatingSubject.java Sat May 30 00:42:29 2009
@@ -18,15 +18,6 @@
  */
 package org.apache.ki.subject;
 
-import java.io.Serializable;
-import java.net.InetAddress;
-import java.net.UnknownHostException;
-import java.util.Collection;
-import java.util.List;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
 import org.apache.ki.authc.AuthenticationException;
 import org.apache.ki.authc.AuthenticationToken;
 import org.apache.ki.authc.InetAuthenticationToken;
@@ -39,6 +30,14 @@
 import org.apache.ki.session.Session;
 import org.apache.ki.session.mgt.DelegatingSession;
 import org.apache.ki.util.ThreadContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.Serializable;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.util.Collection;
+import java.util.List;
 
 /**
  * Implementation of the <tt>Subject</tt> interface that delegates
@@ -144,7 +143,9 @@
         return this.inetAddress;
     }
 
-    /** @see Subject#getPrincipal() */
+    /**
+     * @see Subject#getPrincipal()
+     */
     public Object getPrincipal() {
         PrincipalCollection principals = getPrincipals();
         if (principals == null || principals.isEmpty()) {
@@ -290,10 +291,9 @@
         }
 
         if (this.session == null && create) {
-            if (log.isTraceEnabled()) {
-                log.trace("starting session for address [" + getInetAddress() + "]");
-            }
-            Serializable sessionId = this.securityManager.start(getInetAddress());
+            InetAddress host = getInetAddress();
+            log.trace("Starting session for host {}", host);
+            Serializable sessionId = this.securityManager.start(host);
             this.session = decorateSession(sessionId);
         }
         return this.session;

Modified: incubator/jsecurity/trunk/samples/standalone/src/main/java/MyRealm.java
URL: http://svn.apache.org/viewvc/incubator/jsecurity/trunk/samples/standalone/src/main/java/MyRealm.java?rev=780154&r1=780153&r2=780154&view=diff
==============================================================================
--- incubator/jsecurity/trunk/samples/standalone/src/main/java/MyRealm.java (original)
+++ incubator/jsecurity/trunk/samples/standalone/src/main/java/MyRealm.java Sat May 30 00:42:29 2009
@@ -22,8 +22,6 @@
 import org.apache.ki.realm.AuthorizingRealm;
 import org.apache.ki.subject.PrincipalCollection;
 
-import java.util.Collection;
-
 /**
  * @author Les Hazlewood
  * @since Aug 28, 2008 5:13:06 PM
@@ -41,7 +39,7 @@
      * in this method. The {@link org.apache.ki.realm.AuthenticatingRealm AuthenticatingRealm} superclass will do
      * that automatically via the use of a configured
      * {@link org.apache.ki.authc.credential.CredentialsMatcher CredentialsMatcher} (see this example's corresponding
-     * <code>ki.ini</code> file to see a configured credentials matcher).
+     * {@code ki.ini} file to see a configured credentials matcher).
      * <p/>
      * All that is required is that the account information include directly the credentials found in the EIS.
      *
@@ -74,18 +72,8 @@
     }
 
     protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
-        //simulate a call to an underlying data store:
-
-        //get only the principals that this realm cares about:
-        Collection thisRealmPrincipals = principals.fromRealm(getName());
-
-        //note that the return value of 'getName()' here is whatever you specify it to be in ki.ini
-        //in this case, the ki.ini file calls it 'myRealm'.  All realms must have a unique name.
-
-        //Since this realm supplied these principals from the doGetAuthenticationInfo method above when the
-        //user logged-in and that method in this simple example has only one principal - a username - we can safely
-        //assume the only element in this collection is that username.
-        String username = (String) thisRealmPrincipals.iterator().next();
+        //get the principal this realm cares about:
+        String username = (String) getAvailablePrincipal(principals);
 
         //call the underlying EIS for the account data:
         return getAccount(username);

Modified: incubator/jsecurity/trunk/web/src/main/java/org/apache/ki/web/session/ServletContainerSessionManager.java
URL: http://svn.apache.org/viewvc/incubator/jsecurity/trunk/web/src/main/java/org/apache/ki/web/session/ServletContainerSessionManager.java?rev=780154&r1=780153&r2=780154&view=diff
==============================================================================
--- incubator/jsecurity/trunk/web/src/main/java/org/apache/ki/web/session/ServletContainerSessionManager.java (original)
+++ incubator/jsecurity/trunk/web/src/main/java/org/apache/ki/web/session/ServletContainerSessionManager.java Sat May 30 00:42:29 2009
@@ -18,20 +18,21 @@
  */
 package org.apache.ki.web.session;
 
-import java.io.Serializable;
-import java.net.InetAddress;
-import javax.servlet.ServletRequest;
-import javax.servlet.ServletResponse;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpSession;
-
 import org.apache.ki.authz.AuthorizationException;
-import org.apache.ki.authz.HostUnauthorizedException;
 import org.apache.ki.session.InvalidSessionException;
 import org.apache.ki.session.Session;
 import org.apache.ki.session.mgt.AbstractSessionManager;
+import org.apache.ki.session.mgt.SessionFactory;
 import org.apache.ki.web.WebUtils;
 
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpSession;
+import java.io.Serializable;
+import java.net.InetAddress;
+import java.util.Map;
+
 
 /**
  * SessionManager implementation providing Session implementations that are merely wrappers for the
@@ -44,8 +45,8 @@
  * Note that because this implementation relies on the {@link HttpSession HttpSession}, it is only functional in a
  * servlet container.  I.e. it is <em>NOT</em> capable of supporting Sessions any clients other than
  * {@code HttpRequest/HttpResponse} based clients.
- *
- * <p>Therefore, if you need {@code Session} access from heterogenous client mediums (e.g. web pages,
+ * <p/>
+ * Therefore, if you need {@code Session} access from heterogenous client mediums (e.g. web pages,
  * Flash applets, Java Web Start applications, etc.), use the {@link DefaultWebSessionManager DefaultWebSessionManager}
  * instead.  The {@code DefaultWebSessionManager} supports both traditional web-based access as well as non web-based
  * clients.
@@ -79,7 +80,8 @@
         return session;
     }
 
-    protected Session createSession(InetAddress originatingHost) throws HostUnauthorizedException, IllegalArgumentException {
+    protected Session createSession(Map initData) throws AuthorizationException {
+
         ServletRequest request = WebUtils.getRequiredServletRequest();
         HttpSession httpSession = ((HttpServletRequest) request).getSession();
 
@@ -87,6 +89,12 @@
         long timeoutMillis = getGlobalSessionTimeout();
         httpSession.setMaxInactiveInterval((int) (timeoutMillis / MILLIS_PER_SECOND));
 
+
+        InetAddress originatingHost = null;
+        if (initData != null && initData.containsKey(SessionFactory.ORIGINATING_HOST_KEY)) {
+            originatingHost = (InetAddress) initData.get(SessionFactory.ORIGINATING_HOST_KEY);
+        }
+
         return createSession(httpSession, originatingHost);
     }