DeferringObservationAuthorizationManager 类用于在授权决策过程中收集观测数据(observability data),特别是针对需要延迟执行的授权决策。它主要作为一个装饰器(Decorator),包装其他 AuthorizationManager 实例,并在授权决策完成后记录观察指标(如执行时间、成功 / 失败状态)。
延迟观察,在授权决策执行后,捕获并记录决策结果和性能指标。
指标收集,集成 Micrometer 观测系统,自动收集授权决策的执行时间、成功率等指标。
非侵入式增强,不改变原有授权逻辑,仅在决策完成后进行观察记录。
需要监控授权决策性能的场景。
分析不同权限规则的执行效率。
记录授权失败的频率和原因。
下面是 DeferringObservationAuthorizationManager 类的部分源码:
package org.springframework.security.config.annotation.method.configuration;
import java.util.function.Supplier;
import io.micrometer.observation.ObservationRegistry;
import org.aopalliance.intercept.MethodInvocation;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.security.authorization.AuthorizationDecision;
import org.springframework.security.authorization.AuthorizationManager;
import org.springframework.security.authorization.AuthorizationResult;
import org.springframework.security.authorization.ObservationAuthorizationManager;
import org.springframework.security.authorization.method.MethodAuthorizationDeniedHandler;
import org.springframework.security.authorization.method.MethodInvocationResult;
import org.springframework.security.authorization.method.ThrowingMethodAuthorizationDeniedHandler;
import org.springframework.security.core.Authentication;
import org.springframework.util.function.SingletonSupplier;
/**
* 延迟观察授权管理器 - 用于在授权决策后进行指标收集和观察
* 该类包装另一个 AuthorizationManager,在其决策完成后记录观察指标
* 支持与 Micrometer 集成,实现授权决策的性能监控
*/
final class DeferringObservationAuthorizationManager<T>
implements AuthorizationManager<T>, MethodAuthorizationDeniedHandler {
// 被装饰的授权管理器提供者(延迟初始化)
private final Supplier<AuthorizationManager<T>> delegate;
// 方法授权拒绝处理器
private MethodAuthorizationDeniedHandler handler = new ThrowingMethodAuthorizationDeniedHandler();
/**
* 构造函数
* @param provider ObservationRegistry 对象提供者
* @param delegate 被装饰的授权管理器
*/
DeferringObservationAuthorizationManager(ObjectProvider<ObservationRegistry> provider,
AuthorizationManager<T> delegate) {
// 使用单例提供者延迟初始化授权管理器
this.delegate = SingletonSupplier.of(() -> {
// 获取 ObservationRegistry 实例,如果不可用则使用 NOOP 实现
ObservationRegistry registry = provider.getIfAvailable(() -> ObservationRegistry.NOOP);
// 如果注册表为 NOOP(无操作),则直接使用原始授权管理器
if (registry.isNoop()) {
return delegate;
}
// 否则使用 ObservationAuthorizationManager 包装原始管理器以添加观察功能
return new ObservationAuthorizationManager<>(registry, delegate);
});
if (delegate instanceof MethodAuthorizationDeniedHandler h) {
this.handler = h;
}
}
/**
* 检查授权决策
* @param authentication 认证信息提供者
* @param object 待授权的对象
* @return 授权决策结果
*/
@Override
public AuthorizationDecision check(Supplier<Authentication> authentication, T object) {
// 委托给实际的授权管理器进行决策
return this.delegate.get().check(authentication, object);
}
/**
* 处理方法调用被拒绝的情况
* @param methodInvocation 方法调用对象
* @param authorizationResult 授权结果
* @return 处理结果对象
*/
@Override
public Object handleDeniedInvocation(MethodInvocation methodInvocation, AuthorizationResult authorizationResult) {
// 委托给拒绝处理器处理
return this.handler.handleDeniedInvocation(methodInvocation, authorizationResult);
}
/**
* 处理带返回值的方法调用被拒绝的情况
* @param methodInvocationResult 方法调用结果对象
* @param authorizationResult 授权结果
* @return 处理结果对象
*/
@Override
public Object handleDeniedInvocationResult(MethodInvocationResult methodInvocationResult,
AuthorizationResult authorizationResult) {
// 委托给拒绝处理器处理
return this.handler.handleDeniedInvocationResult(methodInvocationResult, authorizationResult);
}
}DeferringObservationAuthorizationManager 类通过非侵入式方式为授权决策添加监控能力。它适用于需要深入了解权限控制行为的生产环境,帮助开发者优化授权策略和排查问题。
虽然不能直接访问 DeferringObservationAuthorizationManager,但 Spring Security 提供了自动配置机制和工厂方法来启用观察功能。详细步骤如下:
在 Spring Boot 应用中,只需添加 Micrometer 依赖并启用观察功能:
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-core</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>配置文件添加如下配置,启用安全指标:
management.metrics.enable.security= true此时,Spring Security 会自动包装所有授权管理器,添加观察功能。
通过 Actuator 端点查看指标,添加如下接口,如下:
package com.hxstrive.spring_security.controller;
import io.micrometer.core.instrument.Meter;
import io.micrometer.core.instrument.MeterRegistry;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PostAuthorize;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.Collection;
import java.util.stream.Collectors;
/**
* 简单控制器
* @author hxstrive.com
*/
@RestController
public class HelloController {
@Autowired
private MeterRegistry meterRegistry;
// 通过 Actuator 端点查看指标
@GetMapping("/metrics")
public Collection<Meter> getMetrics() {
return meterRegistry.getMeters()
.stream()
.filter(m -> m.getId().getName().startsWith("spring.security"))
.collect(Collectors.toList());
}
}重启服务器,访问 /metrics 接口,浏览器返回信息如下图:

从上图中可以看出,输出了很多关于 spring.security 的指标信息。