1 | |
|
2 | |
|
3 | |
|
4 | |
|
5 | |
|
6 | |
|
7 | |
|
8 | |
|
9 | |
|
10 | |
|
11 | |
|
12 | |
|
13 | |
|
14 | |
|
15 | |
|
16 | |
|
17 | |
|
18 | |
|
19 | |
package org.apache.shiro.web.mgt; |
20 | |
|
21 | |
import org.apache.shiro.mgt.DefaultSecurityManager; |
22 | |
import org.apache.shiro.mgt.DefaultSubjectDAO; |
23 | |
import org.apache.shiro.mgt.SessionStorageEvaluator; |
24 | |
import org.apache.shiro.mgt.SubjectDAO; |
25 | |
import org.apache.shiro.realm.Realm; |
26 | |
import org.apache.shiro.session.mgt.SessionContext; |
27 | |
import org.apache.shiro.session.mgt.SessionKey; |
28 | |
import org.apache.shiro.session.mgt.SessionManager; |
29 | |
import org.apache.shiro.subject.Subject; |
30 | |
import org.apache.shiro.subject.SubjectContext; |
31 | |
import org.apache.shiro.util.LifecycleUtils; |
32 | |
import org.apache.shiro.web.servlet.ShiroHttpServletRequest; |
33 | |
import org.apache.shiro.web.session.mgt.*; |
34 | |
import org.apache.shiro.web.subject.WebSubject; |
35 | |
import org.apache.shiro.web.subject.WebSubjectContext; |
36 | |
import org.apache.shiro.web.subject.support.DefaultWebSubjectContext; |
37 | |
import org.apache.shiro.web.util.WebUtils; |
38 | |
import org.slf4j.Logger; |
39 | |
import org.slf4j.LoggerFactory; |
40 | |
|
41 | |
import javax.servlet.ServletRequest; |
42 | |
import javax.servlet.ServletResponse; |
43 | |
import java.io.Serializable; |
44 | |
import java.util.Collection; |
45 | |
|
46 | |
|
47 | |
|
48 | |
|
49 | |
|
50 | |
|
51 | |
|
52 | |
|
53 | |
public class DefaultWebSecurityManager extends DefaultSecurityManager implements WebSecurityManager { |
54 | |
|
55 | |
|
56 | |
|
57 | 1 | private static final Logger log = LoggerFactory.getLogger(DefaultWebSecurityManager.class); |
58 | |
|
59 | |
@Deprecated |
60 | |
public static final String HTTP_SESSION_MODE = "http"; |
61 | |
@Deprecated |
62 | |
public static final String NATIVE_SESSION_MODE = "native"; |
63 | |
|
64 | |
|
65 | |
|
66 | |
|
67 | |
@Deprecated |
68 | |
private String sessionMode; |
69 | |
|
70 | |
public DefaultWebSecurityManager() { |
71 | 14 | super(); |
72 | 14 | ((DefaultSubjectDAO) this.subjectDAO).setSessionStorageEvaluator(new DefaultWebSessionStorageEvaluator()); |
73 | 14 | this.sessionMode = HTTP_SESSION_MODE; |
74 | 14 | setSubjectFactory(new DefaultWebSubjectFactory()); |
75 | 14 | setRememberMeManager(new CookieRememberMeManager()); |
76 | 14 | setSessionManager(new ServletContainerSessionManager()); |
77 | 14 | } |
78 | |
|
79 | |
@SuppressWarnings({"UnusedDeclaration"}) |
80 | |
public DefaultWebSecurityManager(Realm singleRealm) { |
81 | 0 | this(); |
82 | 0 | setRealm(singleRealm); |
83 | 0 | } |
84 | |
|
85 | |
@SuppressWarnings({"UnusedDeclaration"}) |
86 | |
public DefaultWebSecurityManager(Collection<Realm> realms) { |
87 | 0 | this(); |
88 | 0 | setRealms(realms); |
89 | 0 | } |
90 | |
|
91 | |
@Override |
92 | |
protected SubjectContext createSubjectContext() { |
93 | 1 | return new DefaultWebSubjectContext(); |
94 | |
} |
95 | |
|
96 | |
@Override |
97 | |
|
98 | |
public void setSubjectDAO(SubjectDAO subjectDAO) { |
99 | 0 | super.setSubjectDAO(subjectDAO); |
100 | 0 | applySessionManagerToSessionStorageEvaluatorIfPossible(); |
101 | 0 | } |
102 | |
|
103 | |
|
104 | |
@Override |
105 | |
protected void afterSessionManagerSet() { |
106 | 22 | super.afterSessionManagerSet(); |
107 | 22 | applySessionManagerToSessionStorageEvaluatorIfPossible(); |
108 | 22 | } |
109 | |
|
110 | |
|
111 | |
private void applySessionManagerToSessionStorageEvaluatorIfPossible() { |
112 | 22 | SubjectDAO subjectDAO = getSubjectDAO(); |
113 | 22 | if (subjectDAO instanceof DefaultSubjectDAO) { |
114 | 22 | SessionStorageEvaluator evaluator = ((DefaultSubjectDAO)subjectDAO).getSessionStorageEvaluator(); |
115 | 22 | if (evaluator instanceof DefaultWebSessionStorageEvaluator) { |
116 | 22 | ((DefaultWebSessionStorageEvaluator)evaluator).setSessionManager(getSessionManager()); |
117 | |
} |
118 | |
} |
119 | 22 | } |
120 | |
|
121 | |
@Override |
122 | |
protected SubjectContext copy(SubjectContext subjectContext) { |
123 | 7 | if (subjectContext instanceof WebSubjectContext) { |
124 | 6 | return new DefaultWebSubjectContext((WebSubjectContext) subjectContext); |
125 | |
} |
126 | 1 | return super.copy(subjectContext); |
127 | |
} |
128 | |
|
129 | |
@SuppressWarnings({"UnusedDeclaration"}) |
130 | |
@Deprecated |
131 | |
public String getSessionMode() { |
132 | 0 | return sessionMode; |
133 | |
} |
134 | |
|
135 | |
|
136 | |
|
137 | |
|
138 | |
|
139 | |
@Deprecated |
140 | |
public void setSessionMode(String sessionMode) { |
141 | 12 | log.warn("The 'sessionMode' property has been deprecated. Please configure an appropriate WebSessionManager " + |
142 | |
"instance instead of using this property. This property/method will be removed in a later version."); |
143 | 12 | String mode = sessionMode; |
144 | 12 | if (mode == null) { |
145 | 0 | throw new IllegalArgumentException("sessionMode argument cannot be null."); |
146 | |
} |
147 | 12 | mode = sessionMode.toLowerCase(); |
148 | 12 | if (!HTTP_SESSION_MODE.equals(mode) && !NATIVE_SESSION_MODE.equals(mode)) { |
149 | 0 | String msg = "Invalid sessionMode [" + sessionMode + "]. Allowed values are " + |
150 | |
"public static final String constants in the " + getClass().getName() + " class: '" |
151 | |
+ HTTP_SESSION_MODE + "' or '" + NATIVE_SESSION_MODE + "', with '" + |
152 | |
HTTP_SESSION_MODE + "' being the default."; |
153 | 0 | throw new IllegalArgumentException(msg); |
154 | |
} |
155 | 12 | boolean recreate = this.sessionMode == null || !this.sessionMode.equals(mode); |
156 | 12 | this.sessionMode = mode; |
157 | 12 | if (recreate) { |
158 | 7 | LifecycleUtils.destroy(getSessionManager()); |
159 | 7 | SessionManager sessionManager = createSessionManager(mode); |
160 | 7 | this.setInternalSessionManager(sessionManager); |
161 | |
} |
162 | 12 | } |
163 | |
|
164 | |
@Override |
165 | |
public void setSessionManager(SessionManager sessionManager) { |
166 | 15 | this.sessionMode = null; |
167 | 15 | if (sessionManager != null && !(sessionManager instanceof WebSessionManager)) { |
168 | 0 | if (log.isWarnEnabled()) { |
169 | 0 | String msg = "The " + getClass().getName() + " implementation expects SessionManager instances " + |
170 | |
"that implement the " + WebSessionManager.class.getName() + " interface. The " + |
171 | |
"configured instance is of type [" + sessionManager.getClass().getName() + "] which does not " + |
172 | |
"implement this interface.. This may cause unexpected behavior."; |
173 | 0 | log.warn(msg); |
174 | |
} |
175 | |
} |
176 | 15 | setInternalSessionManager(sessionManager); |
177 | 15 | } |
178 | |
|
179 | |
|
180 | |
|
181 | |
|
182 | |
|
183 | |
private void setInternalSessionManager(SessionManager sessionManager) { |
184 | 22 | super.setSessionManager(sessionManager); |
185 | 22 | } |
186 | |
|
187 | |
|
188 | |
|
189 | |
|
190 | |
public boolean isHttpSessionMode() { |
191 | 1 | SessionManager sessionManager = getSessionManager(); |
192 | 1 | return sessionManager instanceof WebSessionManager && ((WebSessionManager)sessionManager).isServletContainerSessions(); |
193 | |
} |
194 | |
|
195 | |
protected SessionManager createSessionManager(String sessionMode) { |
196 | 7 | if (sessionMode == null || !sessionMode.equalsIgnoreCase(NATIVE_SESSION_MODE)) { |
197 | 0 | log.info("{} mode - enabling ServletContainerSessionManager (HTTP-only Sessions)", HTTP_SESSION_MODE); |
198 | 0 | return new ServletContainerSessionManager(); |
199 | |
} else { |
200 | 7 | log.info("{} mode - enabling DefaultWebSessionManager (non-HTTP and HTTP Sessions)", NATIVE_SESSION_MODE); |
201 | 7 | return new DefaultWebSessionManager(); |
202 | |
} |
203 | |
} |
204 | |
|
205 | |
@Override |
206 | |
protected SessionContext createSessionContext(SubjectContext subjectContext) { |
207 | 0 | SessionContext sessionContext = super.createSessionContext(subjectContext); |
208 | 0 | if (subjectContext instanceof WebSubjectContext) { |
209 | 0 | WebSubjectContext wsc = (WebSubjectContext) subjectContext; |
210 | 0 | ServletRequest request = wsc.resolveServletRequest(); |
211 | 0 | ServletResponse response = wsc.resolveServletResponse(); |
212 | 0 | DefaultWebSessionContext webSessionContext = new DefaultWebSessionContext(sessionContext); |
213 | 0 | if (request != null) { |
214 | 0 | webSessionContext.setServletRequest(request); |
215 | |
} |
216 | 0 | if (response != null) { |
217 | 0 | webSessionContext.setServletResponse(response); |
218 | |
} |
219 | |
|
220 | 0 | sessionContext = webSessionContext; |
221 | |
} |
222 | 0 | return sessionContext; |
223 | |
} |
224 | |
|
225 | |
@Override |
226 | |
protected SessionKey getSessionKey(SubjectContext context) { |
227 | 7 | if (WebUtils.isWeb(context)) { |
228 | 5 | Serializable sessionId = context.getSessionId(); |
229 | 5 | ServletRequest request = WebUtils.getRequest(context); |
230 | 5 | ServletResponse response = WebUtils.getResponse(context); |
231 | 5 | return new WebSessionKey(sessionId, request, response); |
232 | |
} else { |
233 | 2 | return super.getSessionKey(context); |
234 | |
|
235 | |
} |
236 | |
} |
237 | |
|
238 | |
@Override |
239 | |
protected void beforeLogout(Subject subject) { |
240 | 0 | super.beforeLogout(subject); |
241 | 0 | removeRequestIdentity(subject); |
242 | 0 | } |
243 | |
|
244 | |
protected void removeRequestIdentity(Subject subject) { |
245 | 0 | if (subject instanceof WebSubject) { |
246 | 0 | WebSubject webSubject = (WebSubject) subject; |
247 | 0 | ServletRequest request = webSubject.getServletRequest(); |
248 | 0 | if (request != null) { |
249 | 0 | request.setAttribute(ShiroHttpServletRequest.IDENTITY_REMOVED_KEY, Boolean.TRUE); |
250 | |
} |
251 | |
} |
252 | 0 | } |
253 | |
} |