Spring Security

如果 {url-spring-security-site}[Spring Security] 在类路径中,那么会默认保护 Web 应用程序。Spring Boot 依靠 Spring Security 的内容协商策略来确定是否使用 httpBasicformLogin。要向 Web 应用程序添加方法级安全性,你还可以使用所需设置添加 @EnableGlobalMethodSecurity。有关更多信息,请参见 {url-spring-security-docs}/servlet/authorization/method-security.html[Spring Security 参考指南]。

If {url-spring-security-site}[Spring Security] is on the classpath, then web applications are secured by default. Spring Boot relies on Spring Security’s content-negotiation strategy to determine whether to use httpBasic or formLogin. To add method-level security to a web application, you can also add @EnableGlobalMethodSecurity with your desired settings. Additional information can be found in the {url-spring-security-docs}/servlet/authorization/method-security.html[Spring Security Reference Guide].

默认的 UserDetailsService 有一个用户。用户名为 user,密码是随机的,并且会在应用程序启动时以 WARN 级别打印,如下例所示:

The default UserDetailsService has a single user. The user name is user, and the password is random and is printed at WARN level when the application starts, as shown in the following example:

Using generated security password: 78fa095d-3f4c-48b1-ad50-e24c31d5cf35

This generated password is for development use only. Your security configuration must be updated before running your application in production.

如果你微调了日志配置,请确保将 org.springframework.boot.autoconfigure.security 种类设置为记录 WARN 级别消息。否则,默认密码将不会被打印。

If you fine-tune your logging configuration, ensure that the org.springframework.boot.autoconfigure.security category is set to log WARN-level messages. Otherwise, the default password is not printed.

你可以通过提供 spring.security.user.namespring.security.user.password 来更改用户名和密码。

You can change the username and password by providing a spring.security.user.name and spring.security.user.password.

在 Web 应用程序中默认获得的基本功能有:

The basic features you get by default in a web application are:

  • A UserDetailsService (or ReactiveUserDetailsService in case of a WebFlux application) bean with in-memory store and a single user with a generated password (see SecurityProperties.User for the properties of the user).

  • Form-based login or HTTP Basic security (depending on the Accept header in the request) for the entire application (including actuator endpoints if actuator is on the classpath).

  • A DefaultAuthenticationEventPublisher for publishing authentication events.

你可以通过为其添加一个 bean 来提供不同的 AuthenticationEventPublisher

You can provide a different AuthenticationEventPublisher by adding a bean for it.

MVC Security

默认安全配置在 SecurityAutoConfigurationUserDetailsServiceAutoConfiguration 中实现。SecurityAutoConfiguration 导入 SpringBootWebSecurityConfiguration 以实现 Web 安全,UserDetailsServiceAutoConfiguration 配置身份验证(这也与非 Web 应用程序相关)。

The default security configuration is implemented in SecurityAutoConfiguration and UserDetailsServiceAutoConfiguration. SecurityAutoConfiguration imports SpringBootWebSecurityConfiguration for web security and UserDetailsServiceAutoConfiguration configures authentication, which is also relevant in non-web applications.

要完全关闭默认 Web 应用程序安全配置或组合多个 Spring Security 组件(例如 OAuth2 Client 和资源服务器),请添加 SecurityFilterChain 类型的 bean(这样做不会禁用 UserDetailsService 配置或 Actuator 的安全性)。要同时关闭 UserDetailsService 配置,你可以添加 UserDetailsServiceAuthenticationProviderAuthenticationManager 类型的 bean。

To switch off the default web application security configuration completely or to combine multiple Spring Security components such as OAuth2 Client and Resource Server, add a bean of type SecurityFilterChain (doing so does not disable the UserDetailsService configuration or Actuator’s security). To also switch off the UserDetailsService configuration, you can add a bean of type UserDetailsService, AuthenticationProvider, or AuthenticationManager.

UserDetailsService 的自动配置也会支持类路径中的任何一个 Spring Security 模块:

