Spring Boot Security Auto-Configuration – Spring Boot安全自动配置

最后修改: 2018年 2月 23日

中文/混合/英文(键盘快捷键:t)

1. Overview

1.概述

In this tutorial, we’ll have a look at Spring Boot’s opinionated approach to security.

在本教程中,我们将看一下Spring Boot对安全的意见方法。

Simply put, we’re going to focus on the default security configuration and how we can disable or customize it if we need to.

简单地说,我们将专注于默认的安全配置,以及我们如何在需要时禁用或定制它。

2. Default Security Setup

2.默认的安全设置

In order to add security to our Spring Boot application, we need to add the security starter dependency:

为了给我们的Spring Boot应用程序添加安全性,我们需要添加security starter dependency

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-security</artifactId>
</dependency>

This will also include the SecurityAutoConfiguration class containing the initial/default security configuration.

这也将包括包含初始/默认安全配置的SecurityAutoConfiguration 类。

Notice how we didn’t specify the version here, with the assumption that the project is already using Boot as the parent.

注意我们在这里没有指定版本,假设该项目已经使用Boot作为父代。

By default, the Authentication gets enabled for the Application. Also, content negotiation is used to determine if basic or formLogin should be used.

默认情况下,应用程序的验证功能被启用。此外,内容协商被用来确定是否应该使用基本认证或formLogin。

There are some predefined properties:

有一些预定义的属性。

spring.security.user.name
spring.security.user.password

If we don’t configure the password using the predefined property spring.security.user.password and start the application, a default password is randomly generated and printed in the console log:

如果我们不使用预定义的属性spring.security.user.password来配置密码并启动应用程序,一个默认的密码会随机生成并打印在控制台日志中。

Using default security password: c8be15de-4488-4490-9dc6-fab3f91435c6

For more defaults, see the security properties section of the Spring Boot Common Application Properties reference page.

有关更多的默认值,请参阅Spring Boot通用应用程序属性参考页中的安全属性部分。

3. Disabling the Auto-Configuration

3.禁用自动配置功能

To discard the security auto-configuration and add our own configuration, we need to exclude the SecurityAutoConfiguration class.

为了放弃安全自动配置并添加我们自己的配置,我们需要排除SecurityAutoConfiguration类。

We can do this via a simple exclusion:

我们可以通过一个简单的排除法做到这一点。

@SpringBootApplication(exclude = { SecurityAutoConfiguration.class })
public class SpringBootSecurityApplication {

    public static void main(String[] args) {
        SpringApplication.run(SpringBootSecurityApplication.class, args);
    }
}

Or we can add some configuration into the application.properties file:

或者我们可以在application.properties文件中添加一些配置。

spring.autoconfigure.exclude=org.springframework.boot.autoconfigure.security.SecurityAutoConfiguration

However, there are also some particular cases in which this setup isn’t quite enough.

然而,也有一些特殊情况,这种设置并不十分充分。

For example, almost each Spring Boot application is started with Actuator in the classpath. This causes problems because another auto-configuration class needs the one we’ve just excluded. So, the application will fail to start.

例如,几乎每个Spring Boot应用程序在启动时都在classpath中加入了Actuator。这就造成了问题,因为另一个自动配置类需要我们刚刚排除的那个。因此,应用程序将无法启动。

In order to fix this issue, we need to exclude that class; and, specific to the Actuator situation, we also need to exclude ManagementWebSecurityAutoConfiguration.

为了解决这个问题,我们需要排除该类;而且,针对执行器的情况,我们还需要排除ManagementWebSecurityAutoConfiguration

3.1. Disabling vs Surpassing Security Auto-Configuration

3.1.禁用与超越安全自动配置

There’s a significant difference between disabling auto-configuration and surpassing it.

禁用自动配置和超越自动配置之间有很大区别。

Disabling it is just like adding the Spring Security dependency and the whole setup from scratch. This can be useful in several cases:

禁用它就像添加Spring Security依赖,整个设置从头开始。这在一些情况下是很有用的。

  1. Integrating application security with a custom security provider
  2. Migrating a legacy Spring application with already-existing security setup — to Spring Boot

