Spring integration 抢占式身份验证-HttpComponentMessageSender

Spring integration 抢占式身份验证-HttpComponentMessageSender,spring-integration,Spring Integration,如何在HttpComponentMessageSender中启用抢占式身份验证 <bean id="httpComponentsMessageSender" class="org.springframework.ws.transport.http.HttpComponentsMessageSender"> <property name="credentials"> <bean class="org.apache.http.auth.Usern

如何在HttpComponentMessageSender中启用抢占式身份验证

<bean id="httpComponentsMessageSender" class="org.springframework.ws.transport.http.HttpComponentsMessageSender">
    <property name="credentials">
        <bean class="org.apache.http.auth.UsernamePasswordCredentials">
            <constructor-arg value="userName"/>
            <constructor-arg value="password"/>
        </bean>
    </property>
</bean>

错误:

<faultcode>soapenv:Server.Transport.Http.401</faultcode><faultstring>1136 The HTTP Webservice returned an error: HTTP/1.1 401 Unauthorized</faultstring>
soapenv:Server.Transport.Http.4011136 Http Web服务返回错误:Http/1.1 401未经授权

您需要将定制的
HttpClient
注入发送方。您可以根据官方Apache文档实现的定制客户端:

HttpClient不支持开箱即用的抢占式身份验证,因为如果误用或使用不当,抢占式身份验证可能会导致严重的安全问题,例如以明文形式向未经授权的第三方发送用户凭据

更新

httpcomponents消息发送程序
具有以下方法:

/**
 * Template method that allows for creation of a {@link HttpContext} for the given uri. Default implementation
 * returns {@code null}.
 *
 * @param uri the URI to create the context for
 * @return the context, or {@code null}
 */
protected HttpContext createContext(URI uri) {
    return null;
}
因此,对于抢占式身份验证,我们需要扩展
HttpComponentsMessageSender
,并实现该方法以提供所需的
上下文
,如Apache Commons文档所示:

protected HttpContext createContext(URI uri) {
    HttpHost targetHost = new HttpHost("localhost", 80, "http");
    CredentialsProvider credsProvider = new BasicCredentialsProvider();
    credsProvider.setCredentials(
         new AuthScope(targetHost.getHostName(), targetHost.getPort()),
         new UsernamePasswordCredentials("username", "password"));

    AuthCache authCache = new BasicAuthCache();
    BasicScheme basicAuth = new BasicScheme();
    authCache.put(targetHost, basicAuth);


    HttpClientContext context = HttpClientContext.create();
    context.setCredentialsProvider(credsProvider);
    context.setAuthCache(authCache);
    return context;
}

当然,必须在实例级别缓存此
上下文
,以便将来在每个
httpclient.execute()

中重用。您需要将自定义的
httpclient
注入发送方。您可以根据官方Apache文档实现的定制客户端:

HttpClient不支持开箱即用的抢占式身份验证,因为如果误用或使用不当,抢占式身份验证可能会导致严重的安全问题,例如以明文形式向未经授权的第三方发送用户凭据

更新

httpcomponents消息发送程序
具有以下方法:

/**
 * Template method that allows for creation of a {@link HttpContext} for the given uri. Default implementation
 * returns {@code null}.
 *
 * @param uri the URI to create the context for
 * @return the context, or {@code null}
 */
protected HttpContext createContext(URI uri) {
    return null;
}
因此,对于抢占式身份验证,我们需要扩展
HttpComponentsMessageSender
,并实现该方法以提供所需的
上下文
,如Apache Commons文档所示:

protected HttpContext createContext(URI uri) {
    HttpHost targetHost = new HttpHost("localhost", 80, "http");
    CredentialsProvider credsProvider = new BasicCredentialsProvider();
    credsProvider.setCredentials(
         new AuthScope(targetHost.getHostName(), targetHost.getPort()),
         new UsernamePasswordCredentials("username", "password"));

    AuthCache authCache = new BasicAuthCache();
    BasicScheme basicAuth = new BasicScheme();
    authCache.put(targetHost, basicAuth);


    HttpClientContext context = HttpClientContext.create();
    context.setCredentialsProvider(credsProvider);
    context.setAuthCache(authCache);
    return context;
}

当然,这个
上下文
必须缓存在实例级别,以便将来在每个
httpclient.execute()

中重用。谢谢。如果将服务器端口和凭据指定为自定义httpclient的一部分,是否需要使用凭据再次创建HttpComponentMessageSender?如果我正在创建bean-HttpClient=HttpClientBuilder.create().build();response=client.execute(新的HttpGet(URL\u受基本\u身份验证保护),上下文);我需要回复电话吗?返回的httpclient或上下文应该是什么?它将如何适应bean“httpComponentsMessageSender”4.6。抢占式身份验证--HttpGet-HttpGet=new-HttpGet(“/”);对于(int i=0;i<3;i++){CloseableHttpResponse response=httpclient.execute(targetHost,httpget,context);请尝试{HttpEntity entity=response.getEntity();}最后{response.close();}在上面的例子中,上下文是重要的还是httpclient?它在这里调用HttpGet。ws:outbound gateway呢?这是什么循环3?请参阅我的答案中的更新。很好。它可以工作。必须重写createConnection,并且必须扩展HttpComponents连接------公共类CustomHttpComponents连接扩展HttpComponents连接节{受保护的CustomHttpComponents连接(HttpClient、HttpPost、HttpContext、HttpContext){super(HttpClient、HttpPost、HttpContext);}谢谢。如果服务器端口和凭据被指定为自定义httpclient的一部分,我是否需要使用凭据再次创建HttpComponents MessageSender?如果我正在创建bean-httpclient client=HttpClientBuilder.create().build();response=client.execute(新建HttpGet(URL\u受基本\u身份验证保护),上下文);我需要响应行吗?返回的httpclient或上下文应该是什么?它将如何放入bean“HttpComponents消息源”4.6.抢占式身份验证--HttpGet HttpGet=new HttpGet(“/”);for(int I=0;I<3;I++){CloseableHttpResponse=httpclient.execute(targetHost,HttpGet,context);尝试{HttpEntity entity=response.getEntity();}最后{response.close();}在上面的例子中,上下文是重要的还是httpclient?它在这里调用HttpGet。ws:outbound gateway呢?这是什么循环3?请参阅我的答案中的更新。很好。它可以工作。必须重写createConnection,并且必须扩展HttpComponents连接------公共类CustomHttpComponents连接扩展HttpComponents连接节{受保护的CustomHttpComponents连接(HttpClient、HttpPost、HttpContext、HttpContext){super(HttpClient、HttpPost、HttpContext);}