访问决策管理器会把真正的决策任务委派给访问决策投票器。您也可以自定义认证提供者,只需要实现接口 AccessDecisionVoter,并以 AccessDecisionVoter 接口为 id 注入到 IoC 容器即可。
定义
export interface AccessDecisionVoter {
vote(securityMetadata: SecurityMetadata): Promise<number>;
support(securityMetadata: SecurityMetadata): Promise<boolean>;
readonly priority: number;
}
默认实现
@Component(AccessDecisionVoter)
export class PolicyBasedVoter implements AccessDecisionVoter {
readonly priority = POLICY_BASED_VOTER_PRIORITY;
@Autowired(PolicyResolver)
protected readonly policyResolvers: PolicyResolver[];
@Autowired(ResourcePolicyProvider)
protected readonly resourcePolicyProvider: ResourcePolicyProvider;
@Autowired(PrincipalPolicyProvider)
protected readonly principalPolicyProvider: PrincipalPolicyProvider;
async vote(securityMetadata: SecurityMetadata): Promise<number> {
const principalPolicies = await this.principalPolicyProvider.provide(securityMetadata.principal, securityMetadata.authorizeType);
const resourcePolicies = await this.resourcePolicyProvider.provide(securityMetadata.resource, securityMetadata.authorizeType);
const policies = [ ...principalPolicies, ...resourcePolicies, ...securityMetadata.policies ];
let grant = 0;
for (const policy of policies) {
for (const policyResolver of this.policyResolvers) {
if (await policyResolver.support(policy)) {
if (await policyResolver.resolve(policy, securityMetadata)) {
grant++;
} else {
return ACCESS_DENIED;
}
}
}
}
if (securityMetadata.authorizeType === AuthorizeType.Post || grant > 0) {
return ACCESS_GRANTED;
}
return ACCESS_DENIED;
}
async support(securityMetadata: SecurityMetadata): Promise<boolean> {
return true;
}
}