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 }