我们有一个简单的Saml 2-Logout,用户在IdP中注销,但最后一步,允许我们终止应用程序中会话的回调导致Http状态:未找到。这是我们的RelyingPartyRegistrationRepository和其他与saml 2相关的配置
import org.opensaml.xmlsec.signature.support.SignatureConstants;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
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.configuration.WebSecurityCustomizer;
import org.springframework.security.saml2.core.Saml2X509Credential;
import org.springframework.security.saml2.provider.service.registration.InMemoryRelyingPartyRegistrationRepository;
import org.springframework.security.saml2.provider.service.registration.RelyingPartyRegistration;
import org.springframework.security.saml2.provider.service.registration.RelyingPartyRegistrationRepository;
import org.springframework.security.saml2.provider.service.registration.Saml2MessageBinding;
import org.springframework.security.web.SecurityFilterChain;
import java.security.PrivateKey;
import java.security.cert.X509Certificate;
import static org.springframework.security.config.Customizer.withDefaults;
@Profile("!local")
@EnableWebSecurity
@Configuration
public class Saml2WebSecurityConfig {
private static final String LOGOUT_CALLBACK_URL = "/logout/saml2/slo";
private final EIAMConfigProperties eiamConfigProperties;
public Saml2WebSecurityConfig(EIAMConfigProperties eiamConfigProperties) {
this.eiamConfigProperties = eiamConfigProperties;
}
@Bean
public RelyingPartyRegistrationRepository relyingPartyRegistrationRepository() throws Exception {
final X509Certificate[] cert = ...;
final PrivateKey privateKey = ...;
final X509Certificate[] verificationCertificate = ...;
Saml2X509Credential signingCredential = Saml2X509Credential.signing(privateKey, cert[0]);
Saml2X509Credential verificationCredential = Saml2X509Credential.verification(verificationCertificate[0]);
RelyingPartyRegistration registration = RelyingPartyRegistration
.withRegistrationId(eiamConfigProperties.getRegistrationId())
.entityId(eiamConfigProperties.getEntity())
.signingX509Credentials(c -> c.add(signingCredential))
.assertingPartyDetails(party -> party.entityId(eiamConfigProperties.getAssertionId())
.singleSignOnServiceLocation(eiamConfigProperties.getSingleSignOnServiceLocation())
.singleSignOnServiceBinding(Saml2MessageBinding.POST)
.singleLogoutServiceLocation(eiamConfigProperties.getSingleLogoutServiceLocation())
.singleLogoutServiceBinding(Saml2MessageBinding.POST)
.wantAuthnRequestsSigned(true)
.signingAlgorithms(sign -> sign.add(SignatureConstants.ALGO_ID_SIGNATURE_RSA_SHA256))
.verificationX509Credentials(c -> c.add(verificationCredential))
)
.build();
return new InMemoryRelyingPartyRegistrationRepository(registration);
}
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http.authorizeHttpRequests(authorize -> authorize
.anyRequest().authenticated())
.saml2Login(withDefaults())
.saml2Logout((saml2) -> saml2
.logoutRequest((request) -> request.logoutUrl(LOGOUT_CALLBACK_URL))
.logoutResponse((response) -> response.logoutUrl(LOGOUT_CALLBACK_URL))
);
http.csrf().disable();
return http.build();
}
@Bean
public WebSecurityCustomizer webSecurityCustomizer() {
return web -> web.ignoring().requestMatchers(LOGOUT_CALLBACK_URL);
}
}
如何让Spring Security公开/logout/saml 2/slo并终止会话(或者允许我实现自己的会话销毁逻辑)?
编辑:启用调试日志记录后,我看到:
2023-02-03 14:42:37.845 DEBUG 1 --- [p-nio-80-exec-2] .s.s.p.s.w.a.l.Saml2LogoutResponseFilter : Failed to validate LogoutResponse: [[invalid_destination] Failed to match destination to configured destination]
1条答案
按热度按时间0tdrvxhp1#
我找到了解决方案,并将发布它,以供其他人帮助或为未来的我:)缺少的是RelyingPartyRegistration上的singleLogoutServiceResponseLocation,它必须与LogoutResponse目标匹配。否则Saml2LogoutResponseFilter将引发异常。
}