Springboot项目,前端http访问后端JavaHttps服务器

1.搭建JavaHttps服务器

使用jdk自带的 keytools 创建证书

首先cmd命令行输入如下:

keytool -genkey -alias tomcat -keyalg RSA -keystore ./server.keystore

接着按提示输入:输入完口令后,一顿回车,直到问你是否确认你输入y

输入密钥库口令:888888
再次输入新口令:888888
您的名字与姓氏是什么?
  [Unknown]:  
您的组织单位名称是什么?
  [Unknown]:  
您的组织名称是什么?
  [Unknown]:  
您所在的城市或区域名称是什么?
  [Unknown]:  
您所在的省/市/自治区名称是什么?
  [Unknown]:  
该单位的双字母国家/地区代码是什么?
  [Unknown]: 
CN=kaibowang, OU=yuxuelian, O=yuxuelian, L=chengdu, ST=chengdushi, C=china是否正确?
  [否]:  y
 
输入  的密钥口令
        (如果和密钥库口令相同, 按回车):
再次输入新口令:
 
Warning:
JKS 密钥库使用专用格式。建议使用 "keytool -importkeystore -srckeystore C:\Users\Administrator\.keystore -destkeystore C:\Users\Administrator\.keystore -deststoretype pkcs12" 迁移到行业标准格式 PKCS12

此时,你就可以在电脑的用户组目录下发现server.keystore文件,说明证书生成了。接着将这个证书放到Springboot项目resource目录下。然后配置yaml文件:

server:
  port: 5001
  servlet:
    context-path: /ais/ogw
  ssl:
    key-alias: tomcat
    key-store: classpath:server.keystore # 证书路径,有可能你放到resouce目录下,需要重新构建以下项目,不然可能会抛出找不到server.keystore错误。
    enabled: true
    key-store-password: 888888 # 填写你当时创建证书的密钥
    key-store-type: JKS

到次,你直接浏览器访问https://localhost:端口/你的资源路径。

就可以看到成功!

2.配置Http自动访问Https(补充)

前端发起http请求自动转成访问https请求。

如浏览器访问http://localhost/资源路径。自动重定向访问到你JavaHttps服务器的https://localhost:服务器端口/资源路径.

编写一个Https配置类即可

import org.apache.catalina.Context;
import org.apache.catalina.connector.Connector;
import org.apache.tomcat.util.descriptor.web.SecurityCollection;
import org.apache.tomcat.util.descriptor.web.SecurityConstraint;
import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class HttpsConfig {
    @Bean
    public TomcatServletWebServerFactory 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(initHttpConnector());
        return tomcat;
    }

    private Connector initHttpConnector() {
        Connector connector = new Connector("org.apache.coyote.http11.Http11NioProtocol");
        connector.setScheme("http");
        // 监听http协议的80端口
        connector.setPort(80);
        connector.setSecure(false);
        // 将http 请求转发到https 的5001 (你后端服务器啥地址,这里就填写啥,我是5001)
        connector.setRedirectPort(5001);
        return connector;
    }
}

重启服务,浏览器直接访问localhost/资源路径。会发现浏览器自动302冲顶向到你https服务器的资源。因为你设置了监听80端口。你可以打开浏览器的网络查看,会显示302重定向消息。

3.前后端分离项目实现前端服务器通过http跨域访问后端https服务器(补充)

假设现在前端vue项目所在服务器8080.首先8080是跨域访问https后端。你需要解决跨域,跨域我目前知道的有三种方案:

1. jsonp处理(前端ajax采用jsonp方式,后端处理的时候拿到前端传递过来的回调函数名,构建一个调用函数的代码字符串)

2. 后端配置crossFilter,或者实现WebMvcconfigurer往里面注册跨域信息。(这种方式我试了,我目前无法实现http跨https。你后端如果是http的话,随便跨,不管前端采用https协议还是怎么滴,都能跨。但是后端如果是https协议。前端发http请求,就会提示跨域)。

3. 用nginx服务器(还没试过)

