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 的指标信息。