Spring Security

如果类路径中包含Spring Security,则 Web 应用程序将默认受到保护。 这包括保护 Spring Boot 的 /error 端点。 Spring Boot 依赖 Spring Security 的内容协商策略来确定是使用 httpBasic 还是 formLogin。 若要在 Web 应用程序中添加方法级安全性,您还可以添加带有所需配置的 @EnableMethodSecurity。 更多详细信息请参阅Spring Security 参考指南spring-doc.cadn.net.cn

默认的 UserDetailsService 包含一个用户。 用户名为 user,密码是随机生成的,并在应用程序启动时以 WARN 级别打印,如下例所示:spring-doc.cadn.net.cn

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.security.autoconfigure 类别设置为记录 WARN 级别的日志消息。 否则,默认密码将不会被打印出来。

您可以通过提供 spring.security.user.namespring.security.user.password 来更改用户名和密码。spring-doc.cadn.net.cn

Web 应用程序默认提供的基本功能包括:spring-doc.cadn.net.cn

您可以通过为其添加一个 Bean 来提供不同的 AuthenticationEventPublisherspring-doc.cadn.net.cn

MVC 安全性

默认安全配置在 SecurityAutoConfigurationUserDetailsServiceAutoConfiguration 中实现。 SecurityAutoConfiguration 导入 SpringBootWebSecurityConfiguration 以支持 Web 安全,以及导入 UserDetailsServiceAutoConfiguration 以支持身份认证。spring-doc.cadn.net.cn

若要完全禁用默认的 Web 应用程序安全配置(包括执行器(Actuator)安全配置),或要整合多个 Spring Security 组件(例如 OAuth2 客户端和资源服务器),请添加一个类型为 SecurityFilterChain 的 Bean(此举不会禁用 UserDetailsService 配置)。 如还需禁用 UserDetailsService 配置,请添加一个类型为 UserDetailsServiceAuthenticationProviderAuthenticationManager 的 Bean。spring-doc.cadn.net.cn

当类路径中存在以下任一 Spring Security 模块时,UserDetailsService 的自动配置也会自动退避:spring-doc.cadn.net.cn

若要在使用这些依赖项中的一个或多个的同时使用 UserDetailsService,请自行定义 InMemoryUserDetailsManager Bean。spring-doc.cadn.net.cn

可通过添加自定义的 SecurityFilterChain Bean 来覆盖访问规则。 Spring Boot 提供了便捷方法,可用于覆盖执行器(actuator)端点和静态资源的访问规则。 EndpointRequest 可用于创建基于 management.endpoints.web.base-path 属性的 RequestMatcherPathRequest 可用于为常用位置中的资源创建 RequestMatcherspring-doc.cadn.net.cn

WebFlux 安全性

与 Spring MVC 应用程序类似,您可以通过添加 spring-boot-starter-security 依赖项来保护您的 WebFlux 应用程序。 默认安全配置在 ReactiveWebSecurityAutoConfigurationReactiveUserDetailsServiceAutoConfiguration 中实现。 除响应式 Web 应用程序外,后者在使用 RSocket 时也会自动配置。 ReactiveWebSecurityAutoConfiguration 为 Web 安全导入 WebFluxSecurityConfigurationReactiveUserDetailsServiceAutoConfiguration 自动配置身份验证。spring-doc.cadn.net.cn

若要完全禁用默认的 Web 应用程序安全配置(包括执行器(Actuator)安全配置),请添加一个类型为 WebFilterChainProxy 的 Bean(此举不会禁用 ReactiveUserDetailsService 配置)。 若还要禁用 ReactiveUserDetailsService 配置,请添加一个类型为 ReactiveUserDetailsServiceReactiveAuthenticationManager 的 Bean。spring-doc.cadn.net.cn

当类路径中存在以下任意 Spring Security 模块时,自动配置也将退避:spring-doc.cadn.net.cn