后端接口路径:

/cross2,我是向用来演示后端配置跨域是否能打通。

/cross,我是用来演示采用jsonp方式跨域能否打通。

/**
     * 这是演示直接在后端配置跨域解决。
     * @return
     */
    @GetMapping("/cross2")
    @ResponseBody
    public Map cross2(){
        System.out.println("cross2.......");
        Map map = new HashMap<>();
        map.put("data","hello...cross2...success");

        return map;
    }

    /**
     * 这是演示jsonp 来处理跨域的。
     * @param request
     * @param response
     */
    @GetMapping("/cross")
    public void testCross(HttpServletRequest request, HttpServletResponse response){
        System.out.println("testCross.....start");
        try {
            // 1. 接收前端回调函数名
            String callback = request.getParameter("callback");

            // 2. 业务逻辑处理(我这里简单演示)。。。。
            String data = "hello world";

            // 3. 通过前端传递的回调函数名,我们将data数据放入这个回调函数的参数上,并且以字符串方式调用这个回调函数
            String jsoncallback = callback + "({'result':'"+data+"'})";

            // 4. 由于是jsonp 只能处理get请求,get请求又有乱码问题,只好设置一下响应字符编码
            response.setContentType("text/html");
            response.setCharacterEncoding("utf-8");

            // 5. 通过输入流将jsoncallback这个调用过程,打回给浏览器
            PrintWriter out = response.getWriter();
            out.println(jsoncallback);

            out.flush();
            out.close();
            System.out.println("testCross....end");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

这是我后端配置的允许跨域。而且我也测试了,后端如果是采用http协议启动,前端vue8080是能够跨域访问的,这就说明这个配置是起作用的。

@Configuration
public class MvcConfig implements WebMvcConfigurer {
    /**
     * 解决跨域请求
     * @return
     */
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")
                .allowCredentials(true)
                .allowedOrigins("*")
                .allowedHeaders("*")
                .allowedMethods("*")
                .maxAge(3600);

        WebMvcConfigurer.super.addCorsMappings(registry);
    }
}

前端:

前端是vue项目,服务器启动在8080端口。就两个按钮,用来测试用。







jsonp流程

当我点击测试jsonp跨域按钮时,前端采用ajax并且是jsonp方式,发现后端服务器正常请求。浏览器正常接收。

Springboot项目,前端http访问后端JavaHttps服务器_第1张图片

我们来查看网络分析一下流程:

Springboot项目,前端http访问后端JavaHttps服务器_第2张图片

首先两个请求一个302,一个200.

302请求首先是访问http://localhost/.....是访问本台地址80端口,正好就被我后端https配置监听80端口,随后就302重定向到https的5001端口去,从而有第二个响应正常200的请求。

crossFilter流程:

我们再来点击crossfilter处理跨域的情况。发现出现了跨域,为什么这样?

Springboot项目,前端http访问后端JavaHttps服务器_第3张图片

一样,查看网络情况:

Springboot项目,前端http访问后端JavaHttps服务器_第4张图片

 302应该说明被后端服务器检测到http的80端口,做出了响应告诉浏览器重定向到https的5001,可是我们来看后端控制台情况, 什么也没有输出。我们的/cross2接口如果有进来,是会输出的。

Springboot项目,前端http访问后端JavaHttps服务器_第5张图片

说明crossFilter跨域情况请求都没有打入到服务器。为什么请求都没有打入到服务器,浏览器就报出跨域?跨域应该是请求可以打入服务器,并且服务器也可以做出响应,只不过浏览器拿到数据后,发现你的原始路径和目标路径跨域,最终才会在控制台上提示跨域啊?可是这里后端服务器都没有接收到请求,浏览器就先提示了跨域?我实在不理解。

解决方案:

我直接将后端http自动监听80重定向https的配置关了。前端发请求直接填写https://ip地址:服务器端口/...发现正常请求,正常响应。不管Java后端采用jsonp还是crosfilter都能处理!

你可能感兴趣的:(java,http,https)