访问决策管理器会把真正的决策任务委派给访问决策投票器。您也可以自定义认证提供者,只需要实现接口 AccessDecisionVoter,并以 AccessDecisionVoter 接口为 id 注入到 IoC 容器即可。

定义

  1. export interface AccessDecisionVoter {
  2. vote(securityMetadata: SecurityMetadata): Promise<number>;
  3. support(securityMetadata: SecurityMetadata): Promise<boolean>;
  4. readonly priority: number;
  5. }

默认实现

  1. @Component(AccessDecisionVoter)
  2. export class PolicyBasedVoter implements AccessDecisionVoter {
  3. readonly priority = POLICY_BASED_VOTER_PRIORITY;
  4. @Autowired(PolicyResolver)
  5. protected readonly policyResolvers: PolicyResolver[];
  6. @Autowired(ResourcePolicyProvider)
  7. protected readonly resourcePolicyProvider: ResourcePolicyProvider;
  8. @Autowired(PrincipalPolicyProvider)
  9. protected readonly principalPolicyProvider: PrincipalPolicyProvider;
  10. async vote(securityMetadata: SecurityMetadata): Promise<number> {
  11. const principalPolicies = await this.principalPolicyProvider.provide(securityMetadata.principal, securityMetadata.authorizeType);
  12. const resourcePolicies = await this.resourcePolicyProvider.provide(securityMetadata.resource, securityMetadata.authorizeType);
  13. const policies = [ ...principalPolicies, ...resourcePolicies, ...securityMetadata.policies ];
  14. let grant = 0;
  15. for (const policy of policies) {
  16. for (const policyResolver of this.policyResolvers) {
  17. if (await policyResolver.support(policy)) {
  18. if (await policyResolver.resolve(policy, securityMetadata)) {
  19. grant++;
  20. } else {
  21. return ACCESS_DENIED;
  22. }
  23. }
  24. }
  25. }
  26. if (securityMetadata.authorizeType === AuthorizeType.Post || grant > 0) {
  27. return ACCESS_GRANTED;
  28. }
  29. return ACCESS_DENIED;
  30. }
  31. async support(securityMetadata: SecurityMetadata): Promise<boolean> {
  32. return true;
  33. }
  34. }