使用 spring restTemplate 对 REST API 进行基本身份验证
Posted
技术标签:
【中文标题】使用 spring restTemplate 对 REST API 进行基本身份验证【英文标题】:Basic authentication for REST API using spring restTemplate 【发布时间】:2014-03-22 03:09:35 【问题描述】:我是 RestTemplate 的新手,基本上也是 REST API 的新手。我想通过 Jira REST API 在我的应用程序中检索一些数据,但返回 401 Unauthorized。在jira rest api documentation 上找到并发表文章,但不知道如何将其重写为 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 编码字符串。非常感谢。
【问题讨论】:
另见***.com/questions/9376549/… curl 支持开箱即用的身份验证,您只需告诉它用户名和密码curl -u fred:fred
,无需笨重的手动标头。 Spring 也是如此。
【参考方案1】:
取自example on this site,我认为这是最自然的做法,通过填写标头值并将标头传递给模板。
这个是填表头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();
【讨论】:
谢谢 - 这对我有用。我必须指出,如果您不想使用 org.apache.commons.codec.binary.Base64 类,而是想使用 android Base64 类:import android.util.Base64;,您可以替换上面一行: byte[] base64CredsBytes = Base64.encode(plainCredsBytes, Base64.DEFAULT); @jhadesdev 嗨,这在执行 GET 请求时对我有用。虽然它在发布时未能给出 403。你能帮帮我吗? java 8 你可以使用 Base64.getMimeEncoder().encodeToString()【参考方案2】:你可以使用 spring-boot RestTemplateBuilder
@Bean
RestOperations rest(RestTemplateBuilder restTemplateBuilder)
return restTemplateBuilder.basicAuthentication("user", "password").build();
见documentation
(在 SB 2.1.0 之前它是 #basicAuthorization
)
【讨论】:
你拯救了我的一天。非常感谢。 谢谢!这是最快最简单的方法。 是的。这是最快的方法。不需要额外的依赖项。 这不是一个好的解决方案,因为它会为通过RestTemplate
发送的每个请求添加一个授权标头。【参考方案3】:
有多种方法可以将基本 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();
如果您使用的是Spring 5.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();
希望对你有帮助!
【讨论】:
最佳答案。每个都是善良的。【参考方案4】:从 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-
【讨论】:
【参考方案5】:(也许)不导入 spring-boot 的最简单方法。
restTemplate.getInterceptors().add(new BasicAuthorizationInterceptor("user", "password"));
【讨论】:
请注意,使用拦截器会导致流式传输不再有效。原因如下:exchange()
-> doExecute()
, -> createRequest()
, -> InterceptingHttpAccessor.getRequestFactory()
(因为 RestTemplate
扩展了 InterceptingHttpAccessor
)。如果有拦截器,getRequestFactory()
返回一个InterceptingClientHttpRequestFactory
,它会创建InterceptingClientHttpRequest
s。这些扩展了 AbstractBufferingClientHttpRequest`,它将输入流转换为 byte[](传递给拦截器)。因此,InputStream 实际上并没有流式传输。【参考方案6】:
参考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【参考方案7】:而不是像下面这样实例化:
TestRestTemplate restTemplate = new TestRestTemplate();
就这样吧:
TestRestTemplate restTemplate = new TestRestTemplate(user, password);
对我有用,希望对你有帮助!
【讨论】:
将 Spring Boot 升级到 1.3.x 后,TestRestTemplate 似乎无法正常工作 这不是应该用于单元测试而不是发布代码吗?【参考方案8】:使用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();
【讨论】:
***.com/a/53394971 答案的副本【参考方案9】:HttpHeaders headers = new HttpHeaders();
headers.setBasicAuth(username, password);
然后继续这里其他人提到的相同程序:
HttpEntity<String> request = new HttpEntity<String>(headers);
ResponseEntity<String> response = restTemplate.exchange(url, HttpMethod.GET,
request, String.class);
【讨论】:
以上是关于使用 spring restTemplate 对 REST API 进行基本身份验证的主要内容,如果未能解决你的问题,请参考以下文章
Spring - WebClient & RestTemplate