【发布时间】: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