Spring Boot 2.0 M4 中的安全变更

工程 | Madhura Bhave | 2017 年 9 月 15 日 | ...

Spring Boot 2.0 的 Milestone 4 为 Spring Boot 提供的安全自动配置带来了重要更改。

问题陈述

在 Spring Boot 1.x 中,默认自动配置使用基本身份验证保护了所有应用程序端点。如果类路径中存在 actuator,则会有一个单独的安全配置应用于 actuator 端点。这两种自动配置的开启和关闭方式是完全独立的。因此,想要提供自定义安全的用户发现自己与 WebSecurityConfigurerAdapters 的顺序问题作斗争。

此外,对于 actuator 端点,management.security.enabled 标志在 Spring Security 是否在类路径上的影响非常令人困惑。

security.*management.security.* 下存在许多仅适用于 Spring Boot 提供的自动配置的属性。例如,如果 security.basic.enabled 设置为 false,则设置 security.sessions 将完全无效,这被证明是具有误导性的。

2.0 中的改进

在 Spring Boot 2.0 中,我们的主要目标是大大简化默认安全配置,并使添加自定义安全变得容易。

简化的默认配置

提供安全的默认设置具有挑战性。我们决定选择最安全的默认设置,即保护所有内容,包括公共和静态资源。默认情况下,如果 Spring Security 在类路径中,Spring Boot 将添加 @EnableWebSecurity,并依赖 Spring Security 的内容协商来决定使用哪种身份验证机制。将提供一个带有生成密码的默认用户。

如果类路径中有 actuator,相同的默认安全配置也将应用于 actuator 端点。为了防止 actuator 意外暴露敏感数据,默认情况下大多数 Web 端点将被禁用(但 statusinfo 默认启用)。用户需要采取明确的步骤来启用这些 Web 端点。无论 Spring Security 是否在类路径中,此行为都是一致的。

一致的自定义

一旦用户决定添加自定义安全,Spring Boot 提供的默认安全配置将完全退出。此时,用户需要明确定义他们想要保护的所有部分。这意味着安全配置现在位于一个地方,并避免了与现有 WebSecurityConfigurerAdapters 的任何排序问题。我们提供专门的助手来使您的配置更具可读性和明确性。对于管理端点和静态资源,Spring Boot 提供便利工厂,用于提供正确的 RequestMatcher。对于管理端点,RequestMatcher 将根据 management.context-path 创建。使用 RequestMatchers 使开发人员可以使用现有的 Spring Security 表达式(如 permitAllhasRole 等)灵活地保护应用程序。

以下是自定义安全的一个示例

http
    .authorizeRequests()
        // 1
        .requestMatchers(EndpointRequest.to("status", "info"))
            .permitAll()
        // 2
        .requestMatchers(EndpointRequest.toAnyEndpoint())
            .hasRole("ACTUATOR")
        // 3 
        .requestMatchers(StaticResourceRequest.toCommonLocations())
            .permitAll()
        // 4
        .antMatchers("/**")
            .hasRole("USER")
    .and()
  ... // additional configuration

  1. /status/info 端点不需要身份验证。
  2. 所有其他 actuator 端点均受 ACTUATOR 角色保护。
  3. 常见的静态资源位置对所有人开放。
  4. 所有其他应用程序端点均受 USER 角色保护。

我们已将 SecurityProperties 减少到最低限度,以免混淆哪些属性仅被自动配置使用,哪些属性即使在默认安全关闭时也会被使用。如前所述,Spring Boot 提供一个带有生成密码的默认用户。如果要配置自己的用户,可以定义一个类型为 UserDetailsService 的 bean,如下所示

@Bean
public UserDetailsService userDetailsService() throws Exception {
    InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager();
    manager.createUser(User.withUsername("user").password("password")
        .roles("USER").build());
    return manager;
}

您还可以提供自己的 AuthenticationManager bean 或 AuthenticationProvider bean,它们将被使用。

附加改进

状态端点

以前,health 端点会根据是否存在角色来决定返回状态还是公开完整的 health 详细信息。希望始终公开完整的 health 详细信息的开发者需要将 management.security.flag 设置为 false,这不太理想,因为它会暴露其他 actuator。作为 2.0 的一部分,我们添加了一个单独的状态端点,该端点仅返回状态。health 端点始终返回完整的 health 详细信息。这两个端点默认都是安全的,但这使得为这两种情况添加自定义安全规则更加容易。

获取 Spring 新闻通讯

通过 Spring 新闻通讯保持联系

订阅

领先一步

VMware 提供培训和认证,助您加速进步。

了解更多

获得支持

Tanzu Spring 提供 OpenJDK™、Spring 和 Apache Tomcat® 的支持和二进制文件,只需一份简单的订阅。

了解更多

即将举行的活动

查看 Spring 社区所有即将举行的活动。

查看所有