SAML 2.0 迁移

期望<saml2:LogoutResponse>何时<saml2:LogoutRequest>验证失败

SAML 身份提供者期望服务提供者在无法处理 <saml2:LogoutResponse> 时返回一个错误的 <saml2:LogoutRequest>spring-doc.cadn.net.cn

早期版本的 Spring Security 在某些情况下会返回 401 状态码,从而中断了各个依赖方(relying party)发出的注销请求与响应链。spring-doc.cadn.net.cn

在 Spring Security 7 中,此行为已修复,您无需进行任何操作。spring-doc.cadn.net.cn

然而,如果这给您带来问题,您可以通过发布一个 Saml2LogoutRequestResolver 来恢复旧的行为,该解析器在需要错误的 null 时返回 <saml2:LogoutRequest>。 您可以创建如下所示的委托:spring-doc.cadn.net.cn

@Bean
Saml2LogoutResponseResolver logoutResponseResolver(RelyingPartyRegistrationRepository registrations) {
    OpenSaml5LogoutResponseResolver delegate = new OpenSaml5LogoutResponseResolver(registrations);
    return new Saml2LogoutResponseResolver() {
        @Override
        public void resolve(HttpServletRequest request, Authentication authentication) {
            delegate.resolve(request, authentication);
        }

        @Override
        public void resolve(HttpServletRequest request, Authentication authentication, Saml2AuthenticationException error) {
            return null;
        }
    };
}
@Bean
fun logoutResponseResolver(registrations: RelyingPartyRegistrationRepository?): Saml2LogoutResponseResolver {
    val delegate = OpenSaml5LogoutResponseResolver(registrations)
    return object : Saml2LogoutResponseResolver() {
        override fun resolve(request: HttpServletRequest?, authentication: Authentication?) {
            delegate.resolve(request, authentication)
        }

        override fun resolve(request: HttpServletRequest?, authentication: Authentication?, error: Saml2AuthenticationException?) {
            return null
        }
    }
}

收藏Saml2ResponseAuthenticationAccessor完成Saml2AuthenticatedPrincipal

Spring Security 7 将 <saml2:Assertion> 的详细信息与主体(principal)分离。 这使得 Spring Security 能够检索所需的断言详细信息以执行单点登出(Single Logout)。spring-doc.cadn.net.cn

这已弃用 Saml2AuthenticatedPrincipal。 您不再需要实现它即可使用 Saml2Authenticationspring-doc.cadn.net.cn

相反,该凭据实现了 Saml2ResponseAssertionAccessor,Spring Security 7 在根据身份验证确定适当操作时优先使用该接口。spring-doc.cadn.net.cn

当你使用默认配置时,此更改会自动为你完成。spring-doc.cadn.net.cn

如果在升级时这给您带来麻烦,您可以发布一个自定义的 ResponseAuhenticationConverter,使其返回 Saml2Authentication,而不是像下面这样返回 Saml2AssertionAuthenticationspring-doc.cadn.net.cn

@Bean
OpenSaml5AuthenticationProvider authenticationProvider() {
	OpenSaml5AuthenticationProvider authenticationProvider =
		new OpenSaml5AuthenticationProvider();
	ResponseAuthenticationConverter defaults = new ResponseAuthenticationConverter();
	authenticationProvider.setResponseAuthenticationConverter(
		defaults.andThen((authentication) -> new Saml2Authentication(
			authentication.getPrincipal(),
			authentication.getSaml2Response(),
			authentication.getAuthorities())));
	return authenticationProvider;
}
@Bean
fun authenticationProvider(): OpenSaml5AuthenticationProvider {
	val authenticationProvider = OpenSaml5AuthenticationProvider()
	val defaults = ResponseAuthenticationConverter()
	authenticationProvider.setResponseAuthenticationConverter(
		defaults.andThen { authentication ->
			Saml2Authentication(authentication.getPrincipal(),
				authentication.getSaml2Response(),
				authentication.getAuthorities())
		})
	return authenticationProvider
}

如果你正在自行构建一个 Saml2Authentication 实例,请考虑改用 Saml2AssertionAuthentication,以获得与当前默认实现相同的益处。spring-doc.cadn.net.cn

请勿处理<saml2:Response>使用 GET 请求Saml2AuthenticationTokenConverter

Spring Security 不支持通过 GET 方法处理 <saml2:Response> 负载,因为 SAML 2.0 规范不支持此方式。spring-doc.cadn.net.cn

为了更好地符合这一要求,从 Spring Security 8 开始,Saml2AuthenticationTokenConverterOpenSaml5AuthenticationTokenConverter 默认将不再处理 GET 请求。 为应对这一变更,现已提供 shouldConvertGetRequests 属性。 要使用该属性,请按如下方式发布您自己的转换器:spring-doc.cadn.net.cn

@Bean
OpenSaml5AuthenticationTokenConverter authenticationConverter(RelyingPartyRegistrationRepository registrations) {
	OpenSaml5AuthenticationTokenConverter authenticationConverter = new OpenSaml5AuthenticationTokenConverter(registrations);
	authenticationConverter.setShouldConvertGetRequests(false);
	return authenticationConverter;
}
@Bean
fun authenticationConverter(val registrations: RelyingPartyRegistrationRepository): Saml2AuthenticationTokenConverter {
	val authenticationConverter = Saml2AuthenticationTokenConverter(registrations)
	authenticationConverter.setShouldConvertGetRequests(false)
	return authenticationConverter
}

如果你必须继续使用 Saml2AuthenticationTokenConverterOpenSaml5AuthenticationTokenConverter 来处理 GET 请求,可以调用 setShouldConvertGetRequests 方法并将其设置为 true.spring-doc.cadn.net.cn