But most of the time we won’t need to fully disable the security auto-configuration.

但在大多数情况下,我们并不需要完全禁用安全自动配置。

That’s because Spring Boot is configured to permit surpassing the auto-configured security by adding in our new/custom configuration classes. This is typically easier since we’re just customizing an existing security setup to fulfill our needs.

这是因为Spring Boot的配置允许我们通过添加新的/自定义配置类来超越自动配置的安全性。这通常比较容易,因为我们只是定制了一个现有的安全设置来满足我们的需求。

4. Configuring Spring Boot Security

4.配置Spring Boot安全

If we’ve chosen the path of disabling security auto-configuration, we naturally need to provide our own configuration.

如果我们选择了禁用安全自动配置的路径,我们自然需要提供我们自己的配置。

As we’ve discussed before, this is the default security configuration. We then customize it by modifying the property file.

正如我们之前讨论的,这是默认的安全配置。然后我们通过修改属性文件对其进行自定义。

For example, we can override the default password by adding our own:

例如,我们可以通过添加我们自己的密码来覆盖默认的密码。

spring.security.user.password=password

If we want a more flexible configuration, with multiple users and roles for example, we need to make use of a full @Configuration class:

如果我们想要一个更灵活的配置,比如说有多个用户和角色,我们需要利用一个完整的@Configuration类。

@Configuration
@EnableWebSecurity
public class BasicConfiguration {

    @Bean
    public InMemoryUserDetailsManager userDetailsService(PasswordEncoder passwordEncoder) {
        UserDetails user = User.withUsername("user")
            .password(passwordEncoder.encode("password"))
            .roles("USER")
            .build();

        UserDetails admin = User.withUsername("admin")
            .password(passwordEncoder.encode("admin"))
            .roles("USER", "ADMIN")
            .build();

        return new InMemoryUserDetailsManager(user, admin);
    }

    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http.authorizeRequests()
            .anyRequest()
            .authenticated()
            .and()
            .httpBasic();
        return http.build();
    }

    @Bean
    public PasswordEncoder passwordEncoder() {
        PasswordEncoder encoder = PasswordEncoderFactories.createDelegatingPasswordEncoder();
        return encoder;
    }
}

The @EnableWebSecurity annotation is crucial if we disable the default security configuration.

如果我们禁用默认的安全配置,@EnableWebSecurity注解是至关重要的。

The application will fail to start if it’s missing.

如果缺少它,应用程序将无法启动。

Also, notice that we need to use the PasswordEncoder to set the passwords when using Spring Boot 2. For more details, see our guide on the Default Password Encoder in Spring Security 5.

此外,请注意,在使用Spring Boot 2时,我们需要使用PasswordEncoder来设置密码。有关详细信息,请参阅我们关于Spring Security 5的Default Password Encoder的指南。

Now we should verify that our security configuration applies correctly with a couple of quick live tests:

现在我们应该通过几个快速的现场测试来验证我们的安全配置是否正确适用。

@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = RANDOM_PORT)
public class BasicConfigurationIntegrationTest {

    TestRestTemplate restTemplate;
    URL base;
    @LocalServerPort int port;

    @Before
    public void setUp() throws MalformedURLException {
        restTemplate = new TestRestTemplate("user", "password");
        base = new URL("http://localhost:" + port);
    }

    @Test
    public void whenLoggedUserRequestsHomePage_ThenSuccess()
     throws IllegalStateException, IOException {
        ResponseEntity<String> response =
          restTemplate.getForEntity(base.toString(), String.class);
 
        assertEquals(HttpStatus.OK, response.getStatusCode());
        assertTrue(response.getBody().contains("Baeldung"));
    }

    @Test
    public void whenUserWithWrongCredentials_thenUnauthorizedPage() 
      throws Exception {
 
        restTemplate = new TestRestTemplate("user", "wrongpassword");
        ResponseEntity<String> response =
          restTemplate.getForEntity(base.toString(), String.class);
 
        assertEquals(HttpStatus.UNAUTHORIZED, response.getStatusCode());
        assertTrue(response.getBody().contains("Unauthorized"));
    }
}

