【问题标题】:Rest api in java using https使用https在java中休息api
【发布时间】:2020-07-13 13:12:30
【问题描述】:

当我在 java 中使用 GETPOST 等创建 Restservices 时,我请求它们使用 http protocol。一旦我使用 https,它就会出错。

例如:http://localhost:8080/demorest/webapi/aliens 工作正常。

但是当我使用 https 查询相同时

https://localhost:8080/demorest/webapi/aliens

我收到错误site can not provide secured connection

需要进行哪些修改才能使其与https 兼容。

【问题讨论】:

标签: java rest web-services https rest-security


【解决方案1】:

正如您提到的,您是 API 新手,这里有一个详细的答案。

答案基于您使用的是 tomcat 服务器的假设。在 https 上运行应用程序有 4 步方法,下面是红色

  1. 获取 SSL 证书或生成自签名 SSL 证书
  2. 在应用程序中启用 HTTPS
  3. 将 HTTP 重定向到 HTTPS
  4. 将 SSL 证书分发给客户端。

如果您还没有 ssl 证书,请使用 keytool 自行生成。 Keytool 是与 JDK 一起提供的证书管理实用程序,因此如果您安装了 JDK,则应该已经有 keytool 可用。

让我们打开终端提示并编写以下命令来创建 JKS 密钥库:

keytool -genkeypair -alias tomcat -keyalg RSA -keysize 2048 -keystore keystore.jks -validity 3650 -storepass 密码

要创建一个 PKCS12 密钥库,我们应该这样做,命令如下:

keytool -genkeypair -alias tomcat -keyalg RSA -keysize 2048 -storetype PKCS12 -keystore keystore.p12 -validity 3650 -storepass 密码

让我们仔细看看我们刚刚运行的命令:

genkeypair: generates a key pair;
alias: the alias name for the item we are generating;
keyalg: the cryptographic algorithm to generate the key pair;
keysize: the size of the key. We have used 2048 bits, but 4096 would be a better choice for production;
storetype: the type of keystore;
keystore: the name of the keystore;
validity: validity number of days;
storepass: a password for the keystore.

运行上一条命令时,我们会被要求输入一些信息,但我们可以跳过所有信息(只需按回车键跳过一个选项)。当被问及信息是否正确时,我们应该输入是。最后,我们按回车键将密钥库密码也用作密钥密码。

What is your first and last name? 
    [Unknown]:  What is the name of your organizational unit? 
    [Unknown]:  What is the name of your organization? 
    [Unknown]:  What is the name of your City or Locality? 
    [Unknown]:  What is the name of your State or Province? 
    [Unknown]:  What is the two-letter country code for this unit? 
    [Unknown]:  Is CN=localhost, OU=Unknown, O=Unknown, L=Unknown, ST=Unknown, C=Unknown correct? 
    [no]: yes 

Enter key password for <tomcat> 
    (RETURN if same as keystore password):

验证密钥库内容 要检查 JKS 格式的 keystore 的内容,我们可以再次使用 keytool:

keytool -list -v -keystore keystore.jks

按照 PKCS12 格式测试密钥库的内容:

keytool -list -v -storetype pkcs12 -keystore keystore.p12

将 JKS 密钥库转换为 PKCS12

如果我们已经有 JKS 密钥库,我们可以选择将其迁移到 PKCS12; keytool 有一个方便的命令:

keytool -importkeystore -srckeystore keystore.jks -destkeystore keystore.p12 -deststoretype pkcs12

2.) 在您的项目中启用 https

如果你有 application.properties 文件

server.port=8443

server.ssl.key-store-type=PKCS12
server.ssl.key-store=classpath:keystore.p12
server.ssl.key-store-password=password
server.ssl.key-alias=tomcat

security.require-ssl=true

如果你有 application.yml 文件

server:
  ssl:
    key-store: classpath:keystore.p12
    key-store-password: password
    key-store-type: pkcs12
    key-alias: tomcat
    key-password: password
  port: 8443

为了在应用中实现,我们需要扩展WebSecurityConfigurerAdapter类,因为security.require-ssl属性已经被弃用了。

如果您使用的是旧版本,则可以跳过下面提到的代码。

@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .requiresChannel()
            .anyRequest()
            .requiresSecure();
    }
}

3.) 将 http 重定向到 https

现在我们已经在 Spring Boot 应用程序中启用了 HTTPS 并阻止了任何 HTTP 请求,我们希望将所有流量重定向到 HTTPS。

Spring 只允许在application.properties (or application.yml) 中定义一个网络连接器。由于我们已将其用于 HTTPS,因此我们必须以编程方式为我们的 Tomcat Web 服务器设置 HTTP 连接器。

