在Spring MVC中无法validation目标证书的exception

我试图使用我的用户名和密码从jira服务器获取问题详细信息,但我收到一个ssl错误,说无法validation证书

所以如何validation证书

url:http:local / 8080 / frr / hello

得到错误:

嵌套exception是org.springframework.web.client.ResourceAccessException:GET请求上的I / O错误

“ https://jira.example.com/rest/api/2/issue/id ”:

sun.security.validator.ValidatorException:PKIX路径构建失败:sun.security.provider.certpath.SunCertPathBuilderException:无法找到所请求目标的有效证书路径; 嵌套exception是javax.net.ssl.SSLHandshakeException:sun.security.validator.ValidatorException:PKIX路径构建失败:sun.security.provider.certpath.SunCertPathBuilderException:无法找到具有根本原因sun.security的请求目标的有效证书路径.provider.certpath.SunCertPathBuilderException:无法找到所请求目标的有效证书路径

我的Service.class代码

@Controller public class Service{ @RequestMapping("/hello") public String Data(ModelMap model){ RestTemplate restTemplate = new RestTemplate(); ResponseEntity result = restTemplate.exchange("https://jira.example.com/rest/api/2/issue/id", HttpMethod.GET, new HttpEntity(createHeaders("username", "password")), String.class); model.addAttribute("message", result); return "helloworld"; } RestTemplate restTemplate = new RestTemplate(); HttpHeaders createHeaders( String username, String password ){ HttpHeaders header = new HttpHeaders(); String auth = username + ":" + password; byte[] encodedAuth = Base64.encodeBase64(auth.getBytes(Charset.forName("US-ASCII")) ); String base64Creds = "Basic " + new String( encodedAuth ); header.add("Authorization", "Basic " + base64Creds); return header; } } 

您遇到的问题是您的应用程序无法validation您尝试连接的外部服务器,因为其证书不受信任

简而言之是:

  • 您的应用程序尝试通过安全(HTTPS)通道连接到Jira实例
  • 建立安全连接,应用程序下载证书
  • 应用程序通过尝试将证书跟踪回已知CA(保存在JRE证书库中)来检查证书的有效性
  • 证书检查失败,因为证书是自签名的(最有可能)或过期等。

如果此Jira实例是内部部署(由您的公司托管),那么拥有自签名证书的可能性根本不大。 在这种情况下,证书不是由已知的CA颁发的,因此如果您希望信任它,则需要手动注册它

首先获得证书:

 openssl s_client -connect jira.example.com:443 < /dev/null | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' > public.crt 

然后将其导入您自己的密钥库:

 $JAVA_HOME/keytool -import -alias  -keystore $JAVA_HOME/lib/security/cacerts -file public.crt 

注意:上面的命令适用于Unix环境。 在Windows下,我建议在命令行中使用类似的openssl,但也有可用于同一目的的GUI工具。

检查文件$JAVA_HOME/lib/security/cacerts存在! 在我的情况下,它不是一个文件,而是一个链接到/etc/ssl/certs/java/cacerts ,这也是一个自己的链接(WHAT ???)所以由于它JVM无法找到该文件。

解决方案:将真正的cacerts文件( 我从另一个JDK完成 )复制到/etc/ssl/certs/java/目录,它将解决您的问题:)

你可以替换

 String base64Creds = "Basic " + new String( encodedAuth ); 

 String base64Creds = new String( encodedAuth ); //"Basic " String duplicated