若要在使用这些依赖项中的一个或多个的同时使用 ReactiveUserDetailsService,请自行定义 MapReactiveUserDetailsService Bean。spring-doc.cadn.net.cn

可通过添加自定义的 SecurityWebFilterChain Bean 来配置访问规则,以及多个 Spring Security 组件(例如 OAuth 2 客户端和资源服务器)的使用方式。 Spring Boot 提供了便捷方法,可用于重写执行器(actuator)端点和静态资源的访问规则。 EndpointRequest 可用于创建一个基于 management.endpoints.web.base-path 属性的 ServerWebExchangeMatcherspring-doc.cadn.net.cn

PathRequest 可用于为常用位置中的资源创建 ServerWebExchangeMatcherspring-doc.cadn.net.cn

例如,您可以通过添加如下内容来自定义安全配置:spring-doc.cadn.net.cn

import org.springframework.boot.security.autoconfigure.web.reactive.PathRequest;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.web.server.ServerHttpSecurity;
import org.springframework.security.web.server.SecurityWebFilterChain;

import static org.springframework.security.config.Customizer.withDefaults;

@Configuration(proxyBeanMethods = false)
public class MyWebFluxSecurityConfiguration {

	@Bean
	public SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) {
		http.authorizeExchange((exchange) -> {
			exchange.matchers(PathRequest.toStaticResources().atCommonLocations()).permitAll();
			exchange.pathMatchers("/foo", "/bar").authenticated();
		});
		http.formLogin(withDefaults());
		return http.build();
	}

}
import org.springframework.boot.security.autoconfigure.web.reactive.PathRequest
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
import org.springframework.security.config.Customizer.withDefaults
import org.springframework.security.config.web.server.ServerHttpSecurity
import org.springframework.security.web.server.SecurityWebFilterChain

@Configuration(proxyBeanMethods = false)
class MyWebFluxSecurityConfiguration {

	@Bean
	fun springSecurityFilterChain(http: ServerHttpSecurity): SecurityWebFilterChain {
		http.authorizeExchange { spec ->
			spec.matchers(PathRequest.toStaticResources().atCommonLocations()).permitAll()
			spec.pathMatchers("/foo", "/bar").authenticated()
		}
		http.formLogin(withDefaults())
		return http.build()
	}

}

OAuth2

OAuth2 是一个被 Spring 支持的、广泛使用的授权框架。spring-doc.cadn.net.cn

客户端

如果您的类路径中包含 spring-security-oauth2-client,则可以利用一些自动配置来设置 OAuth2 / OpenID Connect 客户端。 此配置会使用 OAuth2ClientProperties 下的属性。 相同的属性同时适用于 Servlet 应用和响应式(reactive)应用。spring-doc.cadn.net.cn

每个注册项都必须指定一个 OAuth 2 提供商。 当设置了该属性时,spring.security.oauth2.client.registration.<registration-id>.provider 属性的值将用于指定该注册项的提供商。 如果未设置 provider 属性,则使用该注册项的 ID 作为替代。 以下示例展示了这两种方法:spring-doc.cadn.net.cn

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=example
spring.security.oauth2.client.registration.example.client-id=abcd
spring.security.oauth2.client.registration.example.client-secret=password
spring:
  security:
    oauth2:
      client:
        registration:
          my-client:
            client-id: "abcd"
            client-secret: "password"
            provider: "example"
          example:
            client-id: "abcd"
            client-secret: "password"

注册项 my-clientexample 均将使用 ID 为 example 的提供者。 前者会因 spring.security.oauth2.client.registration.my-client.provider 属性的值而使用该提供者。 后者则因其 ID 为 example,且该注册项未配置 provider 属性,从而使用该提供者。spring-doc.cadn.net.cn

指定的提供程序既可以是通过 spring.security.oauth2.client.provider.<provider-id>.* 属性配置的提供程序的引用,也可以是已知常用提供程序之一。spring-doc.cadn.net.cn

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