The auto-configuration of a UserDetailsService will also back off any of the following Spring Security modules is on the classpath:

  • spring-security-oauth2-client

  • spring-security-oauth2-resource-server

  • spring-security-saml2-service-provider

除了上述一个或多个依赖项之外,要使用 UserDetailsService,请定义你自己的 InMemoryUserDetailsManager Bean。

To use UserDetailsService in addition to one or more of these dependencies, define your own InMemoryUserDetailsManager bean.

可以通过添加自定义 SecurityFilterChain Bean 来覆盖访问规则。Spring Boot 提供了可用于覆盖执行器端点和静态资源访问规则的便捷方法。EndpointRequest 可用于创建基于 configprop:management.endpoints.web.base-path[] 属性的 RequestMatcherPathRequest 可用于为常用位置中的资源创建 RequestMatcher

Access rules can be overridden by adding a custom SecurityFilterChain bean. Spring Boot provides convenience methods that can be used to override access rules for actuator endpoints and static resources. EndpointRequest can be used to create a RequestMatcher that is based on the configprop:management.endpoints.web.base-path[] property. PathRequest can be used to create a RequestMatcher for resources in commonly used locations.

WebFlux Security

与 Spring MVC 应用程序类似,你可以通过添加 spring-boot-starter-security 依赖项来保护你的 WebFlux 应用程序。默认安全配置在 ReactiveSecurityAutoConfigurationUserDetailsServiceAutoConfiguration 中实现。ReactiveSecurityAutoConfiguration 为 web 安全导入 WebFluxSecurityConfigurationUserDetailsServiceAutoConfiguration 配置身份验证(在非 web 应用程序中这也相关)。

Similar to Spring MVC applications, you can secure your WebFlux applications by adding the spring-boot-starter-security dependency. The default security configuration is implemented in ReactiveSecurityAutoConfiguration and UserDetailsServiceAutoConfiguration. ReactiveSecurityAutoConfiguration imports WebFluxSecurityConfiguration for web security and UserDetailsServiceAutoConfiguration configures authentication, which is also relevant in non-web applications.

要完全关闭默认的 Web 应用程序安全配置,您可以添加类型为 WebFilterChainProxy 的 Bean(这样做不会禁用 UserDetailsService 配置或执行器的安全)。要关闭 UserDetailsService 配置,您可以添加 ReactiveUserDetailsServiceReactiveAuthenticationManager 类型的 Bean。

To switch off the default web application security configuration completely, you can add a bean of type WebFilterChainProxy (doing so does not disable the UserDetailsService configuration or Actuator’s security). To also switch off the UserDetailsService configuration, you can add a bean of type ReactiveUserDetailsService or ReactiveAuthenticationManager.

当类路径上含有以下任一 Spring Security 模块时,自动配置也将退回:

The auto-configuration will also back off when any of the following Spring Security modules is on the classpath:

  • spring-security-oauth2-client

  • spring-security-oauth2-resource-server

要额外使用 ReactiveUserDetailsService 而非其中的一个或多个依赖项,请定义您自己的 MapReactiveUserDetailsService Bean。

To use ReactiveUserDetailsService in addition to one or more of these dependencies, define your own MapReactiveUserDetailsService bean.

可以通过添加自定义 SecurityWebFilterChain Bean,来配置访问规则和多个 Spring Security 组件(例如 OAuth 2 客户端和资源服务器)的使用。Spring Boot 提供了可用于替代执行器端点和静态资源的访问规则的便捷方法。EndpointRequest 可用于创建基于 configprop:management.endpoints.web.base-path[] 属性的 ServerWebExchangeMatcher

Access rules and the use of multiple Spring Security components such as OAuth 2 Client and Resource Server can be configured by adding a custom SecurityWebFilterChain bean. Spring Boot provides convenience methods that can be used to override access rules for actuator endpoints and static resources. EndpointRequest can be used to create a ServerWebExchangeMatcher that is based on the configprop:management.endpoints.web.base-path[] property.

PathRequest 可用于为常用位置中的资源创建 ServerWebExchangeMatcher

PathRequest can be used to create a ServerWebExchangeMatcher for resources in commonly used locations.

