View Javadoc

    1   /* Copyright 2004, 2005 Acegi Technology Pty Limited
    2    *
    3    * Licensed under the Apache License, Version 2.0 (the "License");
    4    * you may not use this file except in compliance with the License.
    5    * You may obtain a copy of the License at
    6    *
    7    *     http://www.apache.org/licenses/LICENSE-2.0
    8    *
    9    * Unless required by applicable law or agreed to in writing, software
    10   * distributed under the License is distributed on an "AS IS" BASIS,
    11   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12   * See the License for the specific language governing permissions and
    13   * limitations under the License.
    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      //~ Instance fields ========================================================
    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      //~ Methods ================================================================
    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 }