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.vote;
    17
    18  import org.acegisecurity.AccessDeniedException;
    19  import org.acegisecurity.Authentication;
    20  import org.acegisecurity.ConfigAttributeDefinition;
    21
    22  import org.apache.commons.logging.Log;
    23  import org.apache.commons.logging.LogFactory;
    24
    25  import java.util.Iterator;
    26
    27
    28  /***
    29   * Simple concrete implementation of  {@link
    30   * org.acegisecurity.AccessDecisionManager} that uses a  consensus-based
    31   * approach.
    32   */
    33  public class ConsensusBased extends AbstractAccessDecisionManager {
    34      //~ Static fields/initializers =============================================
    35
    36      private static final Log logger = LogFactory.getLog(ConsensusBased.class);
    37
    38      //~ Instance fields ========================================================
    39
    40      private boolean allowIfEqualGrantedDeniedDecisions = true;
    41
    42      //~ Methods ================================================================
    43
    44      /***
    45       * This concrete implementation simply polls all configured  {@link
    46       * AccessDecisionVoter}s and upon completion determines the consensus of
    47       * granted vs denied responses.
    48       *
    49       * <p>
    50       * If there were an equal number of grant and deny votes, the decision will
    51       * be based on the {@link #isAllowIfEqualGrantedDeniedDecisions()}
    52       * property (defaults to true).
    53       * </p>
    54       *
    55       * <p>
    56       * If every <code>AccessDecisionVoter</code> abstained from voting, the
    57       * decision will be based on the {@link #isAllowIfAllAbstainDecisions()}
    58       * property (defaults to false).
    59       * </p>
    60       *
    61       * @param authentication the caller invoking the method
    62       * @param object the secured object
    63       * @param config the configuration attributes associated with the method
    64       *        being invoked
    65       *
    66       * @throws AccessDeniedException if access is denied
    67       */
    68      public void decide(Authentication authentication, Object object,
    69          ConfigAttributeDefinition config) throws AccessDeniedException {
    70          Iterator iter = this.getDecisionVoters().iterator();
    71          int grant = 0;
    72          int deny = 0;
    73          int abstain = 0;
    74
    75          while (iter.hasNext()) {
    76              AccessDecisionVoter voter = (AccessDecisionVoter) iter.next();
    77              int result = voter.vote(authentication, object, config);
    78
    79              switch (result) {
    80              case AccessDecisionVoter.ACCESS_GRANTED:
    81                  grant++;
    82
    83                  break;
    84
    85              case AccessDecisionVoter.ACCESS_DENIED:
    86                  deny++;
    87
    88                  break;
    89
    90              default:
    91                  abstain++;
    92
    93                  break;
    94              }
    95          }
    96
    97          if (grant > deny) {
    98              return;
    99          }
    100
    101         if (deny > grant) {
    102             throw new AccessDeniedException(messages.getMessage(
    103                     "AbstractAccessDecisionManager.accessDenied",
    104                     "Access is denied"));
    105         }
    106
    107         if ((grant == deny) && (grant != 0)) {
    108             if (this.allowIfEqualGrantedDeniedDecisions) {
    109                 return;
    110             } else {
    111                 throw new AccessDeniedException(messages.getMessage(
    112                         "AbstractAccessDecisionManager.accessDenied",
    113                         "Access is denied"));
    114             }
    115         }
    116
    117         // To get this far, every AccessDecisionVoter abstained
    118         if (this.isAllowIfAllAbstainDecisions()) {
    119             return;
    120         } else {
    121             throw new AccessDeniedException(messages.getMessage(
    122                     "AbstractAccessDecisionManager.accessDenied",
    123                     "Access is denied"));
    124         }
    125     }
    126
    127     public boolean isAllowIfEqualGrantedDeniedDecisions() {
    128         return allowIfEqualGrantedDeniedDecisions;
    129     }
    130
    131     public void setAllowIfEqualGrantedDeniedDecisions(
    132         boolean allowIfEqualGrantedDeniedDecisions) {
    133         this.allowIfEqualGrantedDeniedDecisions = allowIfEqualGrantedDeniedDecisions;
    134     }
    135 }