spring.security.oauth2.client.registration.my-login-client.client-id=abcd
spring.security.oauth2.client.registration.my-login-client.client-secret=password
spring.security.oauth2.client.registration.my-login-client.client-name=Client for OpenID Connect
spring.security.oauth2.client.registration.my-login-client.provider=my-oauth-provider
spring.security.oauth2.client.registration.my-login-client.scope=openid,profile,email,phone,address
spring.security.oauth2.client.registration.my-login-client.redirect-uri={baseUrl}/login/oauth2/code/{registrationId}
spring.security.oauth2.client.registration.my-login-client.client-authentication-method=client_secret_basic
spring.security.oauth2.client.registration.my-login-client.authorization-grant-type=authorization_code
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={baseUrl}/authorized/user
spring.security.oauth2.client.registration.my-client-1.client-authentication-method=client_secret_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={baseUrl}/authorized/email
spring.security.oauth2.client.registration.my-client-2.client-authentication-method=client_secret_basic
spring.security.oauth2.client.registration.my-client-2.authorization-grant-type=authorization_code
spring.security.oauth2.client.provider.my-oauth-provider.authorization-uri=https://my-auth-server.com/oauth2/authorize
spring.security.oauth2.client.provider.my-oauth-provider.token-uri=https://my-auth-server.com/oauth2/token
spring.security.oauth2.client.provider.my-oauth-provider.user-info-uri=https://my-auth-server.com/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=https://my-auth-server.com/oauth2/jwks
spring.security.oauth2.client.provider.my-oauth-provider.user-name-attribute=name
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"

在此示例中,共有三个注册项。 按声明顺序,它们的 ID 分别为 my-login-clientmy-client-1my-client-2。 此外,还有一个提供者,其 ID 为 my-oauth-providerspring-doc.cadn.net.cn

对于支持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 提供商:spring-doc.cadn.net.cn

spring.security.oauth2.client.provider.oidc-provider.issuer-uri=https://dev-123456.oktapreview.com/oauth2/default/
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-doc.cadn.net.cn

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.web.SecurityFilterChain;

@Configuration(proxyBeanMethods = false)
@EnableWebSecurity
public class MyOAuthClientConfiguration {

	@Bean
	public SecurityFilterChain securityFilterChain(HttpSecurity http) {
		http
			.authorizeHttpRequests((requests) -> requests
				.anyRequest().authenticated()
			)
			.oauth2Login((login) -> login
				.redirectionEndpoint((endpoint) -> endpoint
					.baseUri("/login/oauth2/callback/*")
				)
			);
		return http.build();
	}

}
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
import org.springframework.security.config.annotation.web.builders.HttpSecurity
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity
import org.springframework.security.config.annotation.web.invoke
import org.springframework.security.web.SecurityFilterChain

@Configuration(proxyBeanMethods = false)
@EnableWebSecurity
open class MyOAuthClientConfiguration {

	@Bean
	open fun securityFilterChain(http: HttpSecurity): SecurityFilterChain {
		http {
			authorizeHttpRequests {
				authorize(anyRequest, authenticated)
			}
			oauth2Login {
				redirectionEndpoint {
					baseUri = "/login/oauth2/callback/*"
				}
			}
		}
		return http.build()
	}

}
Spring Boot 会自动配置一个 InMemoryOAuth2AuthorizedClientService,Spring Security 使用该组件来管理客户端注册。 InMemoryOAuth2AuthorizedClientService 的功能有限,我们建议仅在开发环境中使用它。 对于生产环境,请考虑使用 JdbcOAuth2AuthorizedClientService,或自行实现 OAuth2AuthorizedClientService

常见提供商的 OAuth2 客户端注册

对于常见的 OAuth2 和 OpenID 提供商(Google、GitHub、Facebook 和 Okta),我们提供了一组默认的提供商配置。 这些常见提供商的 ID 分别为 googlegithubfacebookoktaspring-doc.cadn.net.cn

