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.ConfigAttribute;
19 import org.acegisecurity.ConfigAttributeDefinition;
20 import org.acegisecurity.context.SecurityContextHolder;
21 import org.acegisecurity.intercept.web.FilterInvocation;
22 import org.acegisecurity.securechannel.ChannelEntryPoint;
23 import org.acegisecurity.securechannel.ChannelProcessor;
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
34 import java.util.Iterator;
35
36 import javax.servlet.ServletException;
37
38
39 /***
40 * <p>
41 * CaptchaChannel template : Ensures the user has enough human privileges by
42 * review of the {@link CaptchaSecurityContext} and using an abstract routine
43 * {@link #isContextValidConcerningHumanity(CaptchaSecurityContext)}
44 * (implemented by sub classes)
45 * </p>
46 *
47 * <P>
48 * The component uses 2 main parameters for its configuration :
49 *
50 * <ul>
51 * <li>
52 * a keyword to be mapped to urls in the {@link
53 * org.acegisecurity.securechannel.ChannelProcessingFilter} configuration<br>
54 * default value provided by sub classes.
55 * </li>
56 * <li>
57 * and a thresold : used by the routine {@link
58 * #isContextValidConcerningHumanity(CaptchaSecurityContext)} to evaluate
59 * whether the {@link CaptchaSecurityContext} is valid default value = 0
60 * </li>
61 * </ul>
62 * </p>
63 *
64 * @author marc antoine Garrigue
65 * @version $Id: CaptchaChannelProcessorTemplate.java,v 1.2 2005/11/17 00:55:49 benalex Exp $
66 */
67 public abstract class CaptchaChannelProcessorTemplate
68 implements ChannelProcessor, InitializingBean {
69
70
71 protected Log logger = LogFactory.getLog(this.getClass());
72 private ChannelEntryPoint entryPoint;
73 private String keyword = null;
74 private int thresold = 0;
75
76
77
78 public void setEntryPoint(ChannelEntryPoint entryPoint) {
79 this.entryPoint = entryPoint;
80 }
81
82 public ChannelEntryPoint getEntryPoint() {
83 return entryPoint;
84 }
85
86 public void setKeyword(String keyword) {
87 this.keyword = keyword;
88 }
89
90 public String getKeyword() {
91 return keyword;
92 }
93
94 public void setThresold(int thresold) {
95 this.thresold = thresold;
96 }
97
98 public int getThresold() {
99 return thresold;
100 }
101
102 /***
103 * Verify if entryPoint and keyword are ok
104 *
105 * @throws Exception if not
106 */
107 public void afterPropertiesSet() throws Exception {
108 Assert.notNull(entryPoint, "entryPoint required");
109 Assert.hasLength(keyword, "keyword required");
110 }
111
112 public void decide(FilterInvocation invocation,
113 ConfigAttributeDefinition config) throws IOException, ServletException {
114 if ((invocation == null) || (config == null)) {
115 throw new IllegalArgumentException("Nulls cannot be provided");
116 }
117
118 CaptchaSecurityContext context = null;
119 context = (CaptchaSecurityContext) SecurityContextHolder.getContext();
120
121 Iterator iter = config.getConfigAttributes();
122
123 while (iter.hasNext()) {
124 ConfigAttribute attribute = (ConfigAttribute) iter.next();
125
126 if (supports(attribute)) {
127 logger.debug("supports this attribute : " + attribute);
128
129 if (!isContextValidConcerningHumanity(context)) {
130 logger.debug(
131 "context is not allowed to access ressource, redirect to captcha entry point");
132 redirectToEntryPoint(invocation);
133 } else {
134 logger.debug(
135 "has been successfully checked this keyword, increment request count");
136 context.incrementHumanRestrictedRessoucesRequestsCount();
137 }
138 } else {
139 logger.debug("do not support this attribute");
140 }
141 }
142 }
143
144 public boolean supports(ConfigAttribute attribute) {
145 if ((attribute != null) && (keyword.equals(attribute.getAttribute()))) {
146 return true;
147 } else {
148 return false;
149 }
150 }
151
152 abstract boolean isContextValidConcerningHumanity(
153 CaptchaSecurityContext context);
154
155 private void redirectToEntryPoint(FilterInvocation invocation)
156 throws IOException, ServletException {
157 if (logger.isDebugEnabled()) {
158 logger.debug("context is not valid : redirecting to entry point");
159 }
160
161 entryPoint.commence(invocation.getRequest(), invocation.getResponse());
162 }
163 }