Reputation: 1532
I'm working in an application that uses spring 3,2 and consume data from a rest api that requires only basic authentication... the thing is that I can't login to the api, all I get is 401.
The configuration is the following:
First, the credentials provider
<bean id="credentialProvider" class="org.apache.http.impl.client.BasicCredentialsProvider" />
Authorization scope for accessing restful service. Since we want this template to be used for everything, we are setting up it with defaults
<bean id="authScope" class="org.apache.http.auth.AuthScope">
<constructor-arg name="host"> <null /> </constructor-arg>
<constructor-arg name="port"> <value>-1</value> </constructor-arg>
<constructor-arg name="realm"> <null /> </constructor-arg>
<constructor-arg name="scheme"> <null /> </constructor-arg>
</bean>
Username and Password Credentials to access the api services
<bean id="credentials" class="org.apache.http.auth.UsernamePasswordCredentials">
<constructor-arg name="userName" value="${dataApi.username}"></constructor-arg>
<constructor-arg name="password" value="${dataApi.password}"></constructor-arg>
</bean>
Creating the credential provider
<bean id="methodInvoke" class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
<property name="targetObject" ref="credentialProvider" />
<property name="targetMethod" value="setCredentials" />
<property name="arguments">
<list>
<ref local="authScope" />
<ref local="credentials" />
</list>
</property>
</bean>
We have to use a proxy, so...
<bean id="proxyHttpClient" class="com.cibbva.commerce360.utils.ProxyHttpClient">
<constructor-arg name="host" value="${proxy.hostname}" />
<constructor-arg name="port" value="${proxy.port}" />
<constructor-arg name="user" value="${proxy.username}" />
<constructor-arg name="pass" value="${proxy.password}" />
<constructor-arg name="conman" ref="clientConnectionManager"></constructor-arg>
<property name="credentialsProvider" ref="credentialProvider" />
</bean>
The clientConnectionManager it's defined as:
<bean id="clientConnectionManager" class="org.apache.http.impl.conn.PoolingClientConnectionManager">
<property name="defaultMaxPerRoute" value="${dataAPi.connection.maxPerRoute}"></property>
<property name="maxTotal" value="${dataAPi.connection.maxTotal}"></property>
</bean>
And finally the requestFactory and restTemplate:
<bean id="requestFactory" class="org.springframework.http.client.HttpComponentsClientHttpRequestFactory">
<constructor-arg ref="proxyHttpClient" />
</bean>
<bean id="restTemplate" class="org.springframework.web.client.RestTemplate">
<constructor-arg name="requestFactory" ref="requestFactory" />
</bean>
I think that the problem is because the Authorization parameter isn't being added to the header of the request, looking in debug mode, I see the following:
DEBUG org.apache.http.headers - >> GET /xxxx/xxxxxx?xxxx HTTP/1.1
DEBUG org.apache.http.headers - >> Accept: application/json, application/*+json
DEBUG org.apache.http.headers - >> Host: hostname
DEBUG org.apache.http.headers - >> Connection: Keep-Alive
DEBUG org.apache.http.headers - >> User-Agent: Apache-HttpClient/4.2.3 (java 1.5)
DEBUG org.apache.http.wire - << "HTTP/1.1 401 No Autorizado[\r][\n]"
As can you see, there isn't auth information in the header. To discard the possibility of wrong username and password, I use curl to make the same request:
curl -v --user 'username:pasword' https://xxxx/xxxxxx?xxxx
The output is:
SSL certificate verify ok.
Server auth using Basic with user 'user'
GET xxxx/xxxxxx?xxxx HTTP/1.1
Authorization: Basic Y29tL....
User-Agent: curl/7.29.0
Host: hostname
Accept: */*
HTTP/1.1 404 No Encontrado
To summarize, how can I add the parameter Authorization
to the header of my request?
Thank you so much!
Upvotes: 2
Views: 2363
Reputation: 1532
Ok, I've finally got a solution to this problem. What I've done is create a class that implements ClientHttpRequestInterceptor, and then put the Authorization Header manually, the code is something like:
public class RequestHeaderIntercepter implements ClientHttpRequestInterceptor{
@Override
public ClientHttpResponse intercept(HttpRequest request, byte[] body,
ClientHttpRequestExecution execution) throws IOException {
HttpRequestWrapper requestWrapper = new HttpRequestWrapper(request);
requestWrapper.getHeaders().set("Authorization", "encoded username:password");
return execution.execute(request, body);
}
}
After that, you have to register the listener to the restTemplate and that's all! The request is intercepted and the Authorization parameter is added to the header.
Upvotes: 1