001    /*
002     * Licensed to the Apache Software Foundation (ASF) under one
003     * or more contributor license agreements.  See the NOTICE file
004     * distributed with this work for additional information
005     * regarding copyright ownership.  The ASF licenses this file
006     * to you under the Apache License, Version 2.0 (the
007     * "License"); you may not use this file except in compliance
008     * with the License.  You may obtain a copy of the License at
009     *
010     *     http://www.apache.org/licenses/LICENSE-2.0
011     *
012     * Unless required by applicable law or agreed to in writing,
013     * software distributed under the License is distributed on an
014     * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015     * KIND, either express or implied.  See the License for the
016     * specific language governing permissions and limitations
017     * under the License.
018     */
019    package org.apache.shiro.web.session.mgt;
020    
021    import org.apache.shiro.authz.AuthorizationException;
022    import org.apache.shiro.session.Session;
023    import org.apache.shiro.session.SessionException;
024    import org.apache.shiro.session.mgt.AbstractSessionManager;
025    import org.apache.shiro.session.mgt.SessionContext;
026    import org.apache.shiro.session.mgt.SessionKey;
027    import org.apache.shiro.web.session.HttpServletSession;
028    import org.apache.shiro.web.util.WebUtils;
029    
030    import javax.servlet.ServletRequest;
031    import javax.servlet.http.HttpServletRequest;
032    import javax.servlet.http.HttpSession;
033    
034    
035    /**
036     * SessionManager implementation providing Session implementations that are merely wrappers for the
037     * Servlet container's HttpSession.
038     * <p/>
039     * Despite its name, this implementation <em>does not</em> itself manage Sessions since the Servlet container
040     * provides the actual management support.  This class mainly exists to 'impersonate' a regular Shiro
041     * <tt>SessionManager</tt> so it can be pluggable into a normal Shiro configuration in a pure web application.
042     * <p/>
043     * Note that because this implementation relies on the {@link HttpSession HttpSession}, it is only functional in a
044     * servlet container.  I.e. it is <em>NOT</em> capable of supporting Sessions any clients other than
045     * {@code HttpRequest/HttpResponse} based clients.
046     * <p/>
047     * Therefore, if you need {@code Session} access from heterogenous client mediums (e.g. web pages,
048     * Flash applets, Java Web Start applications, etc.), use the {@link DefaultWebSessionManager DefaultWebSessionManager}
049     * instead.  The {@code DefaultWebSessionManager} supports both traditional web-based access as well as non web-based
050     * clients.
051     *
052     * @since 0.9
053     */
054    public class ServletContainerSessionManager extends AbstractSessionManager {
055    
056        //TODO - complete JavaDoc
057    
058        //TODO - read session timeout value from web.xml
059    
060        public ServletContainerSessionManager() {
061        }
062    
063        public Session start(SessionContext context) throws AuthorizationException {
064            return createSession(context);
065        }
066    
067        public Session getSession(SessionKey key) throws SessionException {
068            if (!WebUtils.isHttp(key)) {
069                String msg = "SessionKey must be an HTTP compatible implementation.";
070                throw new IllegalArgumentException(msg);
071            }
072    
073            HttpServletRequest request = WebUtils.getHttpRequest(key);
074    
075            Session session = null;
076    
077            HttpSession httpSession = request.getSession(false);
078            if (httpSession != null) {
079                session = createSession(httpSession, request.getRemoteHost());
080            }
081    
082            return session;
083        }
084    
085        private String getHost(SessionContext context) {
086            String host = context.getHost();
087            if (host == null) {
088                ServletRequest request = WebUtils.getRequest(context);
089                if (request != null) {
090                    host = request.getRemoteHost();
091                }
092            }
093            return host;
094    
095        }
096    
097        /**
098         * @since 1.0
099         */
100        protected Session createSession(SessionContext sessionContext) throws AuthorizationException {
101            if (!WebUtils.isHttp(sessionContext)) {
102                String msg = "SessionContext must be an HTTP compatible implementation.";
103                throw new IllegalArgumentException(msg);
104            }
105    
106            HttpServletRequest request = WebUtils.getHttpRequest(sessionContext);
107    
108            HttpSession httpSession = request.getSession();
109    
110            //ensure that the httpSession timeout reflects what is configured:
111            long timeoutMillis = getGlobalSessionTimeout();
112            httpSession.setMaxInactiveInterval((int) (timeoutMillis / MILLIS_PER_SECOND));
113    
114            String host = getHost(sessionContext);
115    
116            return createSession(httpSession, host);
117        }
118    
119        protected Session createSession(HttpSession httpSession, String host) {
120            return new HttpServletSession(httpSession, host);
121        }
122    
123    }