【问题标题】:Spring Boot + OAuth2 + REST API - Certification Path Not FoundSpring Boot + OAuth2 + REST API - 找不到证书路径
【发布时间】:2020-11-05 11:38:48
【问题描述】:

我正在现有的 Spring Boot v2.1.4 应用程序中实现 RESTful API。该应用程序包含一个 Spring MVC 层,该层使用 Spring Security 进行保护。有使用 JSP 构建的视图。一些 JSP 嵌入了调用 AJAX 调用来检索信息的客户端脚本。这些调用将针对 API 而不是现有的 MVC 端点执行。

新服务端点使用 OAuth2 进行保护,并且已在应用程序中设置授权服务器并使用 @EnableAuthorizationServer 注释激活。为了在这些端点上启用 SSL,我使用 keytool 生成了一个私钥/公钥对。

keytool -genkeypair -alias apitest -keyalg RSA -validity 365 -keysize 2048 -keystore apitest.jks

然后我执行以下命令导出自签名证书。

keytool -export -alias apitest -keystore apitest.jks -rfc -file apitest.cer

我已将证书添加到信任库文件中,该文件的路径和密码在应用程序启动时加载到系统属性中。

System.setProperty("javax.net.ssl.trustStore", truststorePath);
System.setProperty("javax.net.ssl.trustStorePassword", truststorePassword);

由于 MVC 层由 Spring Security 保护,当用户成功登录应用程序时,我尝试从令牌端点检索 OAuth2 令牌。令牌作为 cookie 在响应中返回(此处未显示)。

ResourceOwnerPasswordAccessTokenProvider provider = new ResourceOwnerPasswordAccessTokenProvider();
ResourceOwnerPasswordResourceDetails resource = new ResourceOwnerPasswordResourceDetails();
resource.setClientAuthenticationScheme(AuthenticationScheme.none);
UriComponents uriComponents = ServletUriComponentsBuilder.fromServletMapping(request).path("/oauth/token").build();
resource.setAccessTokenUri(uriComponents.toUriString());
resource.setScope(Arrays.asList("read", "write"));
resource.setClientId(oAuth2ClientDetails.getClientId());
resource.setClientSecret(oAuth2ClientDetails.getClientSecret());
resource.setGrantType("password");
resource.setUsername(userName);
resource.setPassword(userCredentials);
OAuth2AccessToken accessToken = provider.obtainAccessToken(resource, new DefaultAccessTokenRequest());
return accessToken.getValue();

当此逻辑触发对令牌端点的调用时,会观察到以下错误。

org.springframework.web.client.ResourceAccessException: I/O error on POST request for "https://localhost:8443/testapp/oauth/token": sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target; nested exception is javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
    at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:744) ~[spring-web-5.1.6.RELEASE.jar:5.1.6.RELEASE]
    at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:670) ~[spring-web-5.1.6.RELEASE.jar:5.1.6.RELEASE]
    at org.springframework.web.client.RestTemplate.exchange(RestTemplate.java:579) ~[spring-web-5.1.6.RELEASE.jar:5.1.6.RELEASE]

由于 API 端点和授权服务器都在 localhost 上运行,我认为信任库文件中的自签名证书就足够了。完成此设置我缺少什么?

【问题讨论】:

    标签: java spring-boot ssl oauth-2.0 spring-oauth2


    【解决方案1】:

    我怀疑您的问题可能与没有父根权限的证书有关。我通常推荐使用信任链创建现实世界的自签名证书的方法:

    • 首先创建根证书颁发机构
    • 然后使用它来创建服务器 SSL 证书

    根权限

    对于使用 OAuth 进行本地开发,我创建了一个名为 mycompany.ca.crt 的根权限,然后像这样添加 Java 信任,另外还将此证书分发到浏览器:

    • keytool -keystore cacerts -storepass changeit -importcert -alias mycompanyca -file ~/Desktop/mycompany.ca.crt

    创建 SSL 证书

    然后我使用根证书创建 SSL 证书,不需要额外的信任配置。

    脚本

    如果有兴趣,可以看看these scripts of mine,它使用了 openssl 工具:

    • makeCerts.ps1 脚本适用于 Windows
    • makeCerts.sh 脚本适用于 MacOS 或 Linux
    • 运行脚本时会创建其他文件
    • 您需要编辑域名以匹配您正在使用的域名

    我的示例使用用于本地 PC 开发的通配符域,并且我还将域添加到我的主机文件中。然后在浏览器客户端中,我看到了这个:

    my blog post 中的更多信息虽然我怀疑您已经知道大部分内容,但根据您的问题。

    【讨论】:

    • Gary - 感谢您的反馈和信息丰富的博文。我创建了一个根证书并将其导入 Windows 中的 Trusted Root Authorities。然后我用它来生成证书并将其放入我的信任库文件中。不幸的是,这也没有解决我的问题。我能找到的唯一解决方案是在 Firefox 中访问应用程序,下载 localhost 证书,然后将其导入到应用程序使用的信任库文件中。一旦我这样做了,API 调用就成功了。这对你有意义吗?有什么我想念的吗?我想了解为什么会这样。
    • 很高兴看到您现在有了一个可行的解决方案。我不明白您为什么需要信任 SSL 证书本身——我始终致力于只信任根权限,这就是 PKI 在现实世界中的工作方式。可能与使用 localhost 作为域名有关 - 我总是使用本地 PC 域,如 this post of mine,这是团队可以遵循的约定。
    猜你喜欢
    • 2019-12-09
    • 2017-02-12
    • 2016-04-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-05
    • 2016-11-28
    • 2018-10-15
    相关资源
    最近更新 更多