如果您无需自定义这些提供程序,请将注册项的 provider 属性设置为某个常用提供程序的 ID。 或者,您也可以 使用与提供程序 ID 相匹配的注册 ID。 以下示例中的两种配置均使用了常用的 google 提供程序:spring-doc.cadn.net.cn

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
spring:
  security:
    oauth2:
      client:
        registration:
          my-client:
            client-id: "abcd"
            client-secret: "password"
            provider: "google"
          google:
            client-id: "abcd"
            client-secret: "password"

资源服务器

如果您的类路径中包含 spring-security-oauth2-resource-server,Spring Boot 可以配置 OAuth2 资源服务器。 对于 JWT 配置,需要指定 JWK Set URI 或 OIDC 发行者(Issuer)URI,如下例所示:spring-doc.cadn.net.cn

spring.security.oauth2.resourceserver.jwt.jwk-set-uri=https://example.com/oauth2/default/v1/keys
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/
spring:
  security:
    oauth2:
      resourceserver:
        jwt:
          issuer-uri: "https://dev-123456.oktapreview.com/oauth2/default/"
如果授权服务器不支持 JWK Set URI,则可以使用用于验证 JWT 签名的公钥来配置资源服务器。 这可以通过 spring.security.oauth2.resourceserver.jwt.public-key-location 属性实现,其值需指向一个包含 PEM 编码 x509 格式公钥的文件。

spring.security.oauth2.resourceserver.jwt.audiences 属性可用于指定 JWT 中 aud 声明的预期值。 例如,要求 JWT 必须包含值为 my-audienceaud 声明:spring-doc.cadn.net.cn

spring.security.oauth2.resourceserver.jwt.audiences[0]=my-audience
spring:
  security:
    oauth2:
      resourceserver:
        jwt:
          audiences:
            - "my-audience"

相同的属性同时适用于 Servlet 应用程序和响应式应用程序。 或者,您可以为 Servlet 应用程序定义自己的 JwtDecoder Bean,或为响应式应用程序定义 ReactiveJwtDecoderspring-doc.cadn.net.cn

在使用不透明Tokens(opaque tokens)而非 JWT 的情况下,您可以通过以下属性配置,借助Tokens内省(introspection)来验证Tokens:spring-doc.cadn.net.cn

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

同样,这些属性既适用于 Servlet 应用程序,也适用于响应式应用程序。 或者,您可以为 Servlet 应用程序自定义一个 OpaqueTokenIntrospector Bean,或为响应式应用程序自定义一个 ReactiveOpaqueTokenIntrospectorspring-doc.cadn.net.cn

授权服务器

如果您的类路径中包含 spring-security-oauth2-authorization-server,则可以利用一些自动配置来设置基于 Servlet 的 OAuth2 授权服务器。spring-doc.cadn.net.cn

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

