2017-03-06 77 views
0

當我想訪問REST api時,我需要對自己進行身份驗證。如何將Windows憑據添加到apache駱駝路線?

我用apache的WinHttpClients創建了一個簡單的例子,它的工作原理也接受了一個自簽名的crt,該網站使用了這個例子。

這是我的依賴

dependencies { 
compile 'org.apache.httpcomponents:httpclient:4.5.+' 
compile 'org.apache.httpcomponents:httpclient-win:4.5.+' 

testCompile group: 'junit', name: 'junit', version: '4.11' 
} 

而且這是工作的代碼(授權作品,接受CRT作品)

public class Application { 

    public static void main(String[] args) throws IOException { 

    if (WinHttpClients.isWinAuthAvailable()) { 
     PoolingHttpClientConnectionManager httpClientConnectionManager = new PoolingHttpClientConnectionManager(
     buildSSLSocketFactory()); 
     HttpClientBuilder clientBuilder = WinHttpClients.custom().useSystemProperties(); 
     clientBuilder.setConnectionManager(httpClientConnectionManager); 
     CloseableHttpClient httpClient = clientBuilder.build(); 

     HttpHost httpHost = new HttpHost("server.evilcorp.com", 443, "https"); 
     HttpGet httpGet = new HttpGet(
     "/evilwebapi/streams/endpointalpha/data"); 
     httpGet.setHeader("accept", "application/json"); 

     CloseableHttpResponse httpResponse = httpClient.execute(httpHost, httpGet); 

     String content = EntityUtils.toString(httpResponse.getEntity()); 
     System.out.println(content); // returns expected json result 
    } 
    } 

    private static Registry<ConnectionSocketFactory> buildSSLSocketFactory() { 
    SSLConnectionSocketFactory sslSocketFactory = new SSLConnectionSocketFactory(buildSSLContext(), NoopHostnameVerifier.INSTANCE); 
    return RegistryBuilder.<ConnectionSocketFactory>create() 
     .register("http", PlainConnectionSocketFactory.getSocketFactory()) 
     .register("https", sslSocketFactory) 
     .build(); 
    } 

    private static SSLContext buildSSLContext() { 
    SSLContext sslContext = null; 
    try { 
     sslContext = new SSLContextBuilder().loadTrustMaterial(null, (TrustStrategy) (arg0, arg1) -> true).build(); 
    } catch (NoSuchAlgorithmException | KeyManagementException | KeyStoreException e) { 
     System.out.println("Failed to initialize SSL handling.\n" + e); 
    } 
    return sslContext; 
    } 
} 

當我試圖通過Apache的駱駝我去訪問相同的網站401狀態。

我試圖以各種方式配置駱駝的httpComponent,但到目前爲止我無法使認證工作。這是目前的駱駝設置。

這是我的依賴關係:

dependencies { 
    compile 'org.apache.camel:camel-core:2.18.+' 
    compile 'org.apache.camel:camel-sql:2.18.+' 
    compile 'org.apache.camel:camel-http4:2.18.+' 
    compile 'org.apache.camel:camel-jetty:2.18.+' 
    compile 'org.apache.camel:camel-jackson:2.18.+' 
    compile 'org.apache.camel:camel-guava-eventbus:2.18.+' 
    compile 'org.apache.camel:camel-quartz2:2.18.+' 
    compile 'com.fasterxml.jackson.core:jackson-core:2.7.+' 
    compile 'org.apache.httpcomponents:httpclient:4.5.+' 
    compile 'org.apache.httpcomponents:httpclient-win:4.5.+' 
    testRuntime files('src/test/resources') 
    runtime files('src/main/resources') 
} 

這是RouteBuilder不工作(授權doesm't工作,的StatusCode:401)

context = new DefaultCamelContext(registry); 
PropertiesComponent pc = new PropertiesComponent(); 
pc.setLocation("classpath:model.properties"); 
context.addComponent("properties", pc); 
try { 

    context.addRoutes(new RouteBuilder() { 
    public void configure() { 
     HttpComponent httpComponent = getContext().getComponent("https4", HttpComponent.class); 
     httpComponent.setHttpClientConfigurer(new WinHttpClientConfigurer()); 
     httpComponent.setClientConnectionManager(new PoolingHttpClientConnectionManager(WinHttpClientConfigurer.buildSSLSocketFactory())); 
     httpComponent.setHttpConfiguration(buildHttpConfiguration()); 
     getContext().getProperties().put("CamelJacksonEnableTypeConverter", "true"); 
     getContext().getProperties().put("CamelJacksonTypeConverterToPojo", "true"); 

     from("quartz2://pipull?cron=0+0/1+*+1/1+*+?+*") 
     .setHeader(Exchange.HTTP_QUERY, 
      simple("start='${header.start}'&end='${header.end}'")) 
     .multicast().parallelProcessing() 
     .to("direct:model"); 

     from("direct:model") 
     .setHeader("contractRef", simple("${properties:model.name}")) 
     .to("https4://server.evilcorp.com/evilwebapi/streams/endpointalpha/data") 
     .to("direct:transform"); 

     from("direct:transform").unmarshal() 
     .json(JsonLibrary.Jackson, Model.class) 
     .bean(ProcessorImpl.class) 
     .to("guava-eventbus:botBus"); 
     } 

     private HttpConfiguration buildHttpConfiguration() { 
     WindowsCredentialsProvider credentialsProvider = new WindowsCredentialsProvider(
      new SystemDefaultCredentialsProvider()); 
     Credentials credentials = credentialsProvider.getCredentials(new AuthScope(null, -1, null, AuthSchemes.NTLM)); 
     HttpConfiguration httpConfiguration = new HttpConfiguration(); 
     httpConfiguration.setAuthMethod(AuthSchemes.NTLM); 
     httpConfiguration.setAuthUsername(credentials.getUserPrincipal().getName()); 

     return httpConfiguration; 
     } 

    }); 
    context.start(); 
    } catch (Exception e) { 
    isRunning.set(false); 
    throw new RuntimeException(e); 
    } 
+0

鑑於您使用的是NTLM,您是否需要進行搶先認證?您是否已經在測試服務器上嘗試了駱駝路由以查看駱駝端點正在發送什麼標頭?你看到駱駝發送授權頭文件嗎? –

回答

0

我已經解決了通過分型問題HttpComponent並將其添加到駱駝上下文中。

public class WinHttpComponent extends HttpComponent { 
    private static final Logger LOG = LoggerFactory.getLogger(WinHttpComponent.class); 

    public WinHttpComponent() { 
    this(HttpEndpoint.class); 
    } 

    public WinHttpComponent(Class<? extends HttpEndpoint> endpointClass) { 
    super(endpointClass); 
    } 

    @Override protected Endpoint createEndpoint(String uri, String remaining, Map<String, Object> parameters) throws Exception { 
     // copy-paste everything from super method 
     // replace this 
     // HttpClientBuilder clientBuilder = HttpClientBuilder.create(); 
     // with this 
     HttpClientBuilder clientBuilder = WinHttpClients.custom().useSystemProperties(); 
     // copy-paste everything from super method 
    } 
} 

context = new DefaultCamelContext(registry); 
context.addComponent("https4", new WinHttpComponent()); 
try { 
    context.addRoutes(new RouteBuilder() { 
    public void configure() { 
     HttpComponent httpComponent = getContext().getComponent("https4", HttpComponent.class); 
     // connection manager which accepts self-signed cert 
     httpComponent.setClientConnectionManager(new PoolingHttpClientConnectionManager(
     NoopSslVerifierHttpClientConfigurer.buildSSLSocketFactory())); 
     ... 
     ... 
     ... 
    } 
    }