例如,您可以通过添加类似以下内容的方式自定义安全配置:

For example, you can customize your security configuration by adding something like:

OAuth2

OAuth2 是得到 Spring 支持的广泛应用的授权框架。

OAuth2 is a widely used authorization framework that is supported by Spring.

Client

如果类路径上存在 spring-security-oauth2-client,您可以利用某些自动配置来设置 OAuth2/Open ID Connect 客户端。此配置使用 OAuth2ClientProperties 下的属性。这些属性同时适用于 Servlet 和响应式应用程序。

If you have spring-security-oauth2-client on your classpath, you can take advantage of some auto-configuration to set up OAuth2/Open ID Connect clients. This configuration makes use of the properties under OAuth2ClientProperties. The same properties are applicable to both servlet and reactive applications.

您可以在 spring.security.oauth2.client 前缀下注册多个 OAuth2 客户端和提供程序,如下例所示:

You can register multiple OAuth2 clients and providers under the spring.security.oauth2.client prefix, as shown in the following example:

spring:
  security:
    oauth2:
      client:
        registration:
          my-login-client:
            client-id: "abcd"
            client-secret: "password"
            client-name: "Client for OpenID Connect"
            provider: "my-oauth-provider"
            scope: "openid,profile,email,phone,address"
            redirect-uri: "{baseUrl}/login/oauth2/code/{registrationId}"
            client-authentication-method: "client_secret_basic"
            authorization-grant-type: "authorization_code"

          my-client-1:
            client-id: "abcd"
            client-secret: "password"
            client-name: "Client for user scope"
            provider: "my-oauth-provider"
            scope: "user"
            redirect-uri: "{baseUrl}/authorized/user"
            client-authentication-method: "client_secret_basic"
            authorization-grant-type: "authorization_code"

          my-client-2:
            client-id: "abcd"
            client-secret: "password"
            client-name: "Client for email scope"
            provider: "my-oauth-provider"
            scope: "email"
            redirect-uri: "{baseUrl}/authorized/email"
            client-authentication-method: "client_secret_basic"
            authorization-grant-type: "authorization_code"

        provider:
          my-oauth-provider:
            authorization-uri: "https://my-auth-server.com/oauth2/authorize"
            token-uri: "https://my-auth-server.com/oauth2/token"
            user-info-uri: "https://my-auth-server.com/userinfo"
            user-info-authentication-method: "header"
            jwk-set-uri: "https://my-auth-server.com/oauth2/jwks"
            user-name-attribute: "name"

对于支持 OpenID Connect discovery 的 OpenID Connect 提供程序,可以进一步简化配置。该提供程序需要使用 issuer-uri 进行配置,它是断言其颁发者标识符的 URI。例如,如果提供的 issuer-uri 是“https://example.com”,那么将向“https://example.com/.well-known/openid-configuration”发出“OpenID 提供程序配置请求”。结果预计为“OpenID 提供程序配置响应”。以下示例显示如何使用 issuer-uri 配置 OpenID Connect 提供程序:

For OpenID Connect providers that support OpenID Connect discovery, the configuration can be further simplified. The provider needs to be configured with an issuer-uri which is the URI that it asserts as its Issuer Identifier. For example, if the issuer-uri provided is "https://example.com", then an "OpenID Provider Configuration Request" will be made to "https://example.com/.well-known/openid-configuration". The result is expected to be an "OpenID Provider Configuration Response". The following example shows how an OpenID Connect Provider can be configured with the issuer-uri:

spring:
  security:
    oauth2:
      client:
        provider:
          oidc-provider:
            issuer-uri: "https://dev-123456.oktapreview.com/oauth2/default/"

