一、背景
一个Spring Boot项目,为了使用Harbor仓库,起初通过Spring RestTemplate完成了对Harbor仓库的HTTPS请求,后想改为使用Feign客户端的方式请求Harbor仓库。
二、配置过程
1、pom文件依赖添加
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
<version>2.2.1.RELEASE</version>
</dependency>
<dependency>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-jackson</artifactId>
<version>9.3.1</version>
</dependency>
其中openfeign是必须的依赖,而feign-jackson依赖主要是为了配置Feign客户端的编码和解码以支持JSON字符串
2、创建Feign客户端
import feign.Headers;
import feign.Param;
import feign.RequestLine;
import org.springframework.cloud.openfeign.FeignClient;
@FeignClient(name="feignClient")
public interface FeignClient {
@Headers({"Content-Type: application/json", "Authorization: {token}"})
@RequestLine("GET /api/users?username={username}")
List<Map<String, Object>> getUsers(URI baseUri,
@Param("token") String token,
@Param("username") String username);
}
3、在Service中调用Feign客户端完成对Harbor仓库的请求
import feign.Feign;
import feign.Target;
import feign.jackson.JacksonDecoder;
import feign.jackson.JacksonEncoder;
import org.springframework.cloud.openfeign.FeignClientsConfiguration;
@Import(FeignClientsConfiguration.class)
@Service(value = "service")
public class ServiceImpl implements IService {
private FeignClient feignClient;
public ServiceImpl () {
harborFeignClientV0 = Feign.builder().encoder(new JacksonEncoder())
.decoder(new JacksonDecoder()).target(Target.EmptyTarget.create(HarborFeignClientV0.class));
}
@Override
public List<Map<String, Object>> getUsers(DTO dTO){
String usersUrl = getBaseUrl(dTO);
try {
SslUtils.ignoreSsl();
return harborFeignClientV0.getUsers(new URI(usersUrl), dTO.getToken(), dTO.getUsername());
} catch (Exception e){
log.error("调用Harbor API错误:", e.getMessage());
throw new RuntimeException(e);
}
}
}
相比较于Feign客户端发送HTTP请求,这里只多了一行代码SslUtils.ignoreSsl();
,通过这个工具类,所有的HTTPS请求将会绕过证书检查。
4、工具类SslUtils
参考:https://blog.csdn.net/qq_34836433/article/details/78539009
public class SslUtils {
private static void trustAllHttpsCertificates() throws Exception {
TrustManager[] trustAllCerts = new TrustManager[1];
TrustManager tm = new miTM();
trustAllCerts[0] = tm;
SSLContext sc = SSLContext.getInstance("SSL");
sc.init(null, trustAllCerts, null);
HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
}
static class miTM implements TrustManager,X509TrustManager {
public X509Certificate[] getAcceptedIssuers() {
return null;
}
public boolean isServerTrusted(X509Certificate[] certs) {
return true;
}
public boolean isClientTrusted(X509Certificate[] certs) {
return true;
}
public void checkServerTrusted(X509Certificate[] certs, String authType)
throws CertificateException {
return;
}
public void checkClientTrusted(X509Certificate[] certs, String authType)
throws CertificateException {
return;
}
}
/**
* 忽略HTTPS请求的SSL证书,必须在openConnection之前调用
* @throws Exception
*/
public static void ignoreSsl() throws Exception{
HostnameVerifier hv = new HostnameVerifier() {
public boolean verify(String urlHostName, SSLSession session) {
System.out.println("Warning: URL Host: " + urlHostName + " vs. " + session.getPeerHost());
return true;
}
};
trustAllHttpsCertificates();
HttpsURLConnection.setDefaultHostnameVerifier(hv);
}
三、踩坑过程
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
网友评论