Spring Boot3升级:SAML扩展迁移至SP遇/saml/login 404问题
Spring Boot 3 + Spring Security 6 SAML2 迁移问题解决方案
问题1:/saml/login 404 与原SAMLEntryPoint替代实现
Spring Security 6对SAML2模块做了重构,原SAMLEntryPoint类已被移除,需通过新的配置方式实现登录跳转逻辑:
1. 配置自定义登录入口路径
在SecurityFilterChain中指定/saml/login作为SAML登录入口,映射到官方SAML2认证端点:
@Bean public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { http .authorizeHttpRequests(auth -> auth.anyRequest().authenticated()) .saml2Login(saml2 -> saml2 .loginPage("/saml/login") // 自定义入口路径 .authenticationSuccessHandler(new SavedRequestAwareAuthenticationSuccessHandler()) // 自动跳转回原请求页 ) .exceptionHandling(ex -> ex .authenticationEntryPoint((request, response, ex) -> response.sendRedirect("/saml/login"))); // 未认证请求跳转至SAML登录 return http.build(); }
2. 实现原TargetUrlSamlEntryPoint的目标URL传递功能
如果需要在跳转时携带目标URL,可通过relayState参数传递,结合自定义Saml2AuthenticationRequestResolver实现:
@Bean public Saml2AuthenticationRequestResolver customSaml2AuthRequestResolver( Saml2RegistrationRepository registrationRepo) { OpenSaml4AuthenticationRequestResolver resolver = new OpenSaml4AuthenticationRequestResolver(registrationRepo); resolver.setAuthenticationRequestContextConsumer(context -> { HttpServletRequest request = context.getRequest(); // 从请求参数或session获取目标URL String targetUrl = request.getParameter("target") != null ? request.getParameter("target") : request.getRequestURI(); // 将目标URL存入relayState,认证成功后取出跳转 context.getAuthenticationRequest().setRelayState(targetUrl); }); return resolver; }
然后在SecurityFilterChain中注入该Resolver:
.saml2Login(saml2 -> saml2 .loginPage("/saml/login") .authenticationRequestResolver(customSaml2AuthRequestResolver(registrationRepo)) .authenticationSuccessHandler((request, response, auth) -> { String targetUrl = request.getParameter("RelayState"); if (targetUrl != null && !targetUrl.isEmpty()) { response.sendRedirect(targetUrl); } else { response.sendRedirect("/"); } }) )
问题2:自签名证书的安全处理方式
禁止直接禁用SSL验证,这会引入严重安全风险,推荐以下两种合规方案:
1. 将自签名证书加入JVM信任库
导出Shibboleth的自签名证书:
keytool -exportcert -alias shibboleth-idp -keystore shibboleth.jks -file shibboleth.crt
将证书导入JVM默认信任库(默认密码changeit):
keytool -importcert -alias shibboleth-idp -file shibboleth.crt -keystore $JAVA_HOME/jre/lib/security/cacerts
2. 项目自定义信任库
创建项目专属的信任库,导入证书后在application.properties中配置:
# 自定义信任库配置 server.ssl.trust-store=classpath:truststore.jks server.ssl.trust-store-password=your-truststore-password server.ssl.trust-store-type=JKS
也可在SAML2配置中自定义HTTP客户端的SSL上下文:
@Bean public OpenSaml4Configurer openSaml4Configurer() throws Exception { SSLContext sslContext = SSLContextBuilder.create() .loadTrustMaterial(ResourceUtils.getFile("classpath:shibboleth.crt"), "cert-password".toCharArray(), (certChain, authType) -> { // 仅信任导入的自签名证书 return Arrays.stream(certChain) .anyMatch(cert -> cert.getSubjectDN().getName().contains("Shibboleth IDP")); }) .build(); return OpenSaml4Configurer.custom() .httpClient(client -> client.setSSLContext(sslContext)) .build(); }
内容的提问来源于stack exchange,提问作者Jonas Kistler
相关产品推荐
相关产品推荐

