• java使用smiley-http-proxy-servlet实现反向代理,跳过SSL认证


    前言

            nginx可以实现反向代理,但是有时候需要使用java代码来实现,经过摸索,发现有开源的项目可以实现,所以简单记录一下如何使用

    一、引入依赖

            没啥好说

    1. <dependency>
    2. <groupId>org.mitre.dsmiley.httpproxygroupId>
    3. <artifactId>smiley-http-proxy-servletartifactId>
    4. <version>1.12.1version>
    5. dependency>

    二、重写Servlet

            该项目的核心类是ProxyServlet,主要操作都在这个类中实现了,我们可以继承该类,重写其中的方法,自定义实现一些功能。

            这里我们继承ProxyServlet,重写了createHttpClient方法,使其跳过ssl认证

    1. @Slf4j
    2. public class CustomProxyServlet extends ProxyServlet {
    3. /**
    4. * 重写HttpClient,跳过ssl认证
    5. *
    6. * @return {@link HttpClient}
    7. */
    8. @Override
    9. protected HttpClient createHttpClient() {
    10. HttpClientBuilder clientBuilder = getHttpClientBuilder()
    11. .setDefaultRequestConfig(buildRequestConfig())
    12. .setDefaultSocketConfig(buildSocketConfig());
    13. clientBuilder.setMaxConnTotal(maxConnections);
    14. clientBuilder.setMaxConnPerRoute(maxConnections);
    15. if(! doHandleCompression) {
    16. clientBuilder.disableContentCompression();
    17. }
    18. if (useSystemProperties){
    19. clientBuilder.useSystemProperties();
    20. }
    21. SSLContext sslContext = this.getSslContext();
    22. SSLConnectionSocketFactory sslSocketFactory = new SSLConnectionSocketFactory(sslContext, NoopHostnameVerifier.INSTANCE);
    23. clientBuilder.setSSLSocketFactory(sslSocketFactory);
    24. return super.buildHttpClient(clientBuilder);
    25. }
    26. /**
    27. * 获取sslContext
    28. * @return {@link SSLContext}
    29. */
    30. public SSLContext getSslContext() {
    31. SSLContext sslContext = null;
    32. try {
    33. sslContext = SSLContextBuilder.create()
    34. .loadTrustMaterial(TrustAllStrategy.INSTANCE)
    35. .build();
    36. } catch (NoSuchAlgorithmException | KeyManagementException | KeyStoreException e) {
    37. log.error("获取sslContext失败", e);
    38. }
    39. return sslContext;
    40. }
    41. }

    三、添加配置

            添加配置类配置一下代理信息

    代理信息配置

    1. @Data
    2. public class ProxyProperties {
    3. /**
    4. * 映射
    5. */
    6. private String mapping;
    7. /**
    8. * 目标url
    9. */
    10. private String targetUrl;
    11. }

    添加配置,控制是否启代理

    1. @Data
    2. @ConfigurationProperties(prefix = "proxy")
    3. public class ProxyConfig {
    4. /**
    5. * 启用日志
    6. */
    7. private boolean enableLog;
    8. /**
    9. * 配置
    10. */
    11. private List configs;
    12. }

    自动装配,获取自定义配置信息,通过for循环配置多个servlet

    1. import lombok.RequiredArgsConstructor;
    2. import org.mitre.dsmiley.httpproxy.ProxyServlet;
    3. import org.springframework.boot.context.properties.EnableConfigurationProperties;
    4. import org.springframework.boot.web.servlet.ServletContextInitializer;
    5. import org.springframework.context.annotation.Configuration;
    6. import javax.servlet.ServletContext;
    7. import javax.servlet.ServletRegistration;
    8. import java.util.List;
    9. @Configuration
    10. @RequiredArgsConstructor
    11. @EnableConfigurationProperties(ProxyConfig.class)
    12. public class ProxyAutoConfiguration implements ServletContextInitializer {
    13. private final ProxyConfig proxyConfig;
    14. /**
    15. * Configure the given {@link ServletContext} with any servlets, filters, listeners
    16. * context-params and attributes necessary for initialization.
    17. *
    18. * @param servletContext the {@code ServletContext} to initialize
    19. */
    20. @Override
    21. public void onStartup(ServletContext servletContext) {
    22. List configs = proxyConfig.getConfigs();
    23. for (int i = 0; i < configs.size(); i++) {
    24. ProxyProperties properties = configs.get(i);
    25. //定义多个servlet
    26. ServletRegistration initServlet = servletContext.addServlet("ProxyServlet"+i, CustomProxyServlet.class);
    27. initServlet.addMapping(properties.getMapping());
    28. initServlet.setInitParameter(ProxyServlet.P_TARGET_URI, properties.getTargetUrl());
    29. initServlet.setInitParameter(ProxyServlet.P_FORWARDEDFOR, "false");
    30. initServlet.setInitParameter(ProxyServlet.P_LOG, Boolean.toString(proxyConfig.isEnableLog()));
    31. }
    32. }
    33. }

    写在后面的话

            百度使用方法,大部分只能代理一个地址,而且不支持跳过ssl认证,所以这里记录一下,希望对你有用。

  • 相关阅读:
    使用iptables实现 ip & 端口转发
    【Android】编译系统之 make 和 Soong
    GFS分布式文件系统
    2022.11.10 英语背诵
    python目标检测将视频按照帧率切除成图片
    Node.Js基础知识
    解析小结—自用
    《安富莱嵌入式周报》第326期:航空航天级CANopen协议栈,开源USB PD电源和功耗分析,开源EtherCAT伺服驱动板,时序绘制软件,现代机器人设计
    conda中的jupyter notebook无法重命名,无法正确打开文件
    确定了,2022下半年软考报名8月开始
  • 原文地址:https://blog.csdn.net/WayneLee0809/article/details/132685498