【Spring】Feign客户端发送HTTPS请求绕过认证

x33g5p2x  于2022-03-08 转载在 Spring  
字(3.5k)|赞(0)|评价(0)|浏览(642)

1.概述

转载:https://www.jianshu.com/p/ea627708ab52

一个Spring Boot项目,为了使用Harbor仓库,起初通过Spring RestTemplate完成了对Harbor仓库的HTTPS请求,后想改为使用Feign客户端的方式请求Harbor仓库。

2.配置过程

1、pom文件依赖添加

  1. <dependency>
  2. <groupId>org.springframework.cloud</groupId>
  3. <artifactId>spring-cloud-starter-openfeign</artifactId>
  4. <version>2.2.1.RELEASE</version>
  5. </dependency>
  6. <dependency>
  7. <groupId>io.github.openfeign</groupId>
  8. <artifactId>feign-jackson</artifactId>
  9. <version>9.3.1</version>
  10. </dependency>

其中openfeign是必须的依赖,而feign-jackson依赖主要是为了配置Feign客户端的编码和解码以支持JSON字符串

2、创建Feign客户端

  1. import feign.Headers;
  2. import feign.Param;
  3. import feign.RequestLine;
  4. import org.springframework.cloud.openfeign.FeignClient;
  5. @FeignClient(name="feignClient")
  6. public interface FeignClient {
  7. @Headers({"Content-Type: application/json", "Authorization: {token}"})
  8. @RequestLine("GET /api/users?username={username}")
  9. List<Map<String, Object>> getUsers(URI baseUri,
  10. @Param("token") String token,
  11. @Param("username") String username);
  12. }

3、在Service中调用Feign客户端完成对Harbor仓库的请求

  1. import feign.Feign;
  2. import feign.Target;
  3. import feign.jackson.JacksonDecoder;
  4. import feign.jackson.JacksonEncoder;
  5. import org.springframework.cloud.openfeign.FeignClientsConfiguration;
  6. @Import(FeignClientsConfiguration.class)
  7. @Service(value = "service")
  8. public class ServiceImpl implements IService {
  9. private FeignClient feignClient;
  10. public ServiceImpl () {
  11. harborFeignClientV0 = Feign.builder().encoder(new JacksonEncoder())
  12. .decoder(new JacksonDecoder()).target(Target.EmptyTarget.create(HarborFeignClientV0.class));
  13. }
  14. @Override
  15. public List<Map<String, Object>> getUsers(DTO dTO){
  16. String usersUrl = getBaseUrl(dTO);
  17. try {
  18. SslUtils.ignoreSsl();
  19. return harborFeignClientV0.getUsers(new URI(usersUrl), dTO.getToken(), dTO.getUsername());
  20. } catch (Exception e){
  21. log.error("调用Harbor API错误:", e.getMessage());
  22. throw new RuntimeException(e);
  23. }
  24. }
  25. }

相比较于Feign客户端发送HTTP请求,这里只多了一行代码SslUtils.ignoreSsl();,通过这个工具类,所有的HTTPS请求将会绕过证书检查。

4、工具类SslUtils

参考:https://blog.csdn.net/qq_34836433/article/details/78539009

本次我是使用这种方式进行验证的。

  1. public class SslUtils {
  2. private static void trustAllHttpsCertificates() throws Exception {
  3. TrustManager[] trustAllCerts = new TrustManager[1];
  4. TrustManager tm = new miTM();
  5. trustAllCerts[0] = tm;
  6. SSLContext sc = SSLContext.getInstance("SSL");
  7. sc.init(null, trustAllCerts, null);
  8. HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
  9. }
  10. static class miTM implements TrustManager,X509TrustManager {
  11. public X509Certificate[] getAcceptedIssuers() {
  12. return null;
  13. }
  14. public boolean isServerTrusted(X509Certificate[] certs) {
  15. return true;
  16. }
  17. public boolean isClientTrusted(X509Certificate[] certs) {
  18. return true;
  19. }
  20. public void checkServerTrusted(X509Certificate[] certs, String authType)
  21. throws CertificateException {
  22. return;
  23. }
  24. public void checkClientTrusted(X509Certificate[] certs, String authType)
  25. throws CertificateException {
  26. return;
  27. }
  28. }
  29. /**
  30. * 忽略HTTPS请求的SSL证书,必须在openConnection之前调用
  31. * @throws Exception
  32. */
  33. public static void ignoreSsl() throws Exception{
  34. HostnameVerifier hv = new HostnameVerifier() {
  35. public boolean verify(String urlHostName, SSLSession session) {
  36. System.out.println("Warning: URL Host: " + urlHostName + " vs. " + session.getPeerHost());
  37. return true;
  38. }
  39. };
  40. trustAllHttpsCertificates();
  41. HttpsURLConnection.setDefaultHostnameVerifier(hv);
  42. }

三、踩坑过程

1、绕开HTTPS认证的另一个方法
参考:https://blog.csdn.net/Chipslyc/article/details/98851831
通过自己配置Feign客户端的配置绕开HTTPS认证检查,添加依赖和Feign客户端配置之后行不通,首先在添加依赖的时候,导致了好几次项目跑不起来;其次都配置好之后发送HTTPS请求时还是报错PKIX path building failed

2、依赖依赖之后单元测试无法正常启动
参考:http://www.lzhpo.com/article/93

启动单元测试报错Command line is too long

相关文章