1
2
3
4
5
6
7
8
9
10
11
12
13
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
35
36 private static final Log logger = LogFactory.getLog(ConsensusBased.class);
37
38
39
40 private boolean allowIfEqualGrantedDeniedDecisions = true;
41
42
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
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 }