29. Security
如果Spring Security在 Classpath 上,则默认情况下将保护 Web 应用程序的安全。 Spring Boot 依靠 Spring Security 的内容协商策略来确定使用httpBasic
还是formLogin
。要将方法级安全性添加到 Web 应用程序,您还可以使用所需的设置添加@EnableGlobalMethodSecurity
。其他信息可以在Spring Security 参考指南中找到。
默认的UserDetailsService
有一个用户。用户名为user
,密码为随机密码,并在应用程序启动时以 INFO 级别显示,如下例所示:
Using generated security password: 78fa095d-3f4c-48b1-ad50-e24c31d5cf35
Note
如果您微调日志记录配置,请确保将org.springframework.boot.autoconfigure.security
类别设置为记录INFO
级消息。否则,不会打印默认密码。
您可以通过提供spring.security.user.name
和spring.security.user.password
来更改用户名和密码。
默认情况下,您在 Web 应用程序中获得的基本功能是:
-
具有内存存储的
UserDetailsService
(或 WebFlux 应用程序为ReactiveUserDetailsService
)bean 和具有生成的密码的单个用户(有关用户的属性,请参见SecurityProperties.User)。 -
整个应用程序的基于表单的登录或 HTTP 基本安全性(取决于 Content-Type)(如果 Actuator 位于 Classpath 上,则包括 Actuator 端点)。
-
DefaultAuthenticationEventPublisher
用于发布身份验证事件。
您可以通过添加一个 Bean 来提供另一个AuthenticationEventPublisher
。
29.1 MVC 安全性
默认的安全配置在SecurityAutoConfiguration
和UserDetailsServiceAutoConfiguration
中实现。 SecurityAutoConfiguration
导入SpringBootWebSecurityConfiguration
以获得 Web 安全性,并且UserDetailsServiceAutoConfiguration
配置身份验证,这也与非 Web 应用程序相关。要完全关闭默认的 Web 应用程序安全性配置,可以添加类型为WebSecurityConfigurerAdapter
的 bean(这样做不会禁用UserDetailsService
配置或 Actuator 的安全性)。
要也关闭UserDetailsService
配置,可以添加UserDetailsService
,AuthenticationProvider
或AuthenticationManager
类型的 Bean。 Spring Bootsample中有几个安全的应用程序,可帮助您开始使用常见的用例。
通过添加自定义WebSecurityConfigurerAdapter
可以覆盖访问规则。 Spring Boot 提供了便利的方法,可用于覆盖 Actuator 端点和静态资源的访问规则。 EndpointRequest
可用于创建基于management.endpoints.web.base-path
属性的RequestMatcher
。 PathRequest
可用于为常用位置的资源创建RequestMatcher
。
29.2 WebFlux 安全性
与 Spring MVC 应用程序类似,您可以通过添加spring-boot-starter-security
依赖项来保护 WebFlux 应用程序。默认的安全配置在ReactiveSecurityAutoConfiguration
和UserDetailsServiceAutoConfiguration
中实现。 ReactiveSecurityAutoConfiguration
导入WebFluxSecurityConfiguration
以获得 Web 安全性,并且UserDetailsServiceAutoConfiguration
配置身份验证,这也与非 Web 应用程序相关。要完全关闭默认的 Web 应用程序安全性配置,可以添加类型为WebFilterChainProxy
的 bean(这样做不会禁用UserDetailsService
配置或 Actuator 的安全性)。
要也关闭UserDetailsService
配置,可以添加ReactiveUserDetailsService
或ReactiveAuthenticationManager
类型的 Bean。
可以通过添加自定义SecurityWebFilterChain
来配置访问规则。 Spring Boot 提供了便利的方法,可用于覆盖 Actuator 端点和静态资源的访问规则。 EndpointRequest
可用于创建基于management.endpoints.web.base-path
属性的ServerWebExchangeMatcher
。
PathRequest
可用于为常用位置的资源创建ServerWebExchangeMatcher
。
例如,您可以通过添加以下内容来自定义安全配置:
@Bean
public SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) {
return http
.authorizeExchange()
.matchers(PathRequest.toStaticResources().atCommonLocations()).permitAll()
.pathMatchers("/foo", "/bar")
.authenticated().and()
.formLogin().and()
.build();
}
29.3 OAuth2
OAuth2是 Spring 支持的广泛使用的授权框架。
29.3.1 Client
如果您的 Classpath 上有spring-security-oauth2-client
,则可以利用一些自动配置功能来轻松设置 OAuth2/Open ID Connect Client 端。此配置使用OAuth2ClientProperties
下的属性。相同的属性适用于 servlet 和反应式应用程序。
您可以使用spring.security.oauth2.client
前缀注册多个 OAuth2 Client 端和提供者,如以下示例所示:
spring.security.oauth2.client.registration.my-client-1.client-id=abcd
spring.security.oauth2.client.registration.my-client-1.client-secret=password
spring.security.oauth2.client.registration.my-client-1.client-name=Client for user scope
spring.security.oauth2.client.registration.my-client-1.provider=my-oauth-provider
spring.security.oauth2.client.registration.my-client-1.scope=user
spring.security.oauth2.client.registration.my-client-1.redirect-uri-template=http://my-redirect-uri.com
spring.security.oauth2.client.registration.my-client-1.client-authentication-method=basic
spring.security.oauth2.client.registration.my-client-1.authorization-grant-type=authorization_code
spring.security.oauth2.client.registration.my-client-2.client-id=abcd
spring.security.oauth2.client.registration.my-client-2.client-secret=password
spring.security.oauth2.client.registration.my-client-2.client-name=Client for email scope
spring.security.oauth2.client.registration.my-client-2.provider=my-oauth-provider
spring.security.oauth2.client.registration.my-client-2.scope=email
spring.security.oauth2.client.registration.my-client-2.redirect-uri-template=http://my-redirect-uri.com
spring.security.oauth2.client.registration.my-client-2.client-authentication-method=basic
spring.security.oauth2.client.registration.my-client-2.authorization-grant-type=authorization_code
spring.security.oauth2.client.provider.my-oauth-provider.authorization-uri=http://my-auth-server/oauth/authorize
spring.security.oauth2.client.provider.my-oauth-provider.token-uri=http://my-auth-server/oauth/token
spring.security.oauth2.client.provider.my-oauth-provider.user-info-uri=http://my-auth-server/userinfo
spring.security.oauth2.client.provider.my-oauth-provider.user-info-authentication-method=header
spring.security.oauth2.client.provider.my-oauth-provider.jwk-set-uri=http://my-auth-server/token_keys
spring.security.oauth2.client.provider.my-oauth-provider.user-name-attribute=name
对于支持OpenID Connect 发现的 OpenID Connect 提供程序,可以进一步简化配置。提供者需要配置一个issuer-uri
,这是它声明为其发布者标识符的 URI。例如,如果提供的issuer-uri
是“ https://example.com”,则将对“ https://example.com/.well-known/openid-configuration”设置OpenID Provider Configuration Request
。结果预期为OpenID Provider Configuration Response
。以下示例显示了如何使用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 应用程序,您可以添加自己的WebSecurityConfigurerAdapter
,其类似于以下内容:
public class OAuth2LoginSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.anyRequest().authenticated()
.and()
.oauth2Login()
.redirectionEndpoint()
.baseUri("/custom-callback");
}
}
通用提供商的 OAuth2 Client 端注册
对于常见的 OAuth2 和 OpenID 提供程序,包括 Google,Github,Facebook 和 Okta,我们提供了一组提供程序默认值(分别为google
,github
,facebook
和okta
)。
如果不需要自定义这些提供程序,则可以将provider
属性设置为您需要为其推断默认值的属性。另外,如果用于 Client 端注册的密钥与默认支持的提供程序匹配,则 Spring Boot 也会进行推断。
换句话说,以下示例中的两种配置都使用 Google 提供程序:
spring.security.oauth2.client.registration.my-client.client-id=abcd
spring.security.oauth2.client.registration.my-client.client-secret=password
spring.security.oauth2.client.registration.my-client.provider=google
spring.security.oauth2.client.registration.google.client-id=abcd
spring.security.oauth2.client.registration.google.client-secret=password
29.3.2 资源服务器
如果您的 Classpath 上有spring-security-oauth2-resource-server
,则只要指定了 JWK Set URI 或 OIDC Issuer URI,Spring Boot 就可以设置 OAuth2 资源服务器,如以下示例所示:
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/
相同的属性适用于 servlet 和反应式应用程序。
另外,您可以为 Servlet 应用程序定义自己的JwtDecoder
bean 或为 Reactive 应用程序定义ReactiveJwtDecoder
。
29.3.3 授权服务器
当前,Spring Security 不提供对实现 OAuth 2.0 授权服务器的支持。但是,此功能可从Spring Security OAuth项目获得,最终将被 Spring Security 完全取代。在此之前,您可以使用spring-security-oauth2-autoconfigure
模块轻松设置 OAuth 2.0 授权服务器;有关说明,请参见其documentation。
29.4 Actuator 安全性
为了安全起见,默认禁用除/health
和/info
以外的所有 Actuator。 management.endpoints.web.exposure.include
属性可用于启用 Actuator。
如果 Spring Security 位于 Classpath 上,并且不存在其他 WebSecurityConfigurerAdapter,则通过 Spring Boot 自动配置来保护/health
和/info
以外的所有 Actuator。如果您定义一个自定义WebSecurityConfigurerAdapter
,Spring Boot 自动配置将退出,您将完全控制 Actuator 访问规则。
Note
在设置management.endpoints.web.exposure.include
之前,请确保裸露的 Actuator 不包含敏感信息和/或通过将它们放置在防火墙后面或通过诸如 Spring Security 之类的东西进行保护。
29.4.1 跨站点请求伪造保护
由于 Spring Boot 依赖于 Spring Security 的默认值,因此默认情况下 CSRF 保护是打开的。这意味着在使用默认安全性配置时,需要POST
的 Actuator 端点(关机和 Logger 端点),PUT
或DELETE
将收到 403 禁止错误。
Note
我们建议仅在创建非浏览器 Client 端使用的服务时完全禁用 CSRF 保护。
有关 CSRF 保护的其他信息可以在Spring Security 参考指南中找到。