Spring Security
如果 {url-spring-security-site}[Spring Security] 在类路径中,那么会默认保护 Web 应用程序。Spring Boot 依靠 Spring Security 的内容协商策略来确定是否使用 httpBasic
或 formLogin
。要向 Web 应用程序添加方法级安全性,你还可以使用所需设置添加 @EnableGlobalMethodSecurity
。有关更多信息,请参见 {url-spring-security-docs}/servlet/authorization/method-security.html[Spring Security 参考指南]。
默认的 UserDetailsService
有一个用户。用户名为 user
,密码是随机的,并且会在应用程序启动时以 WARN 级别打印,如下例所示:
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.
如果你微调了日志配置,请确保将 |
你可以通过提供 spring.security.user.name
和 spring.security.user.password
来更改用户名和密码。
在 Web 应用程序中默认获得的基本功能有:
-
一个
UserDetailsService
(或者在 WebFlux 应用程序中为ReactiveUserDetailsService
)bean 具有内存存储和一个带有生成密码的单个用户(请参见SecurityProperties.User
以了解用户的属性)。 -
整个应用程序的基于表单的登录或 HTTP 基本安全(取决于请求中的
Accept
头),包括 actuator 端点(如果 actuator 在类路径中)。 -
用于发布身份验证事件的
DefaultAuthenticationEventPublisher
。
你可以通过为其添加一个 bean 来提供不同的 AuthenticationEventPublisher
。
MVC Security
默认安全配置在 SecurityAutoConfiguration
和 UserDetailsServiceAutoConfiguration
中实现。SecurityAutoConfiguration
导入 SpringBootWebSecurityConfiguration
以实现 Web 安全,UserDetailsServiceAutoConfiguration
配置身份验证(这也与非 Web 应用程序相关)。
要完全关闭默认 Web 应用程序安全配置或组合多个 Spring Security 组件(例如 OAuth2 Client 和资源服务器),请添加 SecurityFilterChain
类型的 bean(这样做不会禁用 UserDetailsService
配置或 Actuator 的安全性)。要同时关闭 UserDetailsService
配置,你可以添加 UserDetailsService
、AuthenticationProvider
或 AuthenticationManager
类型的 bean。
UserDetailsService
的自动配置也会支持类路径中的任何一个 Spring Security 模块:
-
spring-security-oauth2-client
-
spring-security-oauth2-resource-server
-
spring-security-saml2-service-provider
除了上述一个或多个依赖项之外,要使用 UserDetailsService
,请定义你自己的 InMemoryUserDetailsManager
Bean。
可以通过添加自定义 SecurityFilterChain
Bean 来覆盖访问规则。Spring Boot 提供了可用于覆盖执行器端点和静态资源访问规则的便捷方法。EndpointRequest
可用于创建基于 configprop:management.endpoints.web.base-path[] 属性的 RequestMatcher
。PathRequest
可用于为常用位置中的资源创建 RequestMatcher
。
WebFlux Security
与 Spring MVC 应用程序类似,你可以通过添加 spring-boot-starter-security
依赖项来保护你的 WebFlux 应用程序。默认安全配置在 ReactiveSecurityAutoConfiguration
和 UserDetailsServiceAutoConfiguration
中实现。ReactiveSecurityAutoConfiguration
为 web 安全导入 WebFluxSecurityConfiguration
,UserDetailsServiceAutoConfiguration
配置身份验证(在非 web 应用程序中这也相关)。
要完全关闭默认的 Web 应用程序安全配置,您可以添加类型为 WebFilterChainProxy
的 Bean(这样做不会禁用 UserDetailsService
配置或执行器的安全)。要关闭 UserDetailsService
配置,您可以添加 ReactiveUserDetailsService
或 ReactiveAuthenticationManager
类型的 Bean。
当类路径上含有以下任一 Spring Security 模块时,自动配置也将退回:
-
spring-security-oauth2-client
-
spring-security-oauth2-resource-server
要额外使用 ReactiveUserDetailsService
而非其中的一个或多个依赖项,请定义您自己的 MapReactiveUserDetailsService
Bean。
可以通过添加自定义 SecurityWebFilterChain
Bean,来配置访问规则和多个 Spring Security 组件(例如 OAuth 2 客户端和资源服务器)的使用。Spring Boot 提供了可用于替代执行器端点和静态资源的访问规则的便捷方法。EndpointRequest
可用于创建基于 configprop:management.endpoints.web.base-path[] 属性的 ServerWebExchangeMatcher
。
PathRequest
可用于为常用位置中的资源创建 ServerWebExchangeMatcher
。
例如,您可以通过添加类似以下内容的方式自定义安全配置:
OAuth2
OAuth2 是得到 Spring 支持的广泛应用的授权框架。
Client
如果类路径上存在 spring-security-oauth2-client
,您可以利用某些自动配置来设置 OAuth2/Open ID Connect 客户端。此配置使用 OAuth2ClientProperties
下的属性。这些属性同时适用于 Servlet 和响应式应用程序。
您可以在 spring.security.oauth2.client
前缀下注册多个 OAuth2 客户端和提供程序,如下例所示:
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 提供程序:
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
:
Spring Boot 自动配置 |
OAuth2 Client Registration for Common Providers
对于包括 Google、Github、Facebook 和 Okta 在内的常见的 OAuth2 和 OpenID 提供程序,我们提供了一组提供程序默认值(分别为 google
、github
、facebook
和 okta
)。
如果您无需自定义这些提供程序,则可以将 provider
属性设置为需要从中推断默认值的那个属性。此外,如果客户端注册的密钥匹配默认支持的提供程序,Spring Boot 也推断该密钥。
换句话说,以下示例中的两个配置使用 Google 提供程序:
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,如下面的示例所示:
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 格式的公钥的文件。 |
可以使用 configprop:spring.security.oauth2.resourceserver.jwt.audiences[] 属性来指定 JWT 中 aud 声明的预期值。例如,要求 JWT 包含具有 my-audience
值的 aud 声明:
spring: security: oauth2: resourceserver: jwt: audiences: - "my-audience"
相同属性适用于 Servlet 和 Reactive 应用程序。或者,可以为 Servlet 应用程序定义自己的 JwtDecoder
bean 或为 Reactive 应用程序定义 ReactiveJwtDecoder
bean。
在使用不透明令牌而不是 JWT 的情况下,可以配置以下属性来验证通过检查令牌:
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。
Authorization Server
如果类路径上有 spring-security-oauth2-authorization-server
,则可以利用一些自动配置来设置基于 Servlet 的 OAuth2 授权服务器。
可以在 spring.security.oauth2.authorizationserver.client
前缀下注册多个 OAuth2 客户端,如以下示例所示:
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"
|
Spring Boot 为 Spring Authorization Server 提供的自动配置旨在快速入门。大多数应用程序需要自定义,并希望定义多个 bean 来覆盖自动配置。
可以将以下组件定义为 bean 来覆盖 Spring Authorization Server 特有的自动配置:
-
RegisteredClientRepository
-
AuthorizationServerSettings
-
SecurityFilterChain
-
com.nimbusds.jose.jwk.source.JWKSource<com.nimbusds.jose.proc.SecurityContext>
-
JwtDecoder
Spring Boot 自动配置了一个 |
可以在 {url-spring-authorization-server-docs}/getting-started.html[{url-spring-authorization-server-docs}[Spring Authorization Server 参考指南]] 的 [入门] 章节中找到更多信息。
SAML 2.0
Relying Party
如果类路径上有 spring-security-saml2-service-provider
,则可以利用一些自动配置来设置 SAML 2.0 依靠方。此配置使用 Saml2RelyingPartyProperties
下的属性。
依靠方注册表示身份提供程序 (IDP) 与服务提供程序 (SP) 之间的配对配置。可以在 spring.security.saml2.relyingparty
前缀下注册多个依靠方,如以下示例所示:
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 的 Saml2LogoutRequestFilter
和 Saml2LogoutResponseFilter
仅处理与 /logout/saml2/slo
匹配的 URL。如果希望自定义 AP 启动注销请求发送到的 url
或 AP 发送注销响应到的 response-url
以使用不同的模式,则需要提供配置来处理该自定义模式。例如,对于 Servlet 应用程序,可以添加类似以下内容的自己的 SecurityFilterChain
: