Spring Boot 2.0 M4 中的安全变更

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

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

问题描述

在 Spring Boot 1.x 之前,默认的自动配置使用基本认证(basic authentication)保护了所有的应用端点。如果类路径中包含 actuator,则会有一个独立的安全配置应用于 actuator 端点。这两种自动配置的开启和关闭方式是完全独立的。因此,想要提供自定义安全配置的用户发现他们不得不处理 WebSecurityConfigurerAdapter 的顺序问题。

此外,对于 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 endpoint)会根据是否存在某个角色来决定是仅返回状态还是暴露完整的健康详情。那些总是想要暴露完整健康详情的用户需要将 management.security.flag 设置为 false,这不太理想,因为它会暴露其他 actuator。作为 2.0 的一部分,我们添加了一个独立的状态端点,它仅返回状态。健康检查端点始终返回完整的健康详情。这两个端点默认都是安全的,但这使得为这两种情况添加自定义安全规则变得容易得多。

订阅 Spring 新闻通讯

订阅 Spring 新闻通讯,保持联系

订阅

领先一步

VMware 提供培训和认证,助力您的飞速进步。

了解更多

获得支持

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

了解更多

即将举行的活动

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

查看全部