升级到spring-security-saml2-service-provider 6.4后如何访问加密断言
解答
1. 是否为有意的行为变更?
是的,这是Spring Security 6.4版本中有意引入的行为变更。该变更旨在对齐OpenSAML的原生处理逻辑:完成断言解密后,从响应对象中移除已解密的加密断言,避免同一断言同时以加密、解密两种形式存在于响应中,消除冗余并减少逻辑混淆的可能。
2. 访问加密断言的正确方式
如果业务逻辑必须访问原始加密断言,官方推荐在解密流程执行前保存加密断言的副本,而非在解密完成后从响应对象中获取。可以通过自定义OpenSaml4AuthenticationProvider的解密配置器实现:
var authProvider = new OpenSaml4AuthenticationProvider(); // 自定义解密配置,提前保存加密断言 authProvider.setDecryptionConfigurer(configurer -> { configurer.setResponseDecrypter(response -> { // 保存原始加密断言的副本 List<EncryptedAssertion> originalEncryptedAssertions = new ArrayList<>(response.getEncryptedAssertions()); // 将副本存入请求上下文,供后续验证器读取 RequestContextHolder.getRequestAttributes().setAttribute( "ORIGINAL_ENCRYPTED_ASSERTIONS", originalEncryptedAssertions, RequestAttributes.SCOPE_REQUEST ); // 执行默认的解密逻辑 configurer.getDefaultResponseDecrypter().decrypt(response); }); }); // 配置自定义响应验证器 authProvider.setResponseValidator(responseToken -> { // 从请求上下文获取提前保存的加密断言 List<EncryptedAssertion> encryptedAssertions = (List<EncryptedAssertion>) RequestContextHolder.getRequestAttributes().getAttribute( "ORIGINAL_ENCRYPTED_ASSERTIONS", RequestAttributes.SCOPE_REQUEST ); // 在这里执行你的业务逻辑 // ... return Saml2ResponseValidatorResult.success(); });
这种方式无需重复解析响应或复制大量解密逻辑,既符合官方设计意图,也能满足业务对原始加密断言的访问需求。
内容的提问来源于stack exchange,提问作者Kim
相关产品推荐
相关产品推荐

