> For the complete documentation index, see [llms.txt](https://potoyang.gitbook.io/spring-in-action-v5/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://potoyang.gitbook.io/spring-in-action-v5/di-16-zhang-shi-yong-springboot-actuator/16.4-bao-hu-actuator.md).

# 16.4 保护 Actuator

对于 Actuator 提供的信息，可能您并不想被间谍窥探到。此外，由于 Actuator 提供了可以更改环境属性，以及调整日志记录级别的操作，那么使只允许具有适当访问权限的客户，才能使用 Actuator 是必要的。

尽管确保 Actuator 的安全非常重要，但 Actuator 并没有提供安全措施的责任。相反，您需要使用 Spring Security 来保护 Actuator。因为 Actuator 端点只是应用程序中的路径，这与应用程序中的任何其他路径没什么区别，所以确保 Actuator 的安全措施，与保证应用程序其他路径的安全措施相比，没有什么独特之处。我们在第 4 章中讨论的所有内容都适用 Actuator 端点。

因为所有的 Actuator 端点都集中在路径 `/actuator` 下（或者其他路径，如果设置了 management.endpoints.web.base-path 属性），很容易将授权规则应用于 Actuator 端点。例如，要求用户具有要 ROLE\_ADMIN 权限，以调用 Actuator 端点，您可以重写 WebSecurityConfigurerAdapter 的 `configure()` 方法，如下所示：

```java
@Override
protected void configure(HttpSecurity http) throws Exception {
  http
    .authorizeRequests()
    .antMatchers("/actuator/**").hasRole("ADMIN")
    .and()
    .httpBasic();
}
```

这要求，所有请求都要来自具有 ROLE\_ADMIN 权限的用户。另外还配置了 HTTP 基本身份验证，以便客户端应用程序，可以在请求头 Authorization 属性中，传输编码过的身份验证信息。

以这种方式保护 Actuator 的真正问题是，端点的路径硬编码为 `/actuator/**` 了。如果修改了 management.endpoints.web.base-path 属性，它将不再工作。为解决这个问题，Spring Boot 还提供了 EndpointRequest，这是一个请求匹配器类。它更容易使用，而且不依赖于给定的字符串路径。使用 EndpointRequest，您可以对 Actuator 端点应用相同的安全配置，而无需硬编码 `/actuator/**` 路径：

```java
@Override
protected void configure(HttpSecurity http) throws Exception {
  http
    .requestMatcher(EndpointRequest.toAnyEndpoint())
      .authorizeRequests()
        .anyRequest().hasRole("ADMIN")
    .and()
    .httpBasic();
}
```

`EndpointRequest.toAnyEndpoint()` 方法返回一个请求匹配器，该匹配器匹配任何 Actuator 端点。如果要从中排除某些端点，可以调用 `excluding()`，并按名称指定它们：

```java
@Override
protected void configure(HttpSecurity http) throws Exception {
  http
    .requestMatcher(EndpointRequest.toAnyEndpoint().excluding("health", "info"))
    .authorizeRequests()
      .anyRequest().hasRole("ADMIN")
    .and()
    .httpBasic();
}
```

另一方面，您如果希望对少数 Actuator 进行保护，您可以通过调用 `to()` 方法，而不是 `toAnyEndpoint()` 方法：

```java
@Override
protected void configure(HttpSecurity http) throws Exception {
  http
    .requestMatcher(EndpointRequest.to("beans", "threaddump", "loggers"))
    .authorizeRequests()
    .anyRequest().hasRole("ADMIN")
    .and()
    .httpBasic();
}
```

这将 Actuator 的安全性仅限于 `/bean`、`/threaddump` 和 `/loggers` 端点。所有其他 Actuator 端点完全开放。
