使用RestTemplate进行基本身份验证(3.1)

时间:2013-01-17 16:08:37

标签: java spring-mvc basic-authentication apache-httpclient-4.x resttemplate

我正在尝试使用Java重现以下curl命令:

curl -v -u user:pass http://myapp.com/api

此命令返回一些JSON数据。

我的错误Java实现如下:

@Test
public void callTest() {
    RestTemplate restTemplate = createRestTemplate("user", "pass");
    URI uri = new URI("http://myapp.com/api");
    String res = restTemplate.getForObject(uri, String.class);
}

private static RestTemplate createRestTemplate(String username, String password) {

    UsernamePasswordCredentials cred = new UsernamePasswordCredentials(username, password);
    BasicCredentialsProvider cp = new BasicCredentialsProvider();
    cp.setCredentials(AuthScope.ANY, cred);
    DefaultHttpClient client = new DefaultHttpClient();
    client.setCredentialsProvider(cp);
    ClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory(client);

    RestTemplate restTemplate = new RestTemplate(factory);
    // set the media types properly
    return restTemplate;
}

然而,当我执行测试时,它会返回org.springframework.web.client.HttpClientErrorException: 401 Unauthorized例外。

登录DEBUG时,我看不到有关身份验证的信息......

设置身份验证凭据时我做错了什么?

4 个答案:

答案 0 :(得分:13)

使用

进行实例化
HttpClient client = new HttpClient();

不再存在,并且版本4.3 中的 HttpComponents HttpClient 弃用了类DefaultHttpClient。所以其他答案要么无效要么被弃用。这是我的版本,我为需要基本身份验证的休息请求编写了这个类:

import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.CredentialsProvider;
import org.apache.http.client.HttpClient;
import org.apache.http.impl.client.BasicCredentialsProvider;
import org.apache.http.impl.client.HttpClients;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.web.client.RestTemplate;

public class RestClient extends RestTemplate {
    public RestClient(String username, String password) {
        CredentialsProvider credsProvider = new BasicCredentialsProvider();
        credsProvider.setCredentials(
                new AuthScope(null, -1),
                new UsernamePasswordCredentials(username, password));
        HttpClient httpClient = HttpClients.custom().setDefaultCredentialsProvider(credsProvider).build();
        setRequestFactory(new HttpComponentsClientHttpRequestFactory(httpClient));
    }
}

然后使用它,例如:

RestClient restClient = new RestClient("username", "password");

String result = restClient.postForObject(...

答案 1 :(得分:1)

我做这样的事情 - 它对我有用:

private RestTemplate createRestTemplate(String username, String password) {
    return new RestTemplate(this.createSecureTransport(username, password));
}

protected ClientHttpRequestFactory createSecureTransport(String username, String password){
    HttpClient client = new HttpClient();
    UsernamePasswordCredentials credentials = new UsernamePasswordCredentials(username,password);
    client.getState().setCredentials(AuthScope.ANY, credentials);
    CommonsClientHttpRequestFactory commons = new CommonsClientHttpRequestFactory(client);

    return commons;
}

在此处使用:Reference Code

答案 2 :(得分:1)

httpclient v4.0不支持抢占式身份验证

看看这个: http://forum.springsource.org/showthread.php?123385-Preemptive-Basic-Authentication-with-RestTemplate

在春天Source找到了这个解决方案。

它对我有用。

看看这个:RestTemplate with Basic Auth in Spring 3.1

答案 3 :(得分:1)

这个答案基于@kevinpeterson的答案,但重写使用更新的Apache HTTP客户端。

RestTemplate createRestTemplate(String username, String password, String host, int port ) {
    return new RestTemplate(this.createSecureTransport( username, password, host, port ));
}

ClientHttpRequestFactory createSecureTransport( String username, String password, String host, int port ){
    DefaultHttpClient client = new DefaultHttpClient();
    UsernamePasswordCredentials credentials = new UsernamePasswordCredentials( username, password );
    client.getCredentialsProvider().setCredentials( new AuthScope( host, port ), credentials );
    return new HttpComponentsClientHttpRequestFactory(client);