使用spring restTemplate的REST API的基本身份验证


83

我在RestTemplate中是全新的,基本上在REST API中也是如此。我想通过Jira REST API在我的应用程序中检索一些数据,但返回401未经授权。找到了有关jira rest api文档的文章,但实际上并不知道如何将其重写为java,因为该示例使用curl的命令行方式。我将不胜感激任何建议或建议如何重写:

curl -D- -X GET -H "Authorization: Basic ZnJlZDpmcmVk" -H "Content-Type: application/json" "http://kelpie9:8081/rest/api/2/issue/QA-31"

使用Spring Rest模板导入Java。其中ZnJlZDpmcmVk是用户名:密码的base64编码的字符串。非常感谢你。



2
curl支持开箱即用的身份验证,您只需要告诉它用户名和密码curl -u fred:fred,就不需要笨拙的手动标题。春天也是如此。
divanov

Answers:


148

取自本网站示例,我认为通过填写标头值并将标头传递给模板,这将是最自然的方法。

这是为了填写标题Authorization

String plainCreds = "willie:p@ssword";
byte[] plainCredsBytes = plainCreds.getBytes();
byte[] base64CredsBytes = Base64.encodeBase64(plainCredsBytes);
String base64Creds = new String(base64CredsBytes);

HttpHeaders headers = new HttpHeaders();
headers.add("Authorization", "Basic " + base64Creds);

这是将标头传递给REST模板:

HttpEntity<String> request = new HttpEntity<String>(headers);
ResponseEntity<Account> response = restTemplate.exchange(url, HttpMethod.GET, request, Account.class);
Account account = response.getBody();

1
谢谢-这对我有用。我必须指出,如果您不想使用org.apache.commons.codec.binary.Base64类,而您想使用android Base64类:import android.util.Base64 ;,则可以替换上面的一行:byte [] base64CredsBytes = Base64.encode(plainCredsBytes,Base64.DEFAULT);
西蒙(Simon)

@jhadesdev嗨,这在执行GET请求时对我有用。尽管在发布时无法给出403。你能帮助我吗?
Stefano Cazzola,2015年

7
Java 8您可以使用Base64.getMimeEncoder()。encodeToString()
Matt Broekhuis

92

您可以使用spring-boot RestTemplateBuilder

@Bean
RestOperations rest(RestTemplateBuilder restTemplateBuilder) {
    return restTemplateBuilder.basicAuthentication("user", "password").build();
}

查看文件

(在SB 2.1.0之前是#basicAuthorization


1
你救了我的日子。非常感谢。
riccardo.cardin

4
谢谢!这是最快,最简单的方法。
Rajkishan Swami

1
是。这是最快的方法。不需要其他依赖项。
Janath

3
@自2.1.0版本起不推荐使用#basicAuthentication(字符串用户名,字符串密码)
rjdkolb

1
这不是一个好的解决方案,因为它会向通过发送的每个请求都添加一个授权标头RestTemplate
attacomsian

22

(也许)是不导入spring-boot的最简单方法。

restTemplate.getInterceptors().add(new BasicAuthorizationInterceptor("user", "password"));

2
注意,使用拦截器会导致流式传输不再起作用。这是为什么:exchange()-> doExecute(),-> createRequest(),-> InterceptingHttpAccessor.getRequestFactory()(因为RestTemplateextends InterceptingHttpAccessor)。如果有拦截器,则getRequestFactory()返回 InterceptingClientHttpRequestFactory,创建InterceptingClientHttpRequest。这些扩展了AbstractBufferingClientHttpRequest`,它将输入流转换为byte [](移交给拦截器)。因此,InputStream实际上并未流式传输。
mconner

17

从Spring 5.1开始,您可以使用 HttpHeaders.setBasicAuth

创建基本授权标头:

String username = "willie";
String password = ":p@ssword";
HttpHeaders headers = new HttpHeaders();
headers.setBasicAuth(username, password);
...other headers goes here...

将标题传递给RestTemplate:

HttpEntity<String> request = new HttpEntity<String>(headers);
ResponseEntity<Account> response = restTemplate.exchange(url, HttpMethod.GET, request, Account.class);
Account account = response.getBody();

文档:https : //docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/http/HttpHeaders.html#setBasicAuth-java.lang.String-java.lang.String-


17

参考Spring Boot的TestRestTemplate实现如下:

https://github.com/spring-projects/spring-boot/blob/v1.2.2.RELEASE/spring-boot/src/main/java/org/springframework/boot/test/TestRestTemplate.java

特别是,请参见如下的addAuthentication()方法:

private void addAuthentication(String username, String password) {
    if (username == null) {
        return;
    }
    List<ClientHttpRequestInterceptor> interceptors = Collections
            .<ClientHttpRequestInterceptor> singletonList(new BasicAuthorizationInterceptor(
                    username, password));
    setRequestFactory(new InterceptingClientHttpRequestFactory(getRequestFactory(),
            interceptors));
}

同样,您可以RestTemplate轻松制作自己的

通过继承TestRestTemplate如下所示:

https://github.com/izeye/samples-spring-boot-branches/blob/rest-and-actuator-with-security/src/main/java/samples/springboot/util/BasicAuthRestTemplate.java


第一条链接通向404
Zarremgregarrok

14

有多种方法可以将基本的HTTP身份验证添加到 RestTemplate

1.对于单个请求

try {
    // request url
    String url = "https://jsonplaceholder.typicode.com/posts";

    // create auth credentials
    String authStr = "username:password";
    String base64Creds = Base64.getEncoder().encodeToString(authStr.getBytes());

    // create headers
    HttpHeaders headers = new HttpHeaders();
    headers.add("Authorization", "Basic " + base64Creds);

    // create request
    HttpEntity request = new HttpEntity(headers);

    // make a request
    ResponseEntity<String> response = new RestTemplate().exchange(url, HttpMethod.GET, request, String.class);

    // get JSON response
    String json = response.getBody();

} catch (Exception ex) {
    ex.printStackTrace();
}

如果您使用的是Spring5.1或更高版本,则不再需要手动设置授权标头。使用headers.setBasicAuth()方法代替:

// create headers
HttpHeaders headers = new HttpHeaders();
headers.setBasicAuth("username", "password");

2.对于一组请求

@Service
public class RestService {

    private final RestTemplate restTemplate;

    public RestService(RestTemplateBuilder restTemplateBuilder) {
        this.restTemplate = restTemplateBuilder
                .basicAuthentication("username", "password")
                .build();
    }

   // use `restTemplate` instance here
}

3.对于每个请求

@Bean
RestOperations restTemplateBuilder(RestTemplateBuilder restTemplateBuilder) {
    return restTemplateBuilder.basicAuthentication("username", "password").build();
}

希望对您有所帮助!


最佳答案。每种都很好。
Rishi

6

而不是实例化如下:

TestRestTemplate restTemplate = new TestRestTemplate();

像这样做:

TestRestTemplate restTemplate = new TestRestTemplate(user, password);

它对我有用,希望对您有所帮助!


TestRestTemplate似乎没有升级春天开机后工作到1.3.x版
维韦克塞西

1
这不是应该用于单元测试而不发布代码吗?
戴维·布拉德利

0

使用setBasicAuth定义的凭据

HttpHeaders headers = new HttpHeaders();
headers.setBasicAuth("myUsername", myPassword);

然后根据自己的喜好创建请求。

例:

HttpEntity<String> request = new HttpEntity<String>(headers);
ResponseEntity<String> response = restTemplate.exchange(url, HttpMethod.GET, 
request, String.class);
String body = response.getBody();

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.