默认情况下,Spring Security 的 OAuth2LoginAuthenticationFilter 仅处理与 /login/oauth2/code/* 匹配的 URL。如果您要自定义 redirect-uri 以使用不同的模式,您需要提供配置来处理该自定义模式。例如,对于 Servlet 应用程序,您可以添加与以下类似的 SecurityFilterChain

By default, Spring Security’s OAuth2LoginAuthenticationFilter only processes URLs matching /login/oauth2/code/*. If you want to customize the redirect-uri to use a different pattern, you need to provide configuration to process that custom pattern. For example, for servlet applications, you can add your own SecurityFilterChain that resembles the following:

Spring Boot 自动配置 InMemoryOAuth2AuthorizedClientService,Spring Security 用它来管理客户端注册。InMemoryOAuth2AuthorizedClientService 的能力有限,我们建议仅在开发环境中使用它。对于生产环境,请考虑使用 JdbcOAuth2AuthorizedClientService 或创建您自己的 OAuth2AuthorizedClientService 实现。

Spring Boot auto-configures an InMemoryOAuth2AuthorizedClientService which is used by Spring Security for the management of client registrations. The InMemoryOAuth2AuthorizedClientService has limited capabilities and we recommend using it only for development environments. For production environments, consider using a JdbcOAuth2AuthorizedClientService or creating your own implementation of OAuth2AuthorizedClientService.

OAuth2 Client Registration for Common Providers

对于包括 Google、Github、Facebook 和 Okta 在内的常见的 OAuth2 和 OpenID 提供程序,我们提供了一组提供程序默认值(分别为 googlegithubfacebookokta)。

For common OAuth2 and OpenID providers, including Google, Github, Facebook, and Okta, we provide a set of provider defaults (google, github, facebook, and okta, respectively).

如果您无需自定义这些提供程序,则可以将 provider 属性设置为需要从中推断默认值的那个属性。此外,如果客户端注册的密钥匹配默认支持的提供程序,Spring Boot 也推断该密钥。

If you do not need to customize these providers, you can set the provider attribute to the one for which you need to infer defaults. Also, if the key for the client registration matches a default supported provider, Spring Boot infers that as well.

换句话说,以下示例中的两个配置使用 Google 提供程序:

In other words, the two configurations in the following example use the Google provider:

spring:
  security:
    oauth2:
      client:
        registration:
          my-client:
            client-id: "abcd"
            client-secret: "password"
            provider: "google"
          google:
            client-id: "abcd"
            client-secret: "password"

Resource Server

如果类路径上存在 spring-security-oauth2-resource-server,Spring Boot 可以设置 OAuth2 资源服务器。对于 JWT 配置,需要指定 JWK Set URI 或 OIDC 颁发者 URI,如下面的示例所示:

If you have spring-security-oauth2-resource-server on your classpath, Spring Boot can set up an OAuth2 Resource Server. For JWT configuration, a JWK Set URI or OIDC Issuer URI needs to be specified, as shown in the following examples:

spring:
  security:
    oauth2:
      resourceserver:
        jwt:
          jwk-set-uri: "https://example.com/oauth2/default/v1/keys"
spring:
  security:
    oauth2:
      resourceserver:
        jwt:
          issuer-uri: "https://dev-123456.oktapreview.com/oauth2/default/"

如果授权服务器不支持 JWK Set URI,则可以使用用于验证 JWT 签名的公钥来配置资源服务器。可以使用 configprop:spring.security.oauth2.resourceserver.jwt.public-key-location[] 属性来执行此操作,其中值需要指向包含 PEM 编码的 x509 格式的公钥的文件。

If the authorization server does not support a JWK Set URI, you can configure the resource server with the Public Key used for verifying the signature of the JWT. This can be done using the configprop:spring.security.oauth2.resourceserver.jwt.public-key-location[] property, where the value needs to point to a file containing the public key in the PEM-encoded x509 format.

可以使用 configprop:spring.security.oauth2.resourceserver.jwt.audiences[] 属性来指定 JWT 中 aud 声明的预期值。例如,要求 JWT 包含具有 my-audience 值的 aud 声明:

The configprop:spring.security.oauth2.resourceserver.jwt.audiences[] property can be used to specify the expected values of the aud claim in JWTs. For example, to require JWTs to contain an aud claim with the value my-audience:

spring:
  security:
    oauth2:
      resourceserver:
        jwt:
          audiences:
            - "my-audience"

相同属性适用于 Servlet 和 Reactive 应用程序。或者,可以为 Servlet 应用程序定义自己的 JwtDecoder bean 或为 Reactive 应用程序定义 ReactiveJwtDecoder bean。

The same properties are applicable for both servlet and reactive applications. Alternatively, you can define your own JwtDecoder bean for servlet applications or a ReactiveJwtDecoder for reactive applications.

在使用不透明令牌而不是 JWT 的情况下,可以配置以下属性来验证通过检查令牌:

In cases where opaque tokens are used instead of JWTs, you can configure the following properties to validate tokens through introspection:

spring:
  security:
    oauth2:
      resourceserver:
        opaquetoken:
          introspection-uri: "https://example.com/check-token"
          client-id: "my-client-id"
          client-secret: "my-client-secret"

同样,相同属性适用于 Servlet 和 Reactive 应用程序。或者,可以为 Servlet 应用程序定义自己的 OpaqueTokenIntrospector bean 或为 Reactive 应用程序定义 ReactiveOpaqueTokenIntrospector bean。

Again, the same properties are applicable for both servlet and reactive applications. Alternatively, you can define your own OpaqueTokenIntrospector bean for servlet applications or a ReactiveOpaqueTokenIntrospector for reactive applications.

Authorization Server

如果类路径上有 spring-security-oauth2-authorization-server ,则可以利用一些自动配置来设置基于 Servlet 的 OAuth2 授权服务器。

If you have spring-security-oauth2-authorization-server on your classpath, you can take advantage of some auto-configuration to set up a Servlet-based OAuth2 Authorization Server.

可以在 spring.security.oauth2.authorizationserver.client 前缀下注册多个 OAuth2 客户端,如以下示例所示:

You can register multiple OAuth2 clients under the spring.security.oauth2.authorizationserver.client prefix, as shown in the following example:

spring:
  security:
    oauth2:
      authorizationserver:
        client:
          my-client-1:
            registration:
              client-id: "abcd"
              client-secret: "{noop}secret1"
              client-authentication-methods:
                - "client_secret_basic"
              authorization-grant-types:
                - "authorization_code"
                - "refresh_token"
              redirect-uris:
                - "https://my-client-1.com/login/oauth2/code/abcd"
                - "https://my-client-1.com/authorized"
              scopes:
                - "openid"
                - "profile"
                - "email"
                - "phone"
                - "address"
            require-authorization-consent: true
          my-client-2:
            registration:
              client-id: "efgh"
              client-secret: "{noop}secret2"
              client-authentication-methods:
                - "client_secret_jwt"
              authorization-grant-types:
                - "client_credentials"
              scopes:
                - "user.read"
                - "user.write"
            jwk-set-uri: "https://my-client-2.com/jwks"
	        token-endpoint-authentication-signing-algorithm: "RS256"

client-secret 属性必须采用能与配置的 PasswordEncoder 匹配的格式。PasswordEncoder 的默认实例是通过 PasswordEncoderFactories.createDelegatingPasswordEncoder() 创建的。

The client-secret property must be in a format that can be matched by the configured PasswordEncoder. The default instance of PasswordEncoder is created via PasswordEncoderFactories.createDelegatingPasswordEncoder().

Spring Boot 为 Spring Authorization Server 提供的自动配置旨在快速入门。大多数应用程序需要自定义,并希望定义多个 bean 来覆盖自动配置。

The auto-configuration Spring Boot provides for Spring Authorization Server is designed for getting started quickly. Most applications will require customization and will want to define several beans to override auto-configuration.

可以将以下组件定义为 bean 来覆盖 Spring Authorization Server 特有的自动配置:

The following components can be defined as beans to override auto-configuration specific to Spring Authorization Server:

  • RegisteredClientRepository

  • AuthorizationServerSettings

  • SecurityFilterChain

  • com.nimbusds.jose.jwk.source.JWKSource<com.nimbusds.jose.proc.SecurityContext>

  • JwtDecoder

Spring Boot 自动配置了一个 InMemoryRegisteredClientRepository ,Spring Authorization Server 使用其管理已注册客户端。 InMemoryRegisteredClientRepository 具有有限的能力,我们建议仅在开发环境中使用它。对于生产环境,请考虑使用 JdbcRegisteredClientRepository 或创建 RegisteredClientRepository 的自己的实现。

Spring Boot auto-configures an InMemoryRegisteredClientRepository which is used by Spring Authorization Server for the management of registered clients. The InMemoryRegisteredClientRepository has limited capabilities and we recommend using it only for development environments. For production environments, consider using a JdbcRegisteredClientRepository or creating your own implementation of RegisteredClientRepository.

可以在 {url-spring-authorization-server-docs}/getting-started.html[{url-spring-authorization-server-docs}[Spring Authorization Server 参考指南]] 的 [入门] 章节中找到更多信息。

Additional information can be found in the {url-spring-authorization-server-docs}/getting-started.html[Getting Started] chapter of the {url-spring-authorization-server-docs}[Spring Authorization Server Reference Guide].

SAML 2.0

Relying Party

如果类路径上有 spring-security-saml2-service-provider ,则可以利用一些自动配置来设置 SAML 2.0 依靠方。此配置使用 Saml2RelyingPartyProperties 下的属性。

If you have spring-security-saml2-service-provider on your classpath, you can take advantage of some auto-configuration to set up a SAML 2.0 Relying Party. This configuration makes use of the properties under Saml2RelyingPartyProperties.

依靠方注册表示身份提供程序 (IDP) 与服务提供程序 (SP) 之间的配对配置。可以在 spring.security.saml2.relyingparty 前缀下注册多个依靠方,如以下示例所示:

A relying party registration represents a paired configuration between an Identity Provider, IDP, and a Service Provider, SP. You can register multiple relying parties under the spring.security.saml2.relyingparty prefix, as shown in the following example:

spring:
  security:
    saml2:
      relyingparty:
        registration:
          my-relying-party1:
            signing:
              credentials:
              - private-key-location: "path-to-private-key"
                certificate-location: "path-to-certificate"
            decryption:
              credentials:
              - private-key-location: "path-to-private-key"
                certificate-location: "path-to-certificate"
            singlelogout:
               url: "https://myapp/logout/saml2/slo"
               response-url: "https://remoteidp2.slo.url"
               binding: "POST"
            assertingparty:
              verification:
                credentials:
                - certificate-location: "path-to-verification-cert"
              entity-id: "remote-idp-entity-id1"
              sso-url: "https://remoteidp1.sso.url"

          my-relying-party2:
            signing:
              credentials:
              - private-key-location: "path-to-private-key"
                certificate-location: "path-to-certificate"
            decryption:
              credentials:
              - private-key-location: "path-to-private-key"
                certificate-location: "path-to-certificate"
            assertingparty:
              verification:
                credentials:
                - certificate-location: "path-to-other-verification-cert"
              entity-id: "remote-idp-entity-id2"
              sso-url: "https://remoteidp2.sso.url"
              singlelogout:
                url: "https://remoteidp2.slo.url"
                response-url: "https://myapp/logout/saml2/slo"
                binding: "POST"

对于 SAML2 注销,默认情况下,Spring Security 的 Saml2LogoutRequestFilterSaml2LogoutResponseFilter 仅处理与 /logout/saml2/slo 匹配的 URL。如果希望自定义 AP 启动注销请求发送到的 url 或 AP 发送注销响应到的 response-url 以使用不同的模式,则需要提供配置来处理该自定义模式。例如,对于 Servlet 应用程序,可以添加类似以下内容的自己的 SecurityFilterChain

For SAML2 logout, by default, Spring Security’s Saml2LogoutRequestFilter and Saml2LogoutResponseFilter only process URLs matching /logout/saml2/slo. If you want to customize the url to which AP-initiated logout requests get sent to or the response-url to which an AP sends logout responses to, to use a different pattern, you need to provide configuration to process that custom pattern. For example, for servlet applications, you can add your own SecurityFilterChain that resembles the following: