2017-08-17 47 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服務獲取的證書無助於此。