Spring Security is in fact behind Spring Boot Security, so any security configuration that can be done with this one or any integration this one supports can also be implemented into Spring Boot.

Spring Security实际上是在Spring Boot Security的背后,所以任何可以用这个做的安全配置或这个支持的任何集成也可以实现到Spring Boot中。

5. Spring Boot OAuth2 Auto-Configuration (Using Legacy Stack)

5.Spring Boot OAuth2自动配置(使用传统堆栈)

Spring Boot has a dedicated auto-configuration support for OAuth2.

Spring Boot对OAuth2有专门的自动配置支持。

The Spring Security OAuth support that came with Spring Boot 1.x was removed in later boot versions in lieu of first-class OAuth support that comes bundled with Spring Security 5. We’ll see how to use that in the next section.

Spring Boot 1.x所附带的Spring Security OAuth支持在后来的启动版本中被删除,取而代之的是Spring Security 5所捆绑的一流OAuth支持。我们将在下一节中看到如何使用它。

For the legacy stack (using Spring Security OAuth), we’ll first need to add a Maven dependency to start setting up our application:

对于传统的堆栈(使用Spring Security OAuth),我们首先需要添加一个Maven依赖,以开始设置我们的应用程序。

<dependency>
   <groupId>org.springframework.security.oauth</groupId>
   <artifactId>spring-security-oauth2</artifactId>
</dependency>

This dependency includes a set of classes that are capable of triggering the auto-configuration mechanism defined in OAuth2AutoConfiguration class.

该依赖关系包括一组能够触发OAuth2AutoConfiguration类中定义的自动配置机制的类。

Now we have multiple choices to continue depending on the scope of our application.

现在我们有多种选择,可以根据我们的应用范围继续下去。

5.1. OAuth2 Authorization Server Auto-Configuration

5.1.OAuth2授权服务器的自动配置

If we want our application to be an OAuth2 provider, we can use @EnableAuthorizationServer.

如果我们想让我们的应用程序成为一个OAuth2提供者,我们可以使用@EnableAuthorizationServer

On startup, we’ll notice in the logs that the auto-configuration classes will generate a client id and a client secret for our authorization server, and of course a random password for basic authentication:

在启动时,我们会在日志中注意到,自动配置类将为我们的授权服务器生成一个客户ID和一个客户秘密,当然还有一个随机的密码用于基本认证。

Using default security password: a81cb256-f243-40c0-a585-81ce1b952a98
security.oauth2.client.client-id = 39d2835b-1f87-4a77-9798-e2975f36972e
security.oauth2.client.client-secret = f1463f8b-0791-46fe-9269-521b86c55b71

These credentials can be used to obtain an access token:

这些凭证可用于获得访问令牌。

curl -X POST -u 39d2835b-1f87-4a77-9798-e2975f36972e:f1463f8b-0791-46fe-9269-521b86c55b71 \
 -d grant_type=client_credentials 
 -d username=user 
 -d password=a81cb256-f243-40c0-a585-81ce1b952a98 \
 -d scope=write  http://localhost:8080/oauth/token

Our other article provides further details on the subject.

我们的其他文章提供了有关该主题的进一步细节。

5.2. Other Spring Boot OAuth2 Auto-Configuration Settings

5.2.其他Spring Boot OAuth2自动配置设置

There are some other use cases covered by Spring Boot OAuth2:

Spring Boot OAuth2还涉及一些其他用例。

  1. Resource Server@EnableResourceServer
  2. Client Application@EnableOAuth2Sso or @EnableOAuth2Client

If we need our application to be one of these types, we just have to add some configuration to application properties, as detailed by the links.

如果我们需要我们的应用程序成为这些类型之一,我们只需在应用程序属性中添加一些配置,如链接所详述。

All OAuth2 specific properties can be found at Spring Boot Common Application Properties.

