在 Spring Boot 中拦截 SSLHandshakeException [英] Intercept SSLHandshakeException in Spring boot
问题描述
我们有一个使用 2-way ssl Auth 用 SpringBoot 编写的 rest API.当用户选择错误/过期的客户端证书时,我们希望发送 401 HTTP 状态代码.
当它发生时,我可以看到异常:
javax.net.ssl.SSLHandshakeException:PKIX 路径构建失败:sun.security.provider.certpath.SunCertPathBuilderException:无法找到请求目标的有效认证路径
API 正常启动并且工作正常.每当用户尝试调用我的 api 选择错误的客户端证书或无效时,就会发生异常.在这种情况下,我想将 401 返回给调用者
Spring boot 配置了Tomcat和@EnableWebSecurity
http.x509().subjectPrincipalRegex("XXXXXX").userDetailsService(this.userDetailsService);((RequiresChannelUrl)http.requiresChannel().anyRequest()).requiresSecure();....http.exceptionHandling().authenticationEntryPoint(new HttpStatusEntryPoint(HttpStatus.UNAUTHORIZED))公共 TomcatConnectorCustomizer httpsConnectorCustomizer(....) {返回(连接器)->{connector.setScheme(https");连接器.setPort(端口);Http11NioProtocol 协议 = (Http11NioProtocol) connector.getProtocolHandler();protocol.setSSLEnabled(true);协议.setSecure(真);协议.setPort(端口);protocol.setClientAuth(可选");协议.setKeystoreFile(...);protocol.setKeystorePass(...);协议.setKeystoreType(...);协议.setKeyAlias(...);协议.setTruststoreFile(...);协议.setTruststorePass(...);协议.setTruststoreType(...);};}
这里是堆栈跟踪:
DirectJDKLog.java:175 [] 换行时握手失败javax.net.ssl.SSLHandshakeException:PKIX 路径构建失败:sun.security.provider.certpath.SunCertPathBuilderException:无法找到请求目标的有效认证路径在 java.base/sun.security.ssl.Alert.createSSLException(Alert.java:131)...引起:sun.security.validator.ValidatorException:PKIX 路径构建失败:sun.security.provider.certpath.SunCertPathBuilderException:无法找到请求目标的有效认证路径在 java.base/sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:439)........引起:sun.security.provider.certpath.SunCertPathBuilderException:无法找到请求目标的有效认证路径在 java.base/sun.security.provider.certpath.SunCertPathBuilder.build(SunCertPathBuilder.java:141)
浏览器显示:ERR_BAD_SSL_CLIENT_AUTH_CERT
是否可以在 SpringBoot 中捕获此异常并发送特定的 HTTP 状态代码?
似乎异常在 java/tomcat 的深处,到目前为止我无法捕获它.
您将无法发送 HTTP 状态代码,因为建立连接失败在您开始使用 HTTP 之前.>
参见 https://www.cloudflare.com/learning/ssl/what-happens-in-a-tls-handshake/ 介绍 SSL/TLS
We have a rest API written in SpringBoot using a 2-way ssl Auth. We would like to send 401 HTTP status code when the user selects the wrong/expired client certificate.
When it happens I can see the exception:
javax.net.ssl.SSLHandshakeException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
The API starts normally and works fine. The exception occurs whenever the user tries to call my api selecting a wrong client certificate or invalid. In this case I would like to return 401 to the caller
Spring boot is configured with Tomcat and @EnableWebSecurity
http.x509().subjectPrincipalRegex("XXXXXX").userDetailsService(this.userDetailsService);
((RequiresChannelUrl)http.requiresChannel().anyRequest()).requiresSecure();
....
http.exceptionHandling()
.authenticationEntryPoint(new HttpStatusEntryPoint(HttpStatus.UNAUTHORIZED))
public TomcatConnectorCustomizer httpsConnectorCustomizer(....) {
return (connector) -> {
connector.setScheme("https");
connector.setPort(port);
Http11NioProtocol protocol = (Http11NioProtocol) connector.getProtocolHandler();
protocol.setSSLEnabled(true);
protocol.setSecure(true);
protocol.setPort(port);
protocol.setClientAuth("optional");
protocol.setKeystoreFile(...);
protocol.setKeystorePass(...);
protocol.setKeystoreType(...);
protocol.setKeyAlias(...);
protocol.setTruststoreFile(...);
protocol.setTruststorePass(...);
protocol.setTruststoreType(...);
};
}
Here the stack trace:
DirectJDKLog.java:175 [] Handshake failed during wrap
javax.net.ssl.SSLHandshakeException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
at java.base/sun.security.ssl.Alert.createSSLException(Alert.java:131)
...
Caused by: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
at java.base/sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:439)
....
....
Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
at java.base/sun.security.provider.certpath.SunCertPathBuilder.build(SunCertPathBuilder.java:141)
The browser shows: ERR_BAD_SSL_CLIENT_AUTH_CERT
Is it possible to catch this exception in SpringBoot and send a specific HTTP status code?
It seems that the exception is deep down in java/tomcat and so far I was not able to catch it.
You won't be able to send a HTTP status code, because establishing the connection fails before you start talking HTTP.
See https://www.cloudflare.com/learning/ssl/what-happens-in-a-tls-handshake/ for an intro to SSL / TLS
这篇关于在 Spring Boot 中拦截 SSLHandshakeException的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!