三种投票策略



Spring Security 的 AccessDecisionManager 通过 AccessDecisionVoter 的投票来决定是否允许访问。有三种投票策略:
AffirmativeBased(默认)
只要有一个Voter 投票允许,就通过。
1 2 3 4
| Voter 1: DENY Voter 2: AFFIRMATIVE Voter 3: ABSTAIN 结果:允许访问
|
适合大多数场景,只要有一个来源授权就放行。
ConsensusBased
大多数 Voter 投票允许,才通过。如果平票,根据 allowIfEqualGrantedDeniedDecisions 决定。
1 2 3 4
| Voter 1: DENY Voter 2: AFFIRMATIVE Voter 3: ABSTAIN 结果:取决于 allowIfEqualGrantedDeniedDecisions
|
适合需要共识的场景,比如需要多个部门审批的操作。
UnanimousBased
所有 Voter 都必须投票允许,才通过。任何一个 Voter 投 DENY 就拒绝。
1 2 3 4
| Voter 1: AFFIRMATIVE Voter 2: AFFIRMATIVE Voter 3: DENY 结果:拒绝访问
|
适合最严格的场景,任何一票否决都生效。
自定义 AccessDecisionManager
1 2 3 4 5 6 7 8 9
| @Bean public AccessDecisionManager accessDecisionManager() { List<AccessDecisionVoter<? extends Object>> decisionVoters = Arrays.asList( new WebExpressionVoter(), new RoleVoter(), new AuthenticatedVoter() ); return new AffirmativeBased(decisionVoters); }
|
自定义 Voter
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| @Component public class CustomAccessDecisionVoter implements AccessDecisionVoter<Object> {
@Override public boolean supports(ConfigAttribute attribute) { return "CUSTOM_PERMISSION".equals(attribute.getAttribute()); }
@Override public boolean supports(Class<?> clazz) { return true; }
@Override public int vote(Authentication authentication, Object object, Collection<ConfigAttribute> attributes) { if (hasCustomPermission(authentication)) { return ACCESS_GRANTED; } return ACCESS_DENIED; } }
|
选择策略的建议
| 场景 |
推荐策略 |
| 普通 Web 应用 |
AffirmativeBased(默认) |
| 需要多因素授权 |
ConsensusBased |
| 高安全要求(金融、政府) |
UnanimousBased |
| 混合场景 |
自定义 AccessDecisionManager |