spring.security.oauth2.authorizationserver.client.my-client-1.registration.client-id=abcd
spring.security.oauth2.authorizationserver.client.my-client-1.registration.client-secret={noop}secret1
spring.security.oauth2.authorizationserver.client.my-client-1.registration.client-authentication-methods[0]=client_secret_basic
spring.security.oauth2.authorizationserver.client.my-client-1.registration.authorization-grant-types[0]=authorization_code
spring.security.oauth2.authorizationserver.client.my-client-1.registration.authorization-grant-types[1]=refresh_token
spring.security.oauth2.authorizationserver.client.my-client-1.registration.redirect-uris[0]=https://my-client-1.com/login/oauth2/code/abcd
spring.security.oauth2.authorizationserver.client.my-client-1.registration.redirect-uris[1]=https://my-client-1.com/authorized
spring.security.oauth2.authorizationserver.client.my-client-1.registration.scopes[0]=openid
spring.security.oauth2.authorizationserver.client.my-client-1.registration.scopes[1]=profile
spring.security.oauth2.authorizationserver.client.my-client-1.registration.scopes[2]=email
spring.security.oauth2.authorizationserver.client.my-client-1.registration.scopes[3]=phone
spring.security.oauth2.authorizationserver.client.my-client-1.registration.scopes[4]=address
spring.security.oauth2.authorizationserver.client.my-client-1.require-authorization-consent=true
spring.security.oauth2.authorizationserver.client.my-client-1.token.authorization-code-time-to-live=5m
spring.security.oauth2.authorizationserver.client.my-client-1.token.access-token-time-to-live=10m
spring.security.oauth2.authorizationserver.client.my-client-1.token.access-token-format=reference
spring.security.oauth2.authorizationserver.client.my-client-1.token.reuse-refresh-tokens=false
spring.security.oauth2.authorizationserver.client.my-client-1.token.refresh-token-time-to-live=30m
spring.security.oauth2.authorizationserver.client.my-client-2.registration.client-id=efgh
spring.security.oauth2.authorizationserver.client.my-client-2.registration.client-secret={noop}secret2
spring.security.oauth2.authorizationserver.client.my-client-2.registration.client-authentication-methods[0]=client_secret_jwt
spring.security.oauth2.authorizationserver.client.my-client-2.registration.authorization-grant-types[0]=client_credentials
spring.security.oauth2.authorizationserver.client.my-client-2.registration.scopes[0]=user.read
spring.security.oauth2.authorizationserver.client.my-client-2.registration.scopes[1]=user.write
spring.security.oauth2.authorizationserver.client.my-client-2.jwk-set-uri=https://my-client-2.com/jwks
spring.security.oauth2.authorizationserver.client.my-client-2.token-endpoint-authentication-signing-algorithm=RS256
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
            token:
              authorization-code-time-to-live: 5m
              access-token-time-to-live: 10m
              access-token-format: "reference"
              reuse-refresh-tokens: false
              refresh-token-time-to-live: 30m
          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() 创建。

Spring Boot 为 Spring Authorization Server 提供的自动配置旨在帮助您快速上手。 大多数应用程序都需要进行自定义,并希望定义若干 Bean 来覆盖自动配置。spring-doc.cadn.net.cn

以下组件可以定义为 Bean,以覆盖 Spring Authorization Server 特定的自动配置:spring-doc.cadn.net.cn

Spring Boot 会自动配置一个 InMemoryRegisteredClientRepository,Spring Authorization Server 使用该组件来管理已注册的客户端。 InMemoryRegisteredClientRepository 的功能有限,我们建议仅在开发环境中使用它。 对于生产环境,请考虑使用 JdbcRegisteredClientRepository,或自行实现 RegisteredClientRepository

有关更多信息,请参阅Spring Security参考文档中的入门章节。spring-doc.cadn.net.cn

SAML 2.0

构建配置

SAML 2.0 支持基于 OpenSAML 库构建,该库需要额外的仓库配置spring-doc.cadn.net.cn

使用 Maven

使用 Maven 时,您需要在 POM 文件中额外添加一个 repository 元素,如下所示:spring-doc.cadn.net.cn

<repositories>
	<repository>
		<id>shibboleth-releases</id>
		<name>Shibboleth Releases Repository</name>
		<url>https://build.shibboleth.net/maven/releases</url>
		<snapshots>
			<enabled>false</enabled>
		</snapshots>
	</repository>
</repositories>

使用 Gradle

使用 Gradle 时,应在构建脚本中添加一个 repository 元素:spring-doc.cadn.net.cn

repositories {
    maven { url "https://build.shibboleth.net/maven/releases" }
}

依赖方

如果您的类路径中包含 spring-security-saml2-service-provider,则可以利用一些自动配置来设置 SAML 2.0 依赖方(Relying Party)。 此配置会使用 Saml2RelyingPartyProperties 下的属性。spring-doc.cadn.net.cn