@Configuration
public class ServerConfig {

    @Bean
    public ServletWebServerFactory servletContainer() {
        TomcatServletWebServerFactory tomcat = new TomcatServletWebServerFactory() {
            @Override
            protected void postProcessContext(Context context) {
                SecurityConstraint securityConstraint = new SecurityConstraint();
                securityConstraint.setUserConstraint("CONFIDENTIAL");
                SecurityCollection collection = new SecurityCollection();
                collection.addPattern("/*");
                securityConstraint.addCollection(collection);
                context.addConstraint(securityConstraint);
            }
        };
        tomcat.addAdditionalTomcatConnectors(getHttpConnector());
        return tomcat;
    }

    private Connector getHttpConnector() {
        Connector connector = new Connector(TomcatServletWebServerFactory.DEFAULT_PROTOCOL);
        connector.setScheme("http");
        connector.setPort(8080);
        connector.setSecure(false);
        connector.setRedirectPort(8443);
        return connector;
    }
}

4.) 将 SSL 证书分发给客户端 当使用自签名 SSL 证书时,我们的浏览器不会信任我们的应用程序,并会警告用户它不安全。任何其他客户也是如此。

可以通过向客户提供我们的证书来让客户信任我们的应用程序。

从密钥库中提取 SSL 证书 我们已将证书存储在密钥库中,因此我们需要提取它。再次,keytool 很好地支持我们:

keytool -export -keystore keystore.jks -alias tomcat -file 我的证书.crt

让浏览器信任 SSL 证书 当使用行业标准 PKCS12 格式的密钥库时,我们应该能够直接使用它而无需提取证书。

我建议您查看有关如何将 PKCS12 文件导入特定客户端的官方指南。

如果在 localhost 上部署应用程序,我们可能需要在浏览器中执行进一步的步骤:启用与 localhost 的不安全连接。

在 Chrome 中,我们可以在搜索栏中输入以下 URL:chrome://flags/#allow-insecure-localhost 并激活相对选项。

在 JRE 密钥库中导入 SSL 证书 为了让 JRE 信任我们的证书,我们需要将它导入到 cacerts 中:JRE 信任库负责保存所有可信任的证书。

首先,我们需要知道 JDK home 的路径。如果我们使用 Eclipse 或 STS 作为我们的 IDE,找到它的快速方法是转到 Preferences > Java > Installed JREs。如果使用 IntelliJ IDEA,我们可以通过转到 Project Structure > SDKs 并查看 JDK home path 字段的值来访问此信息。

然后,在我们的终端提示符下,让我们插入以下命令(我们可能需要通过在它前面加上 sudo 来以管理员权限运行它):

keytool -importcert -file myCertificate.crt -alias tomcat -keystore $JDK_HOME/jre/lib/security/cacerts

你可以参考github上的项目here

【讨论】:

    【解决方案2】:

    这取决于,您的其余服务可能在 Tomcat 或 Spring Boot 上运行,因此应该阅读他们的文档,您还可以使用不同的 https 服务,例如 nginx,它代理从 https 到 http 的全部或部分请求。

    【讨论】:

      【解决方案3】:
      1. 首先检查使用与8080相同端口的https协议?在大多数情况下,http(8080)和 https(8443 或 443)使用不同的端口。
      2. 如果端口正确,则导入证书。 https://stackoverflow.com/a/27928213/5662508

      【讨论】:

        【解决方案4】:

        如果你能提供你正在使用的服务器会很有帮助,如果你能提供 java 版本、框架(如果有的话)和它们的版本,在这种情况下当然是服务器和服务器版本,那也总是很好的。

        here on DZone 提到的链接中,您可以找到如何在 java 应用程序中使用 tomcat 服务器在本地设置 https 的示例,否则您也可以尝试使用不特定于 java here on freecodecamp 的更通用的文章

        【讨论】:

          【解决方案5】:

          第 1 步:您可以使用 java keytool 创建密钥库;

          命令 : keytool -genkey -alias {any-name} -keyalg RSA -keystore {存储密钥库的路径}

          第 2 步:您可以转到您的服务器配置文件,例如 Tomcat 的 conf/server.xml 并取消注释 8443 设置,然后在标签关闭之前添加以下内容;

          keystoreFile="{keystore 的路径}" keystorePass="{您在创建密钥库时设置的密码}" />

          第 3 步:现在重新启动服务器并点击“https://localhost:8443/demorest/webapi/aliens”。

          编码愉快!

          【讨论】:

            猜你喜欢
            • 2017-12-28
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2020-11-30
            • 2019-02-21
            • 1970-01-01
            • 2018-06-14
            • 2020-01-01
            相关资源
            最近更新 更多