所有OAuth2的具体属性都可以在Spring Boot通用应用程序属性中找到。

6. Spring Boot OAuth2 Auto-Configuration (Using New Stack)

6.Spring Boot OAuth2自动配置(使用New Stack)

To use the new stack, we need to add dependencies based on what we want to configure — an authorization server, a resource server, or a client application.

为了使用新的堆栈,我们需要根据我们想要配置的东西来添加依赖性–授权服务器、资源服务器或客户端应用程序。

Let’s look at them one by one.

让我们逐一看一下。

6.1. OAuth2 Authorization Server Support

6.1.支持OAuth2授权服务器

As we saw, the Spring Security OAuth stack offered the possibility of setting up an Authorization Server as a Spring Application. But the project has been deprecated, and Spring does not support its own authorization server as of now. Instead, it’s recommended to use existing well-established providers such as Okta, Keycloak and ForgeRock.

正如我们所看到的,Spring Security OAuth栈提供了将授权服务器设置为Spring应用程序的可能性。但该项目已被废弃,而且Spring目前不支持自己的授权服务器。相反,我们建议使用现有的成熟的供应商,如Okta、Keycloak和ForgeRock。

However, Spring Boot makes it easy for us to configure such providers. For an example Keycloak configuration, we can refer to either A Quick Guide to Using Keycloak With Spring Boot or Keycloak Embedded in a Spring Boot Application.

然而,Spring Boot使我们能够轻松地配置此类提供者。关于Keycloak配置的例子,我们可以参考在Spring Boot中使用Keycloak的快速指南嵌入Spring Boot应用程序中的Keycloak

6.2. OAuth2 Resource Server Support

6.2.OAuth2资源服务器支持

To include support for a resource server, we need to add this dependency:

为了包括对资源服务器的支持,我们需要添加这个依赖关系。

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-oauth2-resource-server</artifactId>    
</dependency>

For the latest version information, head over to Maven Central.

有关最新的版本信息,请访问Maven Central

Additionally, in our security configuration, we need to include the oauth2ResourceServer() DSL:

此外,在我们的安全配置中,我们需要包括oauth2ResourceServer() DSL。

@Configuration
public class JWTSecurityConfig {
 
    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http
          ...
          .oauth2ResourceServer(oauth2 -> oauth2.jwt());
          ...
	}
}

Our OAuth 2.0 Resource Server With Spring Security 5 gives an in-depth view of this topic.

我们的OAuth 2.0 Resource Server With Spring Security 5对该主题进行了深入探讨。

6.3. OAuth2 Client Support

6.3.OAuth2客户端支持

Similar to how we configured a resource server, a client application also needs its own dependencies and DSLs.

与我们配置资源服务器的方式类似,客户端应用程序也需要自己的依赖关系和DSL。

Here’s the specific dependency for OAuth2 client support:

这里是对OAuth2客户端支持的具体依赖。

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-oauth2-client</artifactId>
</dependency>

The latest version can be found at Maven Central.

最新版本可在Maven中心找到。

Spring Security 5 also provides first-class login support via its oath2Login() DSL.

Spring Security 5还通过其oath2Login() DSL提供一流的登录支持。

For details on SSO support in the new stack, please refer to our article Simple Single Sign-On With Spring Security OAuth2.

有关新堆栈中SSO支持的详细信息,请参考我们的文章Simple Single Sign-On With Spring Security OAuth2

7. Conclusion

7.结论

In this article, we focused on the default security configuration provided by Spring Boot. We saw how the security auto-configuration mechanism can be disabled or overridden. Then we looked at how a new security configuration can be applied.

在这篇文章中,我们重点讨论了Spring Boot提供的默认安全配置。我们看到安全自动配置机制是如何被禁用或推翻的。然后,我们研究了如何应用新的安全配置。

The source code for OAuth2 can be found on our OAuth2 GitHub repository, for legacy and new stack. The rest of the code can be found over on GitHub.

OAuth2的源代码可以在我们的OAuth2 GitHub仓库中找到,用于legacynew栈。其余的代码可以在GitHub上找到