2017-08-17 48 views
1

我在接缝基础上挣扎,但无法摆脱困境。我有一个春季启动应用程序应该暴露一个休息的URL。用Feign客户端和证书呼叫WS

我做它喜欢:

@RestController 
@RequestMapping(value = "/api") 
public class MdmhController { 

    @Resource 
    private MdmhClient mdmhClient; 


    @RequestMapping(
      method = RequestMethod.GET, 
      value = "/myEntityNames", 
      produces = { MediaType.APPLICATION_JSON_UTF8_VALUE } 
    ) 
    ResponseEntity<Iterable<String>> getMyEntityNames() { 

     MyEntity[] myEntities = 
       mdmhClient.getMyentitis(); 

     Set<String> myEntityNames= new HashSet<>(); 
     for (MyEntity me : myEntities) { 
      myEntityNames.add(me.getName()); 
     } 
     return new ResponseEntity<Iterable<String>>(myEntityNames, HttpStatus.OK); 
    } 
} 

正如你可以看到它消耗而我试图用假死客户端来实现另一个服务:

@Import(FeignClientsConfiguration.class) 
@Component 
public class MdmhClientImpl implements MdmhClient { 

    private final Decoder decoder; 
    private final Encoder encoder; 

    private MdmhClient mdmhClient; 

    @Value("${mdmh.serviceId}") // injected by sprins yaml e.g. url-to-service.com 
    private String mdmhServiceId; 

    @Autowired 
    public MdmhClientImpl(
      final Decoder decoder, final Encoder encoder) { 
     this.decoder = decoder; 
     this.encoder = encoder; 
    } 

    @Override 
    public MyEntity[] getMyEntities() { 

     if (mdmhClient == null) { 
      mdmhClient = Feign.builder() 
        .encoder(encoder) 
        .decoder(decoder) 
        .client(new Client.Default(TrustingSSLSocketFactory.get(), null)) 
        .target(MdmhClient.class, "https://" + mdmhServiceId); 
     } 
     return mdmhClient.getMyEntity(); 
    } 
} 

接口看起来像:

@RestController 
@RequestMapping(value = "/api") 
public interface MdmhClient { 

    @RequestLine("GET mdmh/service/v2/myentities") 
    @Headers({ "accept: application/json" }) 
    MyEntity[] getMyEntities(); 
} 

当MdmhClient确实给我例外mdmhClient.getEntity()电话:

SunCertPathBuilderException: unable to find valid certification path to requested target. 

我知道要解决这个问题我需要将证书导入到jre。我运行的IntelliJ IDE,并设置我的项目的JDK的路径:

C:\Program Files\Java\jdk1.8.0_65 

我还访问过的Firefox的Web服务:

https://url-to-service.com/mdmh/service/v2/myentities 

和下载我导入证书:

C:\Program Files\Java\jdk1.8.0_65\jre\lib\security\cacerts 

但我仍然得到错误。出于挫折感,我将证书导入到所有已安装的jdks中,仍然一样。

我发现:https://github.com/OpenFeign/feign/blob/master/core/src/test/java/feign/client/TrustingSSLSocketFactory.java

,并把它添加到我的MdmhClient像:

@Override 
public MyEntity[] getMyEntities() { 

    if (mdmhClient == null) { 
     Client client = new Client.Default(
       TrustingSSLSocketFactory.get(), 
       new HostnameVerifier() { 
        @Override 
        public boolean verify(String s, SSLSession sslSession) { 
         return true; 
        } 
       }); 
     mdmhClient = Feign.builder() 
       .encoder(encoder) 
       .decoder(decoder) 
       .client(new Client.Default(TrustingSSLSocketFactory.get(), null)) 
       .target(MdmhClient.class, "https://" + mdmhServiceId); 
    } 
    return mdmhClient.getMyEntities(); 
} 
在此之后

我正在从我的所谓服务的存取遭拒响应。

ERROR [081-exec-3] 17.08.17 08:26:28.868 [email protected]: Servlet.service() for servlet [dispatcherServlet] in context with path [/lic] threw exception [Request processing failed; nested exception is feign.FeignException: status 403 reading MdmhClient#getFamilyVersions(); content: 
<HTML><HEAD> 
<TITLE>Access Denied</TITLE> 
</HEAD> 
<BODY> 
<FONT f... 

但我100%确定我不需要验证。因为我可以在不修改标题的情况下输入浏览器的URL并获得结果。

我希望你能帮助我或给我一些提示如何解决这个问题。

谢谢

+1

您应该删除注释到您的'MdmhClient'界面 – Sonata

回答

1

它看起来像你的客户端通过代理服务器访问服务。代理服务器需要身份验证,因此使用403响应并使用不同的证书(链),因此导入从Web服务获取的证书无助于此。