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 }