View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *     http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.apache.shiro.web.session.mgt;
20  
21  import org.apache.shiro.authz.AuthorizationException;
22  import org.apache.shiro.session.Session;
23  import org.apache.shiro.session.SessionException;
24  import org.apache.shiro.session.mgt.SessionContext;
25  import org.apache.shiro.session.mgt.SessionKey;
26  import org.apache.shiro.web.session.HttpServletSession;
27  import org.apache.shiro.web.util.WebUtils;
28  
29  import javax.servlet.ServletRequest;
30  import javax.servlet.http.HttpServletRequest;
31  import javax.servlet.http.HttpSession;
32  
33  
34  /**
35   * SessionManager implementation providing {@link Session} implementations that are merely wrappers for the
36   * Servlet container's {@link HttpSession}.
37   * <p/>
38   * Despite its name, this implementation <em>does not</em> itself manage Sessions since the Servlet container
39   * provides the actual management support.  This class mainly exists to 'impersonate' a regular Shiro
40   * {@code SessionManager} so it can be pluggable into a normal Shiro configuration in a pure web application.
41   * <p/>
42   * Note that because this implementation relies on the {@link HttpSession HttpSession}, it is only functional in a
43   * servlet container - it is not capable of supporting Sessions for any clients other than those using the HTTP
44   * protocol.
45   * <p/>
46   * Therefore, if you need {@code Session} support for heterogeneous clients (e.g. web browsers,
47   * RMI clients, etc.), use the {@link DefaultWebSessionManager DefaultWebSessionManager}
48   * instead.  The {@code DefaultWebSessionManager} supports both traditional web-based access as well as non web-based
49   * clients.
50   *
51   * @see DefaultWebSessionManager
52   * @since 0.9
53   */
54  public class ServletContainerSessionManager implements WebSessionManager {
55  
56      //TODO - complete JavaDoc
57  
58      //TODO - read session timeout value from web.xml
59  
60      public ServletContainerSessionManager() {
61      }
62  
63      public Session start(SessionContext context) throws AuthorizationException {
64          return createSession(context);
65      }
66  
67      public Session getSession(SessionKey key) throws SessionException {
68          if (!WebUtils.isHttp(key)) {
69              String msg = "SessionKey must be an HTTP compatible implementation.";
70              throw new IllegalArgumentException(msg);
71          }
72  
73          HttpServletRequest request = WebUtils.getHttpRequest(key);
74  
75          Session session = null;
76  
77          HttpSession httpSession = request.getSession(false);
78          if (httpSession != null) {
79              session = createSession(httpSession, request.getRemoteHost());
80          }
81  
82          return session;
83      }
84  
85      private String getHost(SessionContext context) {
86          String host = context.getHost();
87          if (host == null) {
88              ServletRequest request = WebUtils.getRequest(context);
89              if (request != null) {
90                  host = request.getRemoteHost();
91              }
92          }
93          return host;
94  
95      }
96  
97      /**
98       * @since 1.0
99       */
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         //SHIRO-240: DO NOT use the 'globalSessionTimeout' value here on the acquired session.
111         //see: https://issues.apache.org/jira/browse/SHIRO-240
112 
113         String host = getHost(sessionContext);
114 
115         return createSession(httpSession, host);
116     }
117 
118     protected Session createSession(HttpSession httpSession, String host) {
119         return new HttpServletSession(httpSession, host);
120     }
121 
122     /**
123      * This implementation always delegates to the servlet container for sessions, so this method returns
124      * {@code true} always.
125      *
126      * @return {@code true} always
127      * @since 1.2
128      */
129     public boolean isServletContainerSessions() {
130         return true;
131     }
132 
133 }