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 2010/05/17 22:33:13 UTC
svn commit: r945349 [2/2] - in /incubator/shiro/trunk:
core/src/main/java/org/apache/shiro/authz/
core/src/main/java/org/apache/shiro/mgt/
core/src/main/java/org/apache/shiro/session/
core/src/main/java/org/apache/shiro/session/mgt/ core/src/main/java/...
Modified: incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/WebUtils.java
URL: http://svn.apache.org/viewvc/incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/WebUtils.java?rev=945349&r1=945348&r2=945349&view=diff
==============================================================================
--- incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/WebUtils.java (original)
+++ incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/WebUtils.java Mon May 17 20:33:12 2010
@@ -432,13 +432,7 @@ public class WebUtils {
* It is the case in certain enterprise environments where a web-enabled SecurityManager (and its internal mechanisms)
* is the primary SecurityManager but also serves as a 'central' coordinator for security operations in a cluster.
* In these environments, it is possible for a web-enabled SecurityManager to receive remote method invocations that
- * are not HTTP based.
- * <p/>
- * In these environments, we need to acquire a thread-bound ServletRequest if it exists, but
- * not throw an exception if one is not found (with the assumption that the incoming call is not a web request but
- * instead a remote method invocation). This method exists to support these environments, whereas the
- * {@link #getRequiredServletRequest() getRequiredServletRequest()} method always assumes a
- * servlet-only environment.
+ * are not HTTP based. In such an environment this method would return {@code null}.
* <p/>
* <b>THIS IS NOT PART OF APACHE SHIRO'S PUBLIC API.</b> It exists for Shiro implementation requirements only.
*
@@ -446,30 +440,13 @@ public class WebUtils {
* @since 1.0
*/
public static ServletRequest getServletRequest() {
- return (ServletRequest) ThreadContext.get(SERVLET_REQUEST_KEY);
- }
-
- /**
- * Convenience method that simplifies retrieval of a required thread-bound ServletRequest. If there is no
- * ServletRequest bound to the thread when this method is called, an <code>IllegalStateException</code> is
- * thrown.
- * <p/>
- * This method is basically a convenient wrapper for the following:
- * <p/>
- * <code>(ServletRequest){@link ThreadContext#get ThreadContext.get}( SERVLET_REQUEST_KEY );</code>
- * <p/>
- * But throws an <code>IllegalStateException</code> if the value is not bound to the <code>ThreadContext</code>.
- * <p/>
- * This method only returns the bound value if it exists - it does not remove it
- * from the thread. To remove it, one must call {@link #unbindServletRequest() unbindServletRequest} instead.
- *
- * @return the ServletRequest bound to the thread. Never returns null.
- * @throws IllegalStateException if no servlet request is bound in the {@link org.apache.shiro.util.ThreadContext ThreadContext}.
- */
- public static ServletRequest getRequiredServletRequest() throws IllegalStateException {
- ServletRequest request = getServletRequest();
+ ServletRequest request = (ServletRequest) ThreadContext.get(SERVLET_REQUEST_KEY);
if (request == null) {
- throw new IllegalStateException("No ServletRequest found in ThreadContext. " + NOT_BOUND_ERROR_MESSAGE);
+ Subject subject = ThreadContext.getSubject();
+ if (subject instanceof WebSubject) {
+ WebSubject webSubject = (WebSubject) subject;
+ request = webSubject.getServletRequest();
+ }
}
return request;
}
@@ -495,36 +472,12 @@ public class WebUtils {
}
/**
- * Convenience method that simplifies removal of a thread-local ServletRequest from the thread.
- * <p/>
- * The implementation just helps reduce casting and remembering of the ThreadContext key name, i.e it is
- * merely a conveient wrapper for the following:
- * <p/>
- * <code>return (ServletRequest)ThreadContext.remove( SERVLET_REQUEST_KEY );</code>
- * <p/>
- * If you wish to just retrieve the object from the thread without removing it (so it can be retrieved later during
- * thread execution), you should use the {@link #getRequiredServletRequest() getRequiredServletRequest()} method
- * for that purpose.
- *
- * @return the Session object previously bound to the thread, or <tt>null</tt> if there was none bound.
- */
- public static ServletRequest unbindServletRequest() {
- return (ServletRequest) ThreadContext.remove(SERVLET_REQUEST_KEY);
- }
-
- /**
* Returns the current thread-bound {@code ServletResponse} or {@code null} if there is not one bound.
* <p/>
* It is the case in certain enterprise environments where a web-enabled SecurityManager (and its internal mechanisms)
* is the primary SecurityManager but also serves as a 'central' coordinator for security operations in a cluster.
* In these environments, it is possible for a web-enabled SecurityManager to receive remote method invocations that
- * are not HTTP based.
- * <p/>
- * In these environments, we need to acquire a thread-bound ServletResponse if it exists, but
- * not throw an exception if one is not found (with the assumption that the incoming call is not a web request but
- * instead a remote method invocation). This method exists to support these environments, whereas the
- * {@link #getRequiredServletResponse() getRequiredServletResponse()} method always assumes a
- * servlet-only environment.
+ * are not HTTP based. In such an environment this method would return {@code null}.
* <p/>
* <b>THIS IS NOT PART OF APACHE SHIRO'S PUBLIC API.</b> It exists for Shiro implementation requirements only.
*
@@ -532,30 +485,13 @@ public class WebUtils {
* @since 1.0
*/
public static ServletResponse getServletResponse() {
- return (ServletResponse) ThreadContext.get(SERVLET_RESPONSE_KEY);
- }
-
- /**
- * Convenience method that simplifies retrieval of a required thread-bound ServletResponse. If there is no
- * ServletResponse bound to the thread when this method is called, an <code>IllegalStateException</code> is
- * thrown.
- * <p/>
- * This method is basically a convenient wrapper for the following:
- * <p/>
- * <code>return (ServletResponse){@link ThreadContext#get ThreadContext.get}( SERVLET_RESPONSE_KEY );</code>
- * <p/>
- * But throws an <code>IllegalStateException</code> if the value is not bound to the <code>ThreadContext</code>.
- * <p/>
- * This method only returns the bound value if it exists - it does not remove it
- * from the thread. To remove it, one must call {@link #unbindServletResponse() unbindServletResponse} instead.
- *
- * @return the ServletResponse bound to the thread. Never returns null.
- * @throws IllegalStateException if no <code>ServletResponse> is bound in the {@link ThreadContext ThreadContext}
- */
- public static ServletResponse getRequiredServletResponse() throws IllegalStateException {
ServletResponse response = (ServletResponse) ThreadContext.get(SERVLET_RESPONSE_KEY);
if (response == null) {
- throw new IllegalStateException("No ServletResponse found in ThreadContext. " + NOT_BOUND_ERROR_MESSAGE);
+ Subject subject = ThreadContext.getSubject();
+ if (subject instanceof WebSubject) {
+ WebSubject webSubject = (WebSubject) subject;
+ response = webSubject.getServletResponse();
+ }
}
return response;
}
@@ -581,24 +517,6 @@ public class WebUtils {
}
/**
- * Convenience method that simplifies removal of a thread-local ServletResponse from the thread.
- * <p/>
- * The implementation just helps reduce casting and remembering of the ThreadContext key name, i.e it is
- * merely a conveient wrapper for the following:
- * <p/>
- * <code>return (ServletResponse)ThreadContext.remove( SERVLET_RESPONSE_KEY );</code>
- * <p/>
- * If you wish to just retrieve the object from the thread without removing it (so it can be retrieved later during
- * thread execution), you should use the {@link #getRequiredServletResponse() getRequiredServletResponse()} method
- * for that purpose.
- *
- * @return the Session object previously bound to the thread, or <tt>null</tt> if there was none bound.
- */
- public static ServletResponse unbindServletResponse() {
- return (ServletResponse) ThreadContext.remove(SERVLET_RESPONSE_KEY);
- }
-
- /**
* Redirects the current request to a new URL based on the given parameters.
*
* @param request the servlet request.
Modified: incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/servlet/AbstractShiroFilter.java
URL: http://svn.apache.org/viewvc/incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/servlet/AbstractShiroFilter.java?rev=945349&r1=945348&r2=945349&view=diff
==============================================================================
--- incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/servlet/AbstractShiroFilter.java (original)
+++ incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/servlet/AbstractShiroFilter.java Mon May 17 20:33:12 2010
@@ -20,15 +20,12 @@ package org.apache.shiro.web.servlet;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.session.Session;
+import org.apache.shiro.subject.ExecutionException;
import org.apache.shiro.subject.Subject;
-import org.apache.shiro.util.ThreadContext;
-import org.apache.shiro.util.ThreadState;
import org.apache.shiro.web.DefaultWebSecurityManager;
import org.apache.shiro.web.WebSecurityManager;
-import org.apache.shiro.web.WebUtils;
import org.apache.shiro.web.filter.mgt.FilterChainResolver;
import org.apache.shiro.web.subject.WebSubject;
-import org.apache.shiro.web.subject.support.WebSubjectThreadState;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -39,6 +36,7 @@ import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
+import java.util.concurrent.Callable;
/**
* Abstract base class that provides all standard Shiro request filtering behavior and expects
@@ -192,48 +190,16 @@ public abstract class AbstractShiroFilte
}
/**
- * Binds the current request/response pair and additional information to a thread-local to be made available to Shiro
- * during the course of the request/response process. This implementation binds the request/response pair and
- * any associated Subject (and its relevant thread-based data) via a {@link org.apache.shiro.web.subject.support.WebSubjectThreadState}. That
- * threadState is returned so it can be used during thread cleanup at the end of the request.
- * <p/>
- * To guarantee properly cleaned threads in a thread-pooled Servlet Container environment, the corresponding
- * {@link #unbind} method must be called in a {@code finally} block to ensure that the thread remains clean even
- * in the event of an exception thrown while processing the request. This class's
- * {@link #doFilterInternal(javax.servlet.ServletRequest, javax.servlet.ServletResponse, javax.servlet.FilterChain)}
- * method implementation does indeed function this way.
+ * Creates a {@link WebSubject} instance to associate with the incoming request/response pair which will be used
+ * throughout the request/response execution.
*
- * @param request the incoming ServletRequest
- * @param response the outgoing ServletResponse
- * @return ThreadStateManager the thread state used to bind necessary state for the request execution.
+ * @param request the incoming {@code ServletRequest}
+ * @param response the outgoing {@code ServletResponse}
+ * @return the {@code WebSubject} instance to associate with the request/response execution
* @since 1.0
*/
- protected ThreadState bind(ServletRequest request, ServletResponse response) {
- ThreadContext.bind(getSecurityManager());
- WebUtils.bind(request);
- WebUtils.bind(response);
- WebSubject subject = new WebSubject.Builder(getSecurityManager(), request, response).buildWebSubject();
- ThreadState threadState = new WebSubjectThreadState(subject);
- threadState.bind();
- return threadState;
- }
-
- /**
- * Unbinds (removes out of scope) the current {@code ServletRequest} and {@link ServletResponse}.
- * <p/>
- * This method implementation merely clears <em>all</em> thread state by calling
- * {@link org.apache.shiro.subject.support.SubjectThreadState#clear()} to guarantee
- * that <em>everything</em> that might have been bound to the thread by Shiro has been removed to ensure the
- * underlying Thread may be safely re-used in a thread-pooled Servlet Container environment.
- *
- * @param threadState the web thread state created when the request and response first were initiated.
- * @since 1.0
- */
- @SuppressWarnings({"UnusedDeclaration"})
- protected void unbind(ThreadState threadState) {
- if ( threadState != null ) {
- threadState.clear();
- }
+ protected WebSubject createSubject(ServletRequest request, ServletResponse response) {
+ return new WebSubject.Builder(getSecurityManager(), request, response).buildWebSubject();
}
/**
@@ -274,41 +240,58 @@ public abstract class AbstractShiroFilte
* the incoming {@code ServletRequest} for use during Shiro's processing</li>
* <li>{@link #prepareServletResponse(ServletRequest, ServletResponse, FilterChain) Prepares}
* the outgoing {@code ServletResponse} for use during Shiro's processing</li>
- * <li>{@link #bind(ServletRequest,ServletResponse) Binds} the request/response pair
- * and associated data to the currently executing thread for use during processing</li>
- * <li>{@link #updateSessionLastAccessTime(javax.servlet.ServletRequest, javax.servlet.ServletResponse) Updates}
- * any associated session's {@link org.apache.shiro.session.Session#getLastAccessTime() lastAccessTime} to ensure
- * session timeouts are honored</li>
- * <li>{@link #executeChain(ServletRequest,ServletResponse,FilterChain) Executes}
- * the appropriate {@code FilterChain}</li>
- * <li>{@link #unbind(org.apache.shiro.util.ThreadState) Unbinds} the request/response
- * pair and any other associated data from the thread.
- * </ul>
+ * <li> {@link #createSubject(javax.servlet.ServletRequest, javax.servlet.ServletResponse) Creates} a
+ * {@link Subject} instance based on the specified request/response pair.</li>
+ * <li>Finally {@link Subject#execute(Runnable) executes} the
+ * {@link #updateSessionLastAccessTime(javax.servlet.ServletRequest, javax.servlet.ServletResponse)} and
+ * {@link #executeChain(javax.servlet.ServletRequest, javax.servlet.ServletResponse, javax.servlet.FilterChain)}
+ * methods</li>
+ * </ol>
* <p/>
- * The {@link #unbind(org.apache.shiro.util.ThreadState) unbind} method is called in a
- * {@code finally} block to guarantee the thread may be cleanly re-used in a thread-pooled Servlet Container
- * environment.
+ * The {@code Subject.}{@link Subject#execute(Runnable) execute(Runnable)} call in step #4 is used as an
+ * implementation technique to guarantee proper thread binding and restoration is completed successfully.
*
* @param servletRequest the incoming {@code ServletRequest}
* @param servletResponse the outgoing {@code ServletResponse}
* @param chain the container-provided {@code FilterChain} to execute
- * @throws javax.servlet.ServletException if an error occurs
* @throws IOException if an IO error occurs
+ * @throws javax.servlet.ServletException if an Throwable other than an IOException
*/
- protected void doFilterInternal(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain chain)
+ protected void doFilterInternal(ServletRequest servletRequest, ServletResponse servletResponse, final FilterChain chain)
throws ServletException, IOException {
- ServletRequest request = prepareServletRequest(servletRequest, servletResponse, chain);
- ServletResponse response = prepareServletResponse(request, servletResponse, chain);
+ Throwable t = null;
+
+ try {
+ final ServletRequest request = prepareServletRequest(servletRequest, servletResponse, chain);
+ final ServletResponse response = prepareServletResponse(request, servletResponse, chain);
- ThreadState threadState = null;
+ final Subject subject = createSubject(request, response);
- try {
- threadState = bind(request, response);
- updateSessionLastAccessTime(request, response);
- executeChain(request, response, chain);
- } finally {
- unbind(threadState);
+ //noinspection unchecked
+ subject.execute(new Callable() {
+ public Object call() throws Exception {
+ updateSessionLastAccessTime(request, response);
+ executeChain(request, response, chain);
+ return null;
+ }
+ });
+ } catch (ExecutionException ex) {
+ t = ex.getCause();
+ } catch (Throwable throwable) {
+ t = throwable;
+ }
+
+ if (t != null) {
+ if (t instanceof ServletException) {
+ throw (ServletException) t;
+ }
+ if (t instanceof IOException) {
+ throw (IOException) t;
+ }
+ //otherwise it's not one of the two exceptions expected by the filter method signature - wrap it in one:
+ String msg = "Filtered request failed.";
+ throw new ServletException(msg, t);
}
}
Modified: incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/servlet/ShiroHttpSession.java
URL: http://svn.apache.org/viewvc/incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/servlet/ShiroHttpSession.java?rev=945349&r1=945348&r2=945349&view=diff
==============================================================================
--- incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/servlet/ShiroHttpSession.java (original)
+++ incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/servlet/ShiroHttpSession.java Mon May 17 20:33:12 2010
@@ -20,7 +20,7 @@ package org.apache.shiro.web.servlet;
import org.apache.shiro.session.InvalidSessionException;
import org.apache.shiro.session.Session;
-import org.apache.shiro.web.session.WebSession;
+import org.apache.shiro.web.session.HttpServletSession;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
@@ -71,8 +71,8 @@ public class ShiroHttpSession implements
protected Session session = null; //'real' Shiro Session
public ShiroHttpSession(Session session, HttpServletRequest currentRequest, ServletContext servletContext) {
- if (session instanceof WebSession) {
- String msg = "Session constructor argument cannot be an instance of WebSession. This is enforced to " +
+ if (session instanceof HttpServletSession) {
+ String msg = "Session constructor argument cannot be an instance of HttpServletSession. This is enforced to " +
"prevent circular dependencies and infinite loops.";
throw new IllegalArgumentException(msg);
}
Added: incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/session/DefaultWebSessionContext.java
URL: http://svn.apache.org/viewvc/incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/session/DefaultWebSessionContext.java?rev=945349&view=auto
==============================================================================
--- incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/session/DefaultWebSessionContext.java (added)
+++ incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/session/DefaultWebSessionContext.java Mon May 17 20:33:12 2010
@@ -0,0 +1,68 @@
+/*
+ * 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.apache.shiro.web.session;
+
+import org.apache.shiro.session.mgt.DefaultSessionContext;
+
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import java.util.Map;
+
+/**
+ * Default implementation of the {@link WebSessionContext} interface which provides getters and setters that
+ * wrap interaction with the underlying backing context map.
+ *
+ * @author Les Hazlewood
+ * @since 1.0
+ */
+public class DefaultWebSessionContext extends DefaultSessionContext implements WebSessionContext {
+
+ private static final long serialVersionUID = -3974604687792523072L;
+
+ private static final String SERVLET_REQUEST = DefaultWebSessionContext.class.getName() + ".SERVLET_REQUEST";
+ private static final String SERVLET_RESPONSE = DefaultWebSessionContext.class.getName() + ".SERVLET_RESPONSE";
+
+ public DefaultWebSessionContext() {
+ super();
+ }
+
+ public DefaultWebSessionContext(Map<String, Object> map) {
+ super(map);
+ }
+
+ public void setServletRequest(ServletRequest request) {
+ if (request != null) {
+ put(SERVLET_REQUEST, request);
+ }
+ }
+
+ public ServletRequest getServletRequest() {
+ return getTypedValue(SERVLET_REQUEST, ServletRequest.class);
+ }
+
+ public void setServletResponse(ServletResponse response) {
+ if (response != null) {
+ put(SERVLET_RESPONSE, response);
+ }
+ }
+
+ public ServletResponse getServletResponse() {
+ return getTypedValue(SERVLET_RESPONSE, ServletResponse.class);
+ }
+}
Modified: incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/session/DefaultWebSessionManager.java
URL: http://svn.apache.org/viewvc/incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/session/DefaultWebSessionManager.java?rev=945349&r1=945348&r2=945349&view=diff
==============================================================================
--- incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/session/DefaultWebSessionManager.java (original)
+++ incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/session/DefaultWebSessionManager.java Mon May 17 20:33:12 2010
@@ -19,6 +19,7 @@
package org.apache.shiro.web.session;
import org.apache.shiro.session.Session;
+import org.apache.shiro.session.SessionException;
import org.apache.shiro.session.mgt.DefaultSessionManager;
import org.apache.shiro.web.WebUtils;
import org.apache.shiro.web.servlet.Cookie;
@@ -170,6 +171,15 @@ public class DefaultWebSessionManager ex
request.setAttribute(ShiroHttpServletRequest.REFERENCED_SESSION_IS_NEW, Boolean.TRUE);
}
+ public Session getSession(ServletRequest request, ServletResponse response) throws SessionException {
+ Serializable id = getReferencedSessionId(request, response);
+ Session session = null;
+ if ( id != null ) {
+ session = getSession(id);
+ }
+ return session;
+ }
+
public Serializable getSessionId(ServletRequest request, ServletResponse response) {
return getReferencedSessionId(request, response);
}
Modified: incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/session/DelegatingWebSessionManager.java
URL: http://svn.apache.org/viewvc/incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/session/DelegatingWebSessionManager.java?rev=945349&r1=945348&r2=945349&view=diff
==============================================================================
--- incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/session/DelegatingWebSessionManager.java (original)
+++ incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/session/DelegatingWebSessionManager.java Mon May 17 20:33:12 2010
@@ -23,6 +23,7 @@ import org.apache.shiro.session.InvalidS
import org.apache.shiro.session.Session;
import org.apache.shiro.session.SessionException;
import org.apache.shiro.session.mgt.DelegatingSession;
+import org.apache.shiro.session.mgt.SessionContext;
import org.apache.shiro.session.mgt.SessionManager;
import org.apache.shiro.util.ThreadContext;
import org.slf4j.Logger;
@@ -31,7 +32,6 @@ import org.slf4j.LoggerFactory;
import java.io.Serializable;
import java.util.Collection;
import java.util.Date;
-import java.util.Map;
/**
* WARNING: THIS IS A WORK IN PROGRESS AND IS NOT RECOMMENDED FOR USE!
@@ -94,10 +94,10 @@ public class DelegatingWebSessionManager
}
@Override
- protected Session doCreateSession(Map initData) {
+ protected Session doCreateSession(SessionContext initData) {
assertDelegateExists();
- Serializable sessionId = this.delegateSessionManager.start(initData);
- return new DelegatingSession(this, sessionId);
+ Session session = this.delegateSessionManager.start(initData);
+ return new DelegatingSession(this, session.getId());
}
@Override
@@ -167,16 +167,8 @@ public class DelegatingWebSessionManager
}
}
- public Serializable start(final String host) throws AuthorizationException {
- return (Serializable) execute(new SessionManagerCallback() {
- public Object doWithSessionManager(SessionManager sm) throws SessionException {
- return sm.start(host);
- }
- });
- }
-
- public Serializable start(final Map initData) throws AuthorizationException {
- return (Serializable) execute(new SessionManagerCallback() {
+ public Session start(final SessionContext initData) throws AuthorizationException {
+ return (Session) execute(new SessionManagerCallback() {
public Object doWithSessionManager(SessionManager sm) throws SessionException {
return sm.start(initData);
}
Copied: incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/session/HttpServletSession.java (from r944702, incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/session/WebSession.java)
URL: http://svn.apache.org/viewvc/incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/session/HttpServletSession.java?p2=incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/session/HttpServletSession.java&p1=incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/session/WebSession.java&r1=944702&r2=945349&rev=945349&view=diff
==============================================================================
--- incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/session/WebSession.java (original)
+++ incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/session/HttpServletSession.java Mon May 17 20:33:12 2010
@@ -30,23 +30,23 @@ import java.util.Collection;
import java.util.Date;
import java.util.Enumeration;
-
/**
- * TODO class JavaDoc
+ * {@link Session Session} implementation that is backed entirely by a standard servlet container
+ * {@link HttpSession HttpSession} instance. It does not interact with any of Shiro's session-related components
+ * {@code SessionManager}, {@code SecurityManager}, etc, and instead satisfies all method implementations by interacting
+ * with a servlet container provided {@link HttpSession HttpSession} instance.
*
* @author Les Hazlewood
- * @since 0.9
+ * @since 1.0
*/
-public class WebSession implements Session {
-
- //TODO - complete JavaDoc
+public class HttpServletSession implements Session {
- private static final String HOST_SESSION_KEY = WebSession.class.getName() + ".HOST_SESSION_KEY";
- private static final String TOUCH_OBJECT_SESSION_KEY = WebSession.class.getName() + ".TOUCH_OBJECT_SESSION_KEY";
+ private static final String HOST_SESSION_KEY = HttpServletSession.class.getName() + ".HOST_SESSION_KEY";
+ private static final String TOUCH_OBJECT_SESSION_KEY = HttpServletSession.class.getName() + ".TOUCH_OBJECT_SESSION_KEY";
private HttpSession httpSession = null;
- public WebSession(HttpSession httpSession, String host) {
+ public HttpServletSession(HttpSession httpSession, String host) {
if (httpSession == null) {
String msg = "HttpSession constructor argument cannot be null.";
throw new IllegalArgumentException(msg);
Modified: incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/session/ServletContainerSessionManager.java
URL: http://svn.apache.org/viewvc/incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/session/ServletContainerSessionManager.java?rev=945349&r1=945348&r2=945349&view=diff
==============================================================================
--- incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/session/ServletContainerSessionManager.java (original)
+++ incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/session/ServletContainerSessionManager.java Mon May 17 20:33:12 2010
@@ -22,15 +22,13 @@ import org.apache.shiro.authz.Authorizat
import org.apache.shiro.session.InvalidSessionException;
import org.apache.shiro.session.Session;
import org.apache.shiro.session.mgt.AbstractSessionManager;
-import org.apache.shiro.session.mgt.SessionFactory;
-import org.apache.shiro.web.WebUtils;
+import org.apache.shiro.session.mgt.SessionContext;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.io.Serializable;
-import java.util.Map;
/**
@@ -62,15 +60,43 @@ public class ServletContainerSessionMana
public ServletContainerSessionManager() {
}
+ @Override
+ public Session start(SessionContext initData) throws AuthorizationException {
+ return createSession(initData);
+ }
+
+ /**
+ * This method exists only to satisfy the parent's abstract method signature. It should never be called since
+ * there is no way to obtain a Session instance from a Servlet Container by id (in a system independent
+ * manner).
+ * <p/>
+ * This method will always throw an exception if called since the
+ * {@link #getSession(javax.servlet.ServletRequest, javax.servlet.ServletResponse)} method should be used in all
+ * cases instead.
+ *
+ * @param sessionId
+ * @return
+ * @throws InvalidSessionException
+ */
protected Session doGetSession(Serializable sessionId) throws InvalidSessionException {
//Ignore session id since there is no way to acquire a session based on an id in a servlet container
//(that is implementation agnostic)
- ServletRequest request = WebUtils.getRequiredServletRequest();
- ServletResponse response = WebUtils.getRequiredServletResponse();
- return getSession(request, response);
+ String msg = "Cannot retrieve sessions by ID when Sessions are managed by the Servlet Container. This " +
+ "feature is available for Shiro 'native' session SessionManager implementations only.";
+ throw new IllegalStateException(msg);
+ /*ServletRequest request = WebUtils.getServletRequest();
+ ServletResponse response = WebUtils.getServletResponse();
+ if (request == null) {
+ String msg = "Thread-bound ServletRequest cannot be null in ServletContainer-managed Session environments.";
+ throw new IllegalStateException(msg);
+ }
+ return getSession(request, response);*/
}
- protected Session getSession(ServletRequest request, ServletResponse response) throws AuthorizationException {
+ /**
+ * @since 1.0
+ */
+ public Session getSession(ServletRequest request, ServletResponse response) {
Session session = null;
HttpSession httpSession = ((HttpServletRequest) request).getSession(false);
if (httpSession != null) {
@@ -79,32 +105,51 @@ public class ServletContainerSessionMana
return session;
}
+ /**
+ * @since 1.0
+ */
public Serializable getSessionId(ServletRequest request, ServletResponse response) {
HttpSession httpSession = ((HttpServletRequest) request).getSession(false);
return httpSession != null ? httpSession.getId() : null;
}
- protected Session createSession(Map initData) throws AuthorizationException {
+ /**
+ * @since 1.0
+ */
+ protected Session createSession(SessionContext sessionContext) throws AuthorizationException {
+ if (!(sessionContext instanceof WebSessionContext)) {
+ String msg = "SessionContext must be a " + WebSessionContext.class.getName() + " instance.";
+ throw new IllegalArgumentException(msg);
+ }
+
+ WebSessionContext wsc = (WebSessionContext) sessionContext;
+
+ ServletRequest request = wsc.getServletRequest();
+ if (request == null) {
+ String msg = "WebSessionContext must contain a ServletRequest.";
+ throw new IllegalStateException(msg);
+ }
+ ServletResponse response = wsc.getServletResponse();
+ if (response == null) {
+ String msg = "WebSessionContext must contain a ServletResponse.";
+ throw new IllegalStateException(msg);
+ }
- ServletRequest request = WebUtils.getRequiredServletRequest();
HttpSession httpSession = ((HttpServletRequest) request).getSession();
//ensure that the httpSession timeout reflects what is configured:
long timeoutMillis = getGlobalSessionTimeout();
httpSession.setMaxInactiveInterval((int) (timeoutMillis / MILLIS_PER_SECOND));
- String originatingHost;
- if (initData != null && initData.containsKey(SessionFactory.HOST_KEY)) {
- originatingHost = (String) initData.get(SessionFactory.HOST_KEY);
- } else {
+ String originatingHost = wsc.getHost();
+ if (originatingHost == null) {
originatingHost = request.getRemoteHost();
}
-
return createSession(httpSession, originatingHost);
}
protected Session createSession(HttpSession httpSession, String host) {
- return new WebSession(httpSession, host);
+ return new HttpServletSession(httpSession, host);
}
}
Added: incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/session/WebSessionContext.java
URL: http://svn.apache.org/viewvc/incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/session/WebSessionContext.java?rev=945349&view=auto
==============================================================================
--- incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/session/WebSessionContext.java (added)
+++ incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/session/WebSessionContext.java Mon May 17 20:33:12 2010
@@ -0,0 +1,69 @@
+/*
+ * 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.apache.shiro.web.session;
+
+import org.apache.shiro.session.mgt.SessionContext;
+
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+
+/**
+ * A {@code WebSubjectContext} is a {@link SessionContext} that additionally provides for type-safe
+ * methods to set and retrieve a {@link ServletRequest} and {@link ServletResponse}, as the request/response pair will
+ * often need to be referenced during construction of web-initiated {@code Session} instances.
+ *
+ * @author Les Hazlewood
+ * @since 1.0
+ */
+public interface WebSessionContext extends SessionContext {
+
+ /**
+ * Returns the {@code ServletRequest} received by the servlet container triggering the creation of the
+ * {@code Session} instance.
+ *
+ * @return the {@code ServletRequest} received by the servlet container triggering the creation of the
+ * {@code Session} instance.
+ */
+ ServletRequest getServletRequest();
+
+ /**
+ * Sets the {@code ServletRequest} received by the servlet container triggering the creation of the
+ * {@code Session} instance.
+ *
+ * @param request the {@code ServletRequest} received by the servlet container triggering the creation of the
+ * {@code Session} instance.
+ */
+ void setServletRequest(ServletRequest request);
+
+ /**
+ * The paired {@code ServletResponse} corresponding to the associated {@link #getServletRequest servletRequest}.
+ *
+ * @return the paired {@code ServletResponse} corresponding to the associated
+ * {@link #getServletRequest servletRequest}.
+ */
+ ServletResponse getServletResponse();
+
+ /**
+ * Sets the paired {@code ServletResponse} corresponding to the associated {@link #getServletRequest servletRequest}.
+ *
+ * @param response The paired {@code ServletResponse} corresponding to the associated
+ * {@link #getServletRequest servletRequest}.
+ */
+ void setServletResponse(ServletResponse response);
+}
Modified: incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/session/WebSessionManager.java
URL: http://svn.apache.org/viewvc/incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/session/WebSessionManager.java?rev=945349&r1=945348&r2=945349&view=diff
==============================================================================
--- incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/session/WebSessionManager.java (original)
+++ incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/session/WebSessionManager.java Mon May 17 20:33:12 2010
@@ -18,6 +18,8 @@
*/
package org.apache.shiro.web.session;
+import org.apache.shiro.session.Session;
+import org.apache.shiro.session.SessionException;
import org.apache.shiro.session.mgt.SessionManager;
import javax.servlet.ServletRequest;
@@ -45,4 +47,17 @@ public interface WebSessionManager exten
* @since 1.0
*/
Serializable getSessionId(ServletRequest request, ServletResponse response);
+
+ /**
+ * Returns the session associated with the specified request pair or {@code null} if there is no session
+ * associated with the request.
+ *
+ * @param request the incoming {@code ServletRequest}
+ * @param response the outgoing {@code ServletResponse}
+ * @return the current session associated with the specified request pair, or {@code null} if there is no
+ * session associated with the request.
+ * @throws SessionException if there is a problem acquiring the Session associated with the request/response pair
+ * @since 1.0
+ */
+ Session getSession(ServletRequest request, ServletResponse response) throws SessionException;
}
Modified: incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/subject/WebSubject.java
URL: http://svn.apache.org/viewvc/incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/subject/WebSubject.java?rev=945349&r1=945348&r2=945349&view=diff
==============================================================================
--- incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/subject/WebSubject.java (original)
+++ incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/subject/WebSubject.java Mon May 17 20:33:12 2010
@@ -22,7 +22,6 @@ import org.apache.shiro.SecurityUtils;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.subject.SubjectContext;
-import org.apache.shiro.web.WebUtils;
import org.apache.shiro.web.subject.support.DefaultWebSubjectContext;
import javax.servlet.ServletRequest;
@@ -52,16 +51,6 @@ public interface WebSubject extends Subj
public static class Builder extends Subject.Builder {
- public Builder() {
- this(SecurityUtils.getSecurityManager(),
- WebUtils.getRequiredServletRequest(),
- WebUtils.getRequiredServletResponse());
- }
-
- public Builder(SecurityManager securityManager) {
- this(securityManager, WebUtils.getRequiredServletRequest(), WebUtils.getRequiredServletResponse());
- }
-
public Builder(ServletRequest request, ServletResponse response) {
this(SecurityUtils.getSecurityManager(), request, response);
}
Modified: incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/subject/support/DefaultWebSubjectContext.java
URL: http://svn.apache.org/viewvc/incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/subject/support/DefaultWebSubjectContext.java?rev=945349&r1=945348&r2=945349&view=diff
==============================================================================
--- incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/subject/support/DefaultWebSubjectContext.java (original)
+++ incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/subject/support/DefaultWebSubjectContext.java Mon May 17 20:33:12 2010
@@ -36,8 +36,9 @@ import javax.servlet.ServletResponse;
*/
public class DefaultWebSubjectContext extends DefaultSubjectContext implements WebSubjectContext {
- private static final String SERVLET_REQUEST = DefaultWebSubjectContext.class.getName() + ".SERVLET_REQUEST";
+ private static final long serialVersionUID = 8188555355305827739L;
+ private static final String SERVLET_REQUEST = DefaultWebSubjectContext.class.getName() + ".SERVLET_REQUEST";
private static final String SERVLET_RESPONSE = DefaultWebSubjectContext.class.getName() + ".SERVLET_RESPONSE";
public DefaultWebSubjectContext() {
Modified: incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/subject/support/WebDelegatingSubject.java
URL: http://svn.apache.org/viewvc/incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/subject/support/WebDelegatingSubject.java?rev=945349&r1=945348&r2=945349&view=diff
==============================================================================
--- incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/subject/support/WebDelegatingSubject.java (original)
+++ incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/subject/support/WebDelegatingSubject.java Mon May 17 20:33:12 2010
@@ -20,8 +20,12 @@ package org.apache.shiro.web.subject.sup
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.session.Session;
+import org.apache.shiro.session.mgt.SessionContext;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.subject.support.DelegatingSubject;
+import org.apache.shiro.util.StringUtils;
+import org.apache.shiro.web.session.DefaultWebSessionContext;
+import org.apache.shiro.web.session.WebSessionContext;
import org.apache.shiro.web.subject.WebSubject;
import javax.servlet.ServletRequest;
@@ -33,6 +37,8 @@ import java.util.concurrent.Callable;
*/
public class WebDelegatingSubject extends DelegatingSubject implements WebSubject {
+ private static final long serialVersionUID = -1655724323350159250L;
+
private final ServletRequest servletRequest;
private final ServletResponse servletResponse;
@@ -54,6 +60,18 @@ public class WebDelegatingSubject extend
}
@Override
+ protected SessionContext createSessionContext() {
+ WebSessionContext wsc = new DefaultWebSessionContext();
+ String host = getHost();
+ if (StringUtils.hasText(host)) {
+ wsc.setHost(host);
+ }
+ wsc.setServletRequest(this.servletRequest);
+ wsc.setServletResponse(this.servletResponse);
+ return wsc;
+ }
+
+ @Override
public <V> Callable<V> associateWith(Callable<V> callable) {
return new WebSubjectCallable<V>(this, callable);
}
Modified: incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/subject/support/WebSubjectThreadState.java
URL: http://svn.apache.org/viewvc/incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/subject/support/WebSubjectThreadState.java?rev=945349&r1=945348&r2=945349&view=diff
==============================================================================
--- incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/subject/support/WebSubjectThreadState.java (original)
+++ incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/subject/support/WebSubjectThreadState.java Mon May 17 20:33:12 2010
@@ -26,6 +26,11 @@ import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
/**
+ * Web-specific {@code SubjectThreadState} implementation that, in addition to the parent class's bind/unbind
+ * behavior, also ensures that a {@link ServletRequest ServletRequest} and {@link ServletResponse ServletResponse}
+ * pair are also bound/unbound as necessary.
+ *
+ * @author Les Hazlewood
* @since 1.0
*/
public class WebSubjectThreadState extends SubjectThreadState {
@@ -33,6 +38,15 @@ public class WebSubjectThreadState exten
private final ServletRequest request;
private final ServletResponse response;
+ /**
+ * Creates a new {@code WebSubjectThreadState} instance, retaining the {@link WebSubject} argument's
+ * {@link org.apache.shiro.web.subject.WebSubject#getServletRequest() servletRequest} and
+ * {@link org.apache.shiro.web.subject.WebSubject#getServletResponse() servletResponse} in addition to any
+ * state retained by the parent class's constructor.
+ *
+ * @param subject the {@link WebSubject} to bind as well as from which to acquire the
+ * {@code ServletRequest} and {@code ServletResponse} pair.
+ */
public WebSubjectThreadState(WebSubject subject) {
super(subject);
@@ -49,6 +63,12 @@ public class WebSubjectThreadState exten
this.response = response;
}
+ /**
+ * Calls {@code super.bind()} and then additionally binds the internal {@code ServletRequest} and
+ * {@code ServletResponse} pair via
+ * {@code WebUtils.}{@link WebUtils#bind(javax.servlet.ServletRequest) bind(ServletRequest)} and
+ * {@code WebUtils.}{@link WebUtils#bind(javax.servlet.ServletResponse) bind(ServletResponse)}, respectively.
+ */
@Override
public void bind() {
super.bind();
Modified: incubator/shiro/trunk/web/src/test/java/org/apache/shiro/web/DelegatingWebSecurityManagerTest.java
URL: http://svn.apache.org/viewvc/incubator/shiro/trunk/web/src/test/java/org/apache/shiro/web/DelegatingWebSecurityManagerTest.java?rev=945349&r1=945348&r2=945349&view=diff
==============================================================================
--- incubator/shiro/trunk/web/src/test/java/org/apache/shiro/web/DelegatingWebSecurityManagerTest.java (original)
+++ incubator/shiro/trunk/web/src/test/java/org/apache/shiro/web/DelegatingWebSecurityManagerTest.java Mon May 17 20:33:12 2010
@@ -22,6 +22,8 @@ import org.apache.shiro.mgt.SecurityMana
import org.apache.shiro.session.ExpiredSessionException;
import org.apache.shiro.session.Session;
import org.apache.shiro.session.mgt.AbstractSessionManager;
+import org.apache.shiro.session.mgt.DelegatingSession;
+import org.apache.shiro.session.mgt.SessionContext;
import org.apache.shiro.subject.Subject;
import org.easymock.EasyMock;
import org.junit.After;
@@ -33,7 +35,6 @@ import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.Serializable;
-import java.util.Map;
import java.util.UUID;
import static org.easymock.EasyMock.*;
@@ -78,7 +79,7 @@ public class DelegatingWebSecurityManage
String host = "192.168.1.1";
Serializable sessionId = UUID.randomUUID().toString();
- expect(delegate.start(EasyMock.<Map>anyObject())).andReturn(sessionId);
+ expect(delegate.start(EasyMock.<SessionContext>anyObject())).andReturn(new DelegatingSession(sm, sessionId));
expect(delegate.getHost(sessionId)).andReturn(host);
expect(delegate.getTimeout(sessionId)).andReturn(AbstractSessionManager.DEFAULT_GLOBAL_SESSION_TIMEOUT);
delegate.setTimeout(sessionId, 125L);
Modified: incubator/shiro/trunk/web/src/test/java/org/apache/shiro/web/filter/mgt/SimpleNamedFilterListTest.java
URL: http://svn.apache.org/viewvc/incubator/shiro/trunk/web/src/test/java/org/apache/shiro/web/filter/mgt/SimpleNamedFilterListTest.java?rev=945349&r1=945348&r2=945349&view=diff
==============================================================================
--- incubator/shiro/trunk/web/src/test/java/org/apache/shiro/web/filter/mgt/SimpleNamedFilterListTest.java (original)
+++ incubator/shiro/trunk/web/src/test/java/org/apache/shiro/web/filter/mgt/SimpleNamedFilterListTest.java Mon May 17 20:33:12 2010
@@ -24,16 +24,14 @@ import org.apache.shiro.web.filter.authz
import org.apache.shiro.web.filter.authz.PortFilter;
import org.apache.shiro.web.filter.authz.RolesAuthorizationFilter;
import org.apache.shiro.web.filter.authz.SslFilter;
-import static org.easymock.EasyMock.*;
-import static org.junit.Assert.*;
import org.junit.Test;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-import java.util.ListIterator;
+import java.util.*;
+
+import static org.easymock.EasyMock.createNiceMock;
+import static org.junit.Assert.*;
/**
* Test case for the {@link SimpleNamedFilterList} implementation.
@@ -57,8 +55,7 @@ public class SimpleNamedFilterListTest {
@Test
public void testNewInstanceBackingList() {
- //noinspection unchecked
- new SimpleNamedFilterList("test", new ArrayList());
+ new SimpleNamedFilterList("test", new ArrayList<Filter>());
}
@Test(expected = NullPointerException.class)
@@ -87,7 +84,7 @@ public class SimpleNamedFilterListTest {
list.add(0, singleFilter);
assertEquals(2, list.size());
assertTrue(list.get(0) instanceof SslFilter);
- assertEquals(list.toArray(), new Object[]{singleFilter, filter});
+ assertTrue(Arrays.equals(list.toArray(), new Object[]{singleFilter, filter}));
list.addAll(multipleFilters);
assertEquals(4, list.size());