1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.acegisecurity.captcha;
17
18 import org.acegisecurity.securechannel.ChannelEntryPoint;
19
20 import org.acegisecurity.util.PortMapper;
21 import org.acegisecurity.util.PortMapperImpl;
22 import org.acegisecurity.util.PortResolver;
23 import org.acegisecurity.util.PortResolverImpl;
24
25 import org.apache.commons.logging.Log;
26 import org.apache.commons.logging.LogFactory;
27
28 import org.springframework.beans.factory.InitializingBean;
29
30 import org.springframework.util.Assert;
31
32 import java.io.IOException;
33 import java.io.UnsupportedEncodingException;
34
35 import java.net.URLEncoder;
36
37 import java.util.Enumeration;
38
39 import javax.servlet.ServletException;
40 import javax.servlet.ServletRequest;
41 import javax.servlet.ServletResponse;
42 import javax.servlet.http.HttpServletRequest;
43 import javax.servlet.http.HttpServletResponse;
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88 public class CaptchaEntryPoint implements ChannelEntryPoint, InitializingBean {
89
90
91 private static final Log logger = LogFactory.getLog(CaptchaEntryPoint.class);
92
93
94
95
96
97 private PortMapper portMapper = new PortMapperImpl();
98 private PortResolver portResolver = new PortResolverImpl();
99 private String captchaFormUrl;
100 private String originalRequestMethodParameterName = "original_request_method";
101 private String originalRequestParametersNameValueSeparator = "__";
102 private String originalRequestParametersParameterName = "original_request_parameters";
103 private String originalRequestParametersSeparator = ";;";
104 private String originalRequestUrlParameterName = "original_requestUrl";
105 private String urlEncodingCharset = "UTF-8";
106 private boolean forceHttps = false;
107 private boolean includeOriginalParameters = false;
108 private boolean includeOriginalRequest = true;
109 private boolean isOutsideWebApp = false;
110
111
112
113 public void afterPropertiesSet() throws Exception {
114 Assert.hasLength(captchaFormUrl, "captchaFormUrl must be specified");
115 Assert.hasLength(originalRequestMethodParameterName, "originalRequestMethodParameterName must be specified");
116 Assert.hasLength(originalRequestParametersNameValueSeparator,
117 "originalRequestParametersNameValueSeparator must be specified");
118 Assert.hasLength(originalRequestParametersParameterName,
119 "originalRequestParametersParameterName must be specified");
120 Assert.hasLength(originalRequestParametersSeparator, "originalRequestParametersSeparator must be specified");
121 Assert.hasLength(originalRequestUrlParameterName, "originalRequestUrlParameterName must be specified");
122 Assert.hasLength(urlEncodingCharset, "urlEncodingCharset must be specified");
123 Assert.notNull(portMapper, "portMapper must be specified");
124 Assert.notNull(portResolver, "portResolver must be specified");
125 URLEncoder.encode(" fzaef é& à ", urlEncodingCharset);
126 }
127
128 private void buildInternalRedirect(StringBuffer redirectUrl, HttpServletRequest req) {
129
130 StringBuffer simpleRedirect = new StringBuffer();
131
132 String scheme = req.getScheme();
133 String serverName = req.getServerName();
134 int serverPort = portResolver.getServerPort(req);
135 String contextPath = req.getContextPath();
136 boolean includePort = true;
137
138 if ("http".equals(scheme.toLowerCase()) && (serverPort == 80)) {
139 includePort = false;
140 }
141
142 if ("https".equals(scheme.toLowerCase()) && (serverPort == 443)) {
143 includePort = false;
144 }
145
146 simpleRedirect.append(scheme);
147 simpleRedirect.append("://");
148 simpleRedirect.append(serverName);
149
150 if (includePort) {
151 simpleRedirect.append(":");
152 simpleRedirect.append(serverPort);
153 }
154
155 simpleRedirect.append(contextPath);
156 simpleRedirect.append(captchaFormUrl);
157
158 if (forceHttps && req.getScheme().equals("http")) {
159 Integer httpPort = new Integer(portResolver.getServerPort(req));
160 Integer httpsPort = (Integer) portMapper.lookupHttpsPort(httpPort);
161
162 if (httpsPort != null) {
163 if (httpsPort.intValue() == 443) {
164 includePort = false;
165 } else {
166 includePort = true;
167 }
168
169 redirectUrl.append("https://");
170 redirectUrl.append(serverName);
171
172 if (includePort) {
173 redirectUrl.append(":");
174 redirectUrl.append(httpsPort);
175 }
176
177 redirectUrl.append(contextPath);
178 redirectUrl.append(captchaFormUrl);
179 } else {
180 redirectUrl.append(simpleRedirect);
181 }
182 } else {
183 redirectUrl.append(simpleRedirect);
184 }
185 }
186
187 public void commence(ServletRequest request, ServletResponse response)
188 throws IOException, ServletException {
189 StringBuffer redirectUrl = new StringBuffer();
190 HttpServletRequest req = (HttpServletRequest) request;
191
192 if (isOutsideWebApp) {
193 redirectUrl = redirectUrl.append(captchaFormUrl);
194 } else {
195 buildInternalRedirect(redirectUrl, req);
196 }
197
198 if (includeOriginalRequest) {
199 includeOriginalRequest(redirectUrl, req);
200 }
201
202
203 if (logger.isDebugEnabled()) {
204 logger.debug("Redirecting to: " + redirectUrl);
205 }
206
207 ((HttpServletResponse) response).sendRedirect(redirectUrl.toString());
208 }
209
210
211
212
213
214
215 public String getCaptchaFormUrl() {
216 return captchaFormUrl;
217 }
218
219 public boolean getForceHttps() {
220 return forceHttps;
221 }
222
223 public String getOriginalRequestMethodParameterName() {
224 return originalRequestMethodParameterName;
225 }
226
227 public String getOriginalRequestParametersNameValueSeparator() {
228 return originalRequestParametersNameValueSeparator;
229 }
230
231 public String getOriginalRequestParametersParameterName() {
232 return originalRequestParametersParameterName;
233 }
234
235 public String getOriginalRequestParametersSeparator() {
236 return originalRequestParametersSeparator;
237 }
238
239 public String getOriginalRequestUrlParameterName() {
240 return originalRequestUrlParameterName;
241 }
242
243 public PortMapper getPortMapper() {
244 return portMapper;
245 }
246
247 public PortResolver getPortResolver() {
248 return portResolver;
249 }
250
251 public String getUrlEncodingCharset() {
252 return urlEncodingCharset;
253 }
254
255 private void includeOriginalRequest(StringBuffer redirectUrl, HttpServletRequest req) {
256
257 if (redirectUrl.indexOf("?") >= 0) {
258 redirectUrl.append("&");
259 } else {
260 redirectUrl.append("?");
261 }
262
263 redirectUrl.append(originalRequestUrlParameterName);
264 redirectUrl.append("=");
265
266 try {
267 redirectUrl.append(URLEncoder.encode(req.getRequestURL().toString(), urlEncodingCharset));
268 } catch (UnsupportedEncodingException e) {
269 logger.warn(e);
270 }
271
272
273 redirectUrl.append("&");
274 redirectUrl.append(originalRequestMethodParameterName);
275 redirectUrl.append("=");
276 redirectUrl.append(req.getMethod());
277
278 if (includeOriginalParameters) {
279
280 redirectUrl.append("&");
281 redirectUrl.append(originalRequestParametersParameterName);
282 redirectUrl.append("=");
283
284 StringBuffer qp = new StringBuffer();
285 Enumeration parameters = req.getParameterNames();
286
287 if ((parameters != null) && parameters.hasMoreElements()) {
288
289 while (parameters.hasMoreElements()) {
290 String name = parameters.nextElement().toString();
291 String value = req.getParameter(name);
292 qp.append(name);
293 qp.append(originalRequestParametersNameValueSeparator);
294 qp.append(value);
295
296 if (parameters.hasMoreElements()) {
297 qp.append(originalRequestParametersSeparator);
298 }
299 }
300 }
301
302 try {
303 redirectUrl.append(URLEncoder.encode(qp.toString(), urlEncodingCharset));
304 } catch (Exception e) {
305 logger.warn(e);
306 }
307 }
308 }
309
310 public boolean isIncludeOriginalParameters() {
311 return includeOriginalParameters;
312 }
313
314 public boolean isIncludeOriginalRequest() {
315 return includeOriginalRequest;
316 }
317
318 public boolean isOutsideWebApp() {
319 return isOutsideWebApp;
320 }
321
322
323
324
325
326
327
328 public void setCaptchaFormUrl(String captchaFormUrl) {
329 this.captchaFormUrl = captchaFormUrl;
330 }
331
332
333
334
335
336
337
338
339
340
341 public void setForceHttps(boolean forceHttps) {
342 this.forceHttps = forceHttps;
343 }
344
345 public void setIncludeOriginalParameters(boolean includeOriginalParameters) {
346 this.includeOriginalParameters = includeOriginalParameters;
347 }
348
349
350
351
352
353
354
355 public void setIncludeOriginalRequest(boolean includeOriginalRequest) {
356 this.includeOriginalRequest = includeOriginalRequest;
357 }
358
359 public void setOriginalRequestMethodParameterName(String originalRequestMethodParameterName) {
360 this.originalRequestMethodParameterName = originalRequestMethodParameterName;
361 }
362
363 public void setOriginalRequestParametersNameValueSeparator(String originalRequestParametersNameValueSeparator) {
364 this.originalRequestParametersNameValueSeparator = originalRequestParametersNameValueSeparator;
365 }
366
367 public void setOriginalRequestParametersParameterName(String originalRequestParametersParameterName) {
368 this.originalRequestParametersParameterName = originalRequestParametersParameterName;
369 }
370
371 public void setOriginalRequestParametersSeparator(String originalRequestParametersSeparator) {
372 this.originalRequestParametersSeparator = originalRequestParametersSeparator;
373 }
374
375 public void setOriginalRequestUrlParameterName(String originalRequestUrlParameterName) {
376 this.originalRequestUrlParameterName = originalRequestUrlParameterName;
377 }
378
379
380
381
382
383
384
385 public void setOutsideWebApp(boolean isOutsideWebApp) {
386 this.isOutsideWebApp = isOutsideWebApp;
387 }
388
389 public void setPortMapper(PortMapper portMapper) {
390 this.portMapper = portMapper;
391 }
392
393 public void setPortResolver(PortResolver portResolver) {
394 this.portResolver = portResolver;
395 }
396
397 public void setUrlEncodingCharset(String urlEncodingCharset) {
398 this.urlEncodingCharset = urlEncodingCharset;
399 }
400 }