JSEC-42 - made SecurityManager extend SessionManager instead of SessionFactory (reasons documented in the issue).
git-svn-id: https://svn.apache.org/repos/asf/incubator/jsecurity/trunk@733434 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/core/src/org/jsecurity/authz/HostUnauthorizedException.java b/core/src/org/jsecurity/authz/HostUnauthorizedException.java
index 37b972e..843e166 100644
--- a/core/src/org/jsecurity/authz/HostUnauthorizedException.java
+++ b/core/src/org/jsecurity/authz/HostUnauthorizedException.java
@@ -26,7 +26,7 @@
* or access a particular resource.
*
* @author Les Hazlewood
- * @see org.jsecurity.session.SessionFactory#start(java.net.InetAddress)
+ * @see org.jsecurity.session.mgt.SessionManager#start(java.net.InetAddress)
* @since 0.1
*/
public class HostUnauthorizedException extends UnauthorizedException {
diff --git a/core/src/org/jsecurity/mgt/SecurityManager.java b/core/src/org/jsecurity/mgt/SecurityManager.java
index 5a23e7d..47dfff2 100644
--- a/core/src/org/jsecurity/mgt/SecurityManager.java
+++ b/core/src/org/jsecurity/mgt/SecurityManager.java
@@ -21,20 +21,26 @@
import org.jsecurity.authc.AuthenticationException;
import org.jsecurity.authc.AuthenticationToken;
import org.jsecurity.authc.Authenticator;
+import org.jsecurity.authz.AuthorizationException;
import org.jsecurity.authz.Authorizer;
-import org.jsecurity.session.SessionFactory;
+import org.jsecurity.authz.HostUnauthorizedException;
+import org.jsecurity.session.InvalidSessionException;
+import org.jsecurity.session.Session;
+import org.jsecurity.session.mgt.SessionManager;
import org.jsecurity.subject.PrincipalCollection;
import org.jsecurity.subject.Subject;
+import java.io.Serializable;
+
/**
* A <tt>SecurityManager</tt> executes all security operations for <em>all</em> Subjects (aka users) across a
* single application.
*
* <p>The interface itself primarily exists as a convenience - it extends the {@link Authenticator},
- * {@link Authorizer}, and {@link SessionFactory} interfaces, thereby consolidating
+ * {@link Authorizer}, and {@link SessionManager} interfaces, thereby consolidating
* these behaviors into a single point of reference. For most JSecurity usages, this simplifies configuration and
* tends to be a more convenient approach than referencing <code>Authenticator</code>, <code>Authorizer</code>, and
- * <code>SessionFactory</code> instances seperately; instead one only needs to interact with a
+ * <code>SessionManager</code> instances seperately; instead one only needs to interact with a
* single <tt>SecurityManager</tt> instance.</p>
*
* <p>In addition to the above three interfaces, three unique methods are provided by this interface by itself,
@@ -59,14 +65,14 @@
* @see DefaultSecurityManager
* @since 0.2
*/
-public interface SecurityManager extends Authenticator, Authorizer, SessionFactory {
+public interface SecurityManager extends Authenticator, Authorizer, SessionManager {
/**
* Logs in a user, returning a Subject instance if the authentication is successful or throwing an
* <code>AuthenticationException</code> if it is not.
* <p/>
* Note that most application developers should probably not call this method directly unless they have a good
- * reason for doing so. The preferred way to log in a Subject is to call
+ * reason for doing so. The preferred way to log in a Subject is to call
* <code>{@link Subject#login Subject.login(authenticationToken)}</code> (usually after acquiring the
* Subject by calling {@link org.jsecurity.SecurityUtils#getSubject() SecurityUtils.getSubject()}).
* <p/>
@@ -101,4 +107,37 @@
* @since 0.9
*/
Subject getSubject();
+
+ /**
+ * Acquires a handle to the session identified by the specified <tt>sessionId</tt>.
+ *
+ * <p><b>Although simple, this method finally enables behavior absent in Java for years:</b>
+ *
+ * <p>the
+ * ability to participate in a server-side session across clients of different mediums,
+ * such as web appliations, Java applets, standalone C# clients over XMLRPC and/or SOAP, and
+ * many others. This is a <em>huge</em> benefit in heterogeneous enterprise applications.
+ *
+ * <p>To maintain session integrity across client mediums, the sessionId must be transmitted
+ * to all client mediums securely (e.g. over SSL) to prevent man-in-the-middle attacks. This
+ * is nothing new - all web applications are susceptible to the same problem when transmitting
+ * {@link javax.servlet.http.Cookie Cookie}s or when using URL rewriting. As long as the
+ * <tt>sessionId</tt> is transmitted securely, session integrity can be maintained.
+ *
+ * @param sessionId the id of the session to acquire.
+ * @return a handle to the session identified by <tt>sessionId</tt>
+ * @throws org.jsecurity.session.InvalidSessionException
+ * if the session identified by <tt>sessionId</tt> has
+ * been stopped, expired, or doesn't exist.
+ * @throws org.jsecurity.authz.AuthorizationException
+ * if the executor of this method is not allowed to acquire
+ * (i.e. join) the session identified by <tt>sessionId</tt>. The reason for the exception
+ * is implementation specific and could be for any number of reasons. A common reason in many
+ * systems would be if one host tried to acquire/join a session that originated on an entirely
+ * different host (although it is not a JSecurity requirement this scenario is disallowed -
+ * its just an example that <em>may</em> throw an Exception in many systems).
+ * @see HostUnauthorizedException
+ * @since 1.0
+ */
+ Session getSession(Serializable sessionId) throws InvalidSessionException, AuthorizationException;
}
\ No newline at end of file
diff --git a/core/src/org/jsecurity/mgt/SessionsSecurityManager.java b/core/src/org/jsecurity/mgt/SessionsSecurityManager.java
index f85d07d..023359b 100644
--- a/core/src/org/jsecurity/mgt/SessionsSecurityManager.java
+++ b/core/src/org/jsecurity/mgt/SessionsSecurityManager.java
@@ -34,6 +34,7 @@
import java.io.Serializable;
import java.net.InetAddress;
import java.util.Collection;
+import java.util.Date;
/**
* JSecurity support of a {@link SecurityManager} class hierarchy that delegates all
@@ -216,6 +217,58 @@
((SessionListenerRegistrar) sm).remove(listener);
}
+ public Serializable start(InetAddress originatingHost) throws HostUnauthorizedException, IllegalArgumentException {
+ return getSessionManager().start(originatingHost);
+ }
+
+ public Date getStartTimestamp(Serializable sessionId) {
+ return getSessionManager().getStartTimestamp(sessionId);
+ }
+
+ public Date getLastAccessTime(Serializable sessionId) {
+ return getSessionManager().getLastAccessTime(sessionId);
+ }
+
+ public boolean isValid(Serializable sessionId) {
+ return getSessionManager().isValid(sessionId);
+ }
+
+ public long getTimeout(Serializable sessionId) throws InvalidSessionException {
+ return getSessionManager().getTimeout(sessionId);
+ }
+
+ public void setTimeout(Serializable sessionId, long maxIdleTimeInMillis) throws InvalidSessionException {
+ getSessionManager().setTimeout(sessionId, maxIdleTimeInMillis);
+ }
+
+ public void touch(Serializable sessionId) throws InvalidSessionException {
+ getSessionManager().touch(sessionId);
+ }
+
+ public InetAddress getHostAddress(Serializable sessionId) {
+ return getSessionManager().getHostAddress(sessionId);
+ }
+
+ public void stop(Serializable sessionId) throws InvalidSessionException {
+ getSessionManager().stop(sessionId);
+ }
+
+ public Collection<Object> getAttributeKeys(Serializable sessionId) {
+ return getSessionManager().getAttributeKeys(sessionId);
+ }
+
+ public Object getAttribute(Serializable sessionId, Object key) throws InvalidSessionException {
+ return getSessionManager().getAttribute(sessionId, key);
+ }
+
+ public void setAttribute(Serializable sessionId, Object key, Object value) throws InvalidSessionException {
+ getSessionManager().setAttribute(sessionId, key, value);
+ }
+
+ public Object removeAttribute(Serializable sessionId, Object key) throws InvalidSessionException {
+ return getSessionManager().removeAttribute(sessionId, key);
+ }
+
/**
* Template hook for subclasses that wish to perform clean up behavior during shutdown.
*/
@@ -240,12 +293,6 @@
destroySessionManager();
}
- public Session start(InetAddress hostAddress) throws HostUnauthorizedException, IllegalArgumentException {
- SessionManager sm = getSessionManager();
- Serializable sessionId = sm.start(hostAddress);
- return new DelegatingSession(sm, sessionId);
- }
-
public Session getSession(Serializable sessionId) throws InvalidSessionException, AuthorizationException {
SessionManager sm = getSessionManager();
if (!sm.isValid(sessionId)) {
diff --git a/core/src/org/jsecurity/session/Session.java b/core/src/org/jsecurity/session/Session.java
index efde797..721899d 100644
--- a/core/src/org/jsecurity/session/Session.java
+++ b/core/src/org/jsecurity/session/Session.java
@@ -33,7 +33,7 @@
* {@link javax.servlet.http.HttpSession HttpSession} or Stateful Session EJB's, which many times
* unnecessarily coupled applications to web or ejb technologies.
*
- * <p>See the {@link SessionFactory#getSession(java.io.Serializable) SessionFactory.getSession(Serializable)}
+ * <p>See the {@link org.jsecurity.mgt.SecurityManager#getSession(java.io.Serializable) SecurityManager.getSession(Serializable)}
* JavaDoc for more on the benefits of a POJO-based <tt>Session</tt> framework.
*
* @author Les Hazlewood
@@ -107,7 +107,7 @@
*
* @return the <tt>InetAddress</tt> of the host that originated this session, or <tt>null</tt>
* if the host address is unknown.
- * @see SessionFactory#start(java.net.InetAddress)
+ * @see org.jsecurity.session.mgt.SessionManager#start(java.net.InetAddress)
*/
InetAddress getHostAddress();
diff --git a/core/src/org/jsecurity/session/SessionFactory.java b/core/src/org/jsecurity/session/SessionFactory.java
deleted file mode 100644
index 6d74066..0000000
--- a/core/src/org/jsecurity/session/SessionFactory.java
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.jsecurity.session;
-
-import org.jsecurity.authz.AuthorizationException;
-import org.jsecurity.authz.HostUnauthorizedException;
-
-import java.io.Serializable;
-import java.net.InetAddress;
-
-/**
- * A <tt>SessionFactory</tt> is responsible for starting new {@link Session Session}s and
- * acquiring existing {@link Session Session}s.
- *
- * @author Les Hazlewood
- * @since 0.1
- */
-public interface SessionFactory {
-
- /**
- * 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,
- * 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
- * {@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()}
- * 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
- * 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
- * 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.
- * If your system is configured to allow only one session per IP, then the next request from a
- * different NAT or proxy client will fail and access will be deny for that client. Just be
- * aware that ip-based security policies are best utilized in LAN or private WAN environments
- * when you can be ensure clients will not share IPs or be behind such NAT routers or
- * proxy servers.
- *
- * @param hostAddress 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 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.
- */
- Session start(InetAddress hostAddress) throws HostUnauthorizedException, IllegalArgumentException;
-
- /**
- * Acquires a handle to the session identified by the specified <tt>sessionId</tt>.
- *
- * <p><b>Although simple, this method finally enables behavior absent in Java for years:</b>
- *
- * <p>the
- * ability to participate in a server-side session across clients of different mediums,
- * such as web appliations, Java applets, standalone C# clients over XMLRPC and/or SOAP, and
- * many others. This is a <em>huge</em> benefit in heterogeneous enterprise applications.
- *
- * <p>To maintain session integrity across client mediums, the sessionId must be transmitted
- * to all client mediums securely (e.g. over SSL) to prevent man-in-the-middle attacks. This
- * is nothing new - all web applications are susceptible to the same problem when transmitting
- * {@link javax.servlet.http.Cookie Cookie}s or when using URL rewriting. As long as the
- * <tt>sessionId</tt> is transmitted securely, session integrity can be maintained.
- *
- * @param sessionId the id of the session to acquire.
- * @return a handle to the session identified by <tt>sessionId</tt>
- * @throws InvalidSessionException if the session identified by <tt>sessionId</tt> has
- * been stopped, expired, or doesn't exist.
- * @throws AuthorizationException if the executor of this method is not allowed to acquire
- * (i.e. join) the session identified by <tt>sessionId</tt>. The reason for the exception
- * is implementation specific and could be for any number of reasons. A common reason in many
- * systems would be if one host tried to acquire/join a session that originated on an entirely
- * different host (although it is not a JSecurity requirement this scenario is disallowed -
- * its just an example that <em>may</em> throw an Exception in many systems).
- * @see HostUnauthorizedException
- */
- Session getSession(Serializable sessionId) throws InvalidSessionException, AuthorizationException;
-
-}
diff --git a/core/src/org/jsecurity/session/mgt/SessionManager.java b/core/src/org/jsecurity/session/mgt/SessionManager.java
index ab833d1..ba2f5a7 100644
--- a/core/src/org/jsecurity/session/mgt/SessionManager.java
+++ b/core/src/org/jsecurity/session/mgt/SessionManager.java
@@ -36,20 +36,42 @@
public interface SessionManager {
/**
- * Starts a new session within the system for the host with the specified originating IP
- * address.
+ * Starts a new session within the system for the host with the specified originating IP address.
*
- * <p><b>Note</b>: see the
- * {@link org.jsecurity.session.SessionFactory#start(java.net.InetAddress) SessionFactory.init(InetAddress)} method
- * about the implications of using <tt>InetAddress</tt>es in access control policies.
+ * <p>An implementation of this interface may be configured to allow a <tt>null</tt> 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
+ * {@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()}
+ * 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
+ * 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
+ * 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.
+ * If your system is configured to allow only one session per IP, then the next request from a
+ * different NAT or proxy client will fail and access will be deny for that client. Just be
+ * aware that ip-based security policies are best utilized in LAN or private WAN environments
+ * when you can be ensure clients will not share IPs or be behind such NAT routers or
+ * proxy servers.
*
* @param originatingHost the originating host InetAddress of the external party
* (user, 3rd party product, etc) that is attempting to interact with the system.
- * @return the system identifier of the newly created session.
- * @throws IllegalArgumentException if the host specified is not valid.
- * @throws org.jsecurity.authz.HostUnauthorizedException
- * if the host specified is not allowed to start sessions.
- * @see org.jsecurity.session.SessionFactory#start(InetAddress)
+ * @return a handle to 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 IllegalArgumentException if the system is configured to require a valid,
+ * non-<tt>null</tt> argument and the specified <tt>hostAddress</tt> is null.
*/
Serializable start(InetAddress originatingHost)
throws HostUnauthorizedException, IllegalArgumentException;
diff --git a/core/src/org/jsecurity/subject/DelegatingSubject.java b/core/src/org/jsecurity/subject/DelegatingSubject.java
index 3288c0c..f6f1e8f 100644
--- a/core/src/org/jsecurity/subject/DelegatingSubject.java
+++ b/core/src/org/jsecurity/subject/DelegatingSubject.java
@@ -30,8 +30,10 @@
import org.jsecurity.session.InvalidSessionException;
import org.jsecurity.session.ProxiedSession;
import org.jsecurity.session.Session;
+import org.jsecurity.session.mgt.DelegatingSession;
import org.jsecurity.util.ThreadContext;
+import java.io.Serializable;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Collection;
@@ -283,7 +285,8 @@
if (log.isTraceEnabled()) {
log.trace("starting session for address [" + getInetAddress() + "]");
}
- Session target = securityManager.start(getInetAddress());
+ Serializable sessionId = this.securityManager.start(getInetAddress());
+ Session target = new DelegatingSession(this.securityManager, sessionId);
this.session = new StoppingAwareProxiedSession(target, this);
}
return this.session;
diff --git a/support/spring/src/org/jsecurity/spring/remoting/SecureRemoteInvocationExecutor.java b/support/spring/src/org/jsecurity/spring/remoting/SecureRemoteInvocationExecutor.java
index a0314d0..0fc4ecf 100644
--- a/support/spring/src/org/jsecurity/spring/remoting/SecureRemoteInvocationExecutor.java
+++ b/support/spring/src/org/jsecurity/spring/remoting/SecureRemoteInvocationExecutor.java
@@ -111,6 +111,7 @@
Serializable sessionId = invocation.getAttribute(SecureRemoteInvocationFactory.SESSION_ID_KEY);
if (sessionId != null) {
+
session = securityManager.getSession(sessionId);
principals = getPrincipals(invocation, targetObject, session);
authenticated = isAuthenticated(invocation, targetObject, session, principals);