4.8 安全

优质
小牛编辑
126浏览
2023-12-01

如果Spring Security位于类路径上,则默认情况下Web应用程序是安全的。 Spring Boot依赖于Spring Security的内容协商策略来确定是使用httpBasic还是formLogin。 要向Web应用程序添加方法级安全性,还可以使用所需设置添加@EnableGlobalMethodSecurity。 其他信息可以在Spring Security Reference Guide中找到。

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

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

如果您对日志记录配置进行微调,请确保将org.springframework.boot.autoconfigure.security类别设置为记录INFO级别的消息。 否则,不会打印默认密码。

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

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

  • UserDetailsService(或WebFlux应用程序中的ReactiveUserDetailsService)具有内存存储的bean和具有生成密码的单个用户(有关用户属性,请参阅SecurityProperties.User)。
  • 基于表单的登录或HTTP基本安全性(取决于Content-Type)用于整个应用程序(如果执行器在类路径上,则包括执行器端点)。
  • 用于发布身份验证事件的DefaultAuthenticationEventPublisher。

您可以通过为其添加bean来提供不同的AuthenticationEventPublisher。

4.8.1 MVC安全

默认安全配置在SecurityAutoConfiguration和UserDetailsServiceAutoConfiguration中实现。 SecurityAutoConfiguration导入用于Web安全的SpringBootWebSecurityConfiguration和UserDetailsServiceAutoConfiguration配置身份验证,这也适用于非Web应用程序。 要完全关闭默认Web应用程序安全性配置,可以添加WebSecurityConfigurerAdapter类型的bean(这样做不会禁用UserDetailsService配置或Actuator的安全性)。

要关闭UserDetailsService配置,您可以添加UserDetailsService,AuthenticationProvider或AuthenticationManager类型的bean。 Spring Boot示例中有几个安全的应用程序可以帮助您开始使用常见的用例。

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

4.8.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提供了便捷方法,可用于覆盖执行器端点和静态资源的访问规则。 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();
}

4.8.3 OAuth2

OAuth2是Spring支持的一种广泛使用的授权框架。

4.8.3.1 客户端

如果在类路径中有spring-security-oauth2-client,则可以利用一些自动配置来轻松设置OAuth2 / Open ID Connect客户端。 此配置使用OAuth2ClientProperties下的属性。 相同的属性适用于servlet和反应式应用程序。

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

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提供商配置请求。 结果预计将是OpenID提供程序配置响应。 以下示例显示如何使用issuer-uri配置OpenID Connect Provider:

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");
	}
}

1)OAuth2客户端注册常见提供商

对于常见的OAuth2和OpenID提供商,包括Google,Github,Facebook和Okta,我们提供了一组提供商默认设置(分别为google,github,facebook和okta)。

如果不需要自定义这些提供程序,则可以将Provider属性设置为需要推断默认值的提供程序属性。此外,如果客户端注册的键与默认支持的提供程序匹配,SpringBoot也会推断这一点。

换句话说,以下示例中的两个配置使用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

4.8.3.2 资源服务器

如果在类路径上有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,或者为响应式应用程序定义ReactiveJwtDecoder。

4.8.3.3 授权服务器

目前,Spring Security不支持实施OAuth 2.0授权服务器。 但是,此功能可从Spring Security OAuth项目获得,该项目最终将完全被Spring Security取代。 在此之前,您可以使用spring-security-oauth2-autoconfigure模块轻松设置OAuth 2.0授权服务器; 请参阅其文档以获取说明

4.8.4 执行器安全

出于安全考虑,默认情况下禁用除/health和/info之外的所有执行器。 management.endpoints.web.exposure.include属性可用于启用执行器。

如果Spring Security位于类路径上且没有其他WebSecurityConfigurerAdapter,则除了/health和/info之外的所有执行程序都由Spring Boot自动配置保护。 如果您定义了自定义WebSecurityConfigurerAdapter,则Spring Boot自动配置将退回,您将完全控制执行器访问规则。

在设置management.endpoints.web.exposure.include之前,请确保暴露的执行器不包含敏感信息和(或)通过将它们放在防火墙后面或通过Spring Security之类的东西来保护。

4.8.4.1 伪造跨域请求保护

由于Spring Boot依赖于Spring Security的默认值,因此默认情况下会启用CSRF保护。 这意味着当使用默认安全配置时,需要POST(关闭和记录器端点),PUT或DELETE的执行器端点将获得403禁止错误。

我们建议仅在创建非浏览器客户端使用的服务时才完全禁用CSRF保护。