【问题标题】:Spring boot catch SSLHandshakeExceptionSpring Boot 捕获 SSLHandshakeException
【发布时间】:2021-03-26 21:10:52
【问题描述】:

我们有一个使用 2-way ssl Auth 用 SpringBoot 编写的 REST API。 当用户选择错误/过期的客户端证书时,我们想发送 401 HTTP 状态码。

当它发生时,我可以看到异常:

javax.net.ssl.SSLHandshakeException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target

API 正常启动并且工作正常。每当用户尝试调用我的 api 选择错误的客户端证书或无效时,就会发生异常。在这种情况下,我想将 401 返回给调用者

Spring boot配置Tomcat和@EnableWebSecurity

http.x509().subjectPrincipalRegex("XXXXXX").userDetailsService(this.userDetailsService);
((RequiresChannelUrl)http.requiresChannel().anyRequest()).requiresSecure();

urls().forEach((url, guard) -> {
   try {
      ((AuthorizedUrl)http.authorizeRequests().antMatchers(new String[]{url})).access(guard);
    } catch (Exception var4) {
        throw new UnsupportedOperationException("error");
    }
});

这里是堆栈跟踪:

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)

浏览器显示:ERR_BAD_SSL_CLIENT_AUTH_CERT 是否可以在 SpringBoot 中捕捉到这个异常并发送特定的 HTTP 状态码?

【问题讨论】:

  • 在不知道您使用什么用于 2-way SSL(tomcat 或 Spring Security 或 ...)的情况下,这是无法回答的。
  • 我会添加更多信息
  • 什么时候得到这个异常?在启动期间?在认证期间?此外,您的 urls.forEach 有点危险,因为 URL 的顺序非常重要。
  • 正如我所写的,当客户端选择错误的证书或无效证书时出现异常,这意味着客户端正在尝试联系我的 Api。我也会指定这一点。感谢您对 foreach 的评论。我去看看
  • 异常将由入口点和/或ExceptionTranslationFilter处理。我希望这只会出现在日志中。

标签: java spring spring-boot tomcat


【解决方案1】:

也许你可以试试控制器建议:

@ControllerAdvice
class MyControllerExceptionHandler {

    @ResponseStatus(HttpStatus.UNAUTHORIZED)  // or whatever you want
    @ExceptionHandler(SSLHandshakeException.class)
    public void handleHandshakeException() {
        // Nothing to do
    }
}

【讨论】:

  • 这可能不起作用,具体取决于 2-way SSL 的实施方式。
【解决方案2】:

也许here 或here 发布的解决方案可以帮助您

在您的安全配置中添加以下行:

@Override
protected void configure(HttpSecurity http) throws Exception {
    http.
      //....
     and().
    .anonymous().disable()
    .exceptionHandling()
    .authenticationEntryPoint(new org.springframework.boot.autoconfigure.security.Http401AuthenticationEntryPoint("YourValue"));
}

它会返回 HTTP 401:

Status Code: 401 Unauthorized
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Expires: 0
//... other header values
WWW-Authenticate: YourValue

【讨论】:

    猜你喜欢
    • 2021-03-27
    • 1970-01-01
    • 2023-03-30
    • 1970-01-01
    • 1970-01-01
    • 2019-09-14
    • 2020-12-03
    • 2018-12-12
    • 1970-01-01
    相关资源
    最近更新 更多