依赖方注册表示身份提供者(IDP)与服务提供者(SP)之间的一组配对配置。 您可以在 spring.security.saml2.relyingparty 前缀下注册多个依赖方,如下例所示:spring-doc.cadn.net.cn

spring.security.saml2.relyingparty.registration.my-relying-party1.signing.credentials[0].private-key-location=path-to-private-key
spring.security.saml2.relyingparty.registration.my-relying-party1.signing.credentials[0].certificate-location=path-to-certificate
spring.security.saml2.relyingparty.registration.my-relying-party1.decryption.credentials[0].private-key-location=path-to-private-key
spring.security.saml2.relyingparty.registration.my-relying-party1.decryption.credentials[0].certificate-location=path-to-certificate
spring.security.saml2.relyingparty.registration.my-relying-party1.singlelogout.url=https://myapp/logout/saml2/slo
spring.security.saml2.relyingparty.registration.my-relying-party1.singlelogout.response-url=https://remoteidp2.slo.url
spring.security.saml2.relyingparty.registration.my-relying-party1.singlelogout.binding=POST
spring.security.saml2.relyingparty.registration.my-relying-party1.assertingparty.verification.credentials[0].certificate-location=path-to-verification-cert
spring.security.saml2.relyingparty.registration.my-relying-party1.assertingparty.entity-id=remote-idp-entity-id1
spring.security.saml2.relyingparty.registration.my-relying-party1.assertingparty.sso-url=https://remoteidp1.sso.url
spring.security.saml2.relyingparty.registration.my-relying-party2.signing.credentials[0].private-key-location=path-to-private-key
spring.security.saml2.relyingparty.registration.my-relying-party2.signing.credentials[0].certificate-location=path-to-certificate
spring.security.saml2.relyingparty.registration.my-relying-party2.decryption.credentials[0].private-key-location=path-to-private-key
spring.security.saml2.relyingparty.registration.my-relying-party2.decryption.credentials[0].certificate-location=path-to-certificate
spring.security.saml2.relyingparty.registration.my-relying-party2.assertingparty.verification.credentials[0].certificate-location=path-to-other-verification-cert
spring.security.saml2.relyingparty.registration.my-relying-party2.assertingparty.entity-id=remote-idp-entity-id2
spring.security.saml2.relyingparty.registration.my-relying-party2.assertingparty.sso-url=https://remoteidp2.sso.url
spring.security.saml2.relyingparty.registration.my-relying-party2.assertingparty.singlelogout.url=https://remoteidp2.slo.url
spring.security.saml2.relyingparty.registration.my-relying-party2.assertingparty.singlelogout.response-url=https://myapp/logout/saml2/slo
spring.security.saml2.relyingparty.registration.my-relying-party2.assertingparty.singlelogout.binding=POST
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。 如果您希望自定义服务提供方(SP)发起的注销请求所发送到的 url,或自定义服务提供方(SP)发送注销响应所使用的 response-url,以采用不同的匹配模式,则需要提供相应配置来处理该自定义模式。 例如,在 Servlet 应用程序中,您可以添加自己的 SecurityFilterChain,其结构类似于以下示例:spring-doc.cadn.net.cn

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.web.SecurityFilterChain;

import static org.springframework.security.config.Customizer.withDefaults;

@Configuration(proxyBeanMethods = false)
public class MySamlRelyingPartyConfiguration {

	@Bean
	public SecurityFilterChain securityFilterChain(HttpSecurity http) {
		http.authorizeHttpRequests((requests) -> requests.anyRequest().authenticated());
		http.saml2Login(withDefaults());
		http.saml2Logout((saml2) -> saml2.logoutRequest((request) -> request.logoutUrl("/SLOService.saml2"))
			.logoutResponse((response) -> response.logoutUrl("/SLOService.saml2")));
		return http.build();
	}

}