当前位置: 首页 > 知识库问答 >
问题:

Spring RestTem板收到"401未授权"

寿亦
2023-03-14

我在Spring 4中使用以下内容通过RestTemplate检索JSON:

protected DocInfoResponse retrieveData(String urlWithAuth) {
    RestTemplate restTemplate = new RestTemplate();
    HttpHeaders headers = new HttpHeaders();
    headers.add("Authorization", "Basic " + auth.getSig());
    HttpEntity<String> request = new HttpEntity<String>(headers);
    ResponseEntity<DocInfoResponse> response = restTemplate.exchange(urlWithAuth, HttpMethod.GET, request, DocInfoResponse.class);
    return response.getBody();
}

我使用相同的代码(具有不同的响应类)成功地从相同的站点获得JSON文档(具有不同的参数以获得不同的文档)。

当我执行上述代码时,我收到以下堆栈跟踪(部分):

Caused by: org.springframework.web.client.HttpClientErrorException: 401 Unauthorized 
at 
org.springframework.web.client.DefaultResponseErrorHandler.handleError(DefaultResponseErrorHandler.java:91) ~[spring-web-4.3.7.RELEASE.jar:4.3.7.RELEASE]

有人能告诉我为什么这可能会收到异常吗?

共有3个答案

阴元青
2023-03-14

对于基本身份验证,创建授权标头的过程相对简单,因此几乎可以通过几行代码手动完成:

 HttpHeaders createHeaders(String username, String password){
   return new HttpHeaders() {{
         String auth = username + ":" + password;
         byte[] encodedAuth = Base64.encodeBase64( 
            auth.getBytes(Charset.forName("US-ASCII")) );
         String authHeader = "Basic " + new String( encodedAuth );
         set( "Authorization", authHeader );
      }};
}

然后,发送请求变得同样简单:

RestTemplate restTemplate = new RestTemplate();    
restTemplate.exchange
     (uri, HttpMethod.POST, new HttpEntity<T>(createHeaders(username, password)), clazz);

https://www.baeldung.com/how-to-use-resttemplate-with-basic-authentication-in-spring#manual_auth

莘聪
2023-03-14

在调查了自己的问题后,我意识到FireFox RESTClient是成功的,因为我连接到了目标网址。我以为我正在使用的基本认证,毕竟不是那么基本。

最后,我读了我试图连接的应用程序的文档,意识到他们提出了一种连接令牌机制。现在它起作用了。

在阅读了您的代码之后,我说它看起来很好,尽管我不确定您调用的对象是什么auth

第一件事:尝试从任何客户端访问您的服务,如web浏览器、邮递员或RESTClient。确保您在未连接到应用程序的情况下成功检索信息!!!

根据结果,我建议你要么尝试手动加密你的授权令牌(你很容易在这个网站上找到帖子来告诉你如何加密),要么尝试另一种连接机制

尚宏硕
2023-03-14

我发现我最初在上面发布的问题是由于authparams上发生了双重加密。我通过使用UriComponentsBuilder并在exchange()上显式调用encode()解决了这个问题。

SyncResponse retrieveData(UriComponentsBuilder builder) {
    RestTemplate restTemplate = new RestTemplate();
    HttpHeaders headers = new HttpHeaders();
    headers.set("Accept", MediaType.APPLICATION_JSON_VALUE);
    HttpEntity<String> request = new HttpEntity<String>(headers);
    ResponseEntity<SyncResponse> response = restTemplate.exchange(builder.build().encode().toUri(), HttpMethod.GET, request, SyncResponse.class);
    return response.getBody();
} 

MyUriComponentsBuilder是通过以下方式构建的:

UriComponentsBuilder buildUrl(String urlString) {
    UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(urlString);

    return auth.appendAuth(builder);
}

(auth.appendAuth()在urlString中添加目标服务所需的其他.queryParams()

执行此操作的调用是retrieveData(buildUrl(urlString))

 类似资料:
  • 当处理webhook时,我得到一个未经授权的401,我使用Spring Security和Vaadin 和 我知道我需要公开我的endpoint /通知 如何公开endpoint? 已更新 引发消息 2022-06-10 17:39:30.040WARN 37089 --- [ restartedMain]ConfigServletWebServerApplication Context:在上下文

  • 我的代码:GoogleCredential凭据 credential.refreshToken() 错误日志: 创建服务号的步骤: 我在凭据中的oauth 2.0中创建了一个Web应用程序 然后我用客户端ID创建了一个服务号 现在我正在使用这个服务号和从它生成的p12证书来验证和创建Google凭据的对象 一旦刷新令牌,我就给了我401例外。 在这种情况下,任何帮助都会受到感激

  • 我正在SpringBoot应用程序中使用SpringREST模板。 即使我正在传递凭据,我也总是收到未经授权的错误。 我可以通过ChromeREST Web Service Client访问此服务。 在SpringBoot中是否有访问REST模板的简化方法。 下面是到目前为止完成的导致401错误的代码片段 RestClientConfig类 错误:

  • 我想使用爪哇谷歌驱动器API。我尝试了这段代码: 但是我得到了这个错误: 我使用以下配置: 你能告诉我怎么解决这个问题吗?

  • null null 使用NodePort服务公开Keycloak。 应用程序使用istio入口网关公开。 Keycloak服务器版本:9.0.0。

  • 我试图测试Firebase Cloud messaging APIs,因为控制台没有提供所有功能(特别是当应用程序在后台时定制通知)。但由于某些原因,我无法让它工作,它总是显示401错误。我调查了出现这种情况的原因,并在重新生成新的服务器密钥后进行了尝试,但错误仍然存在。令人惊讶的是,当我生成一个新的服务器密钥时,它没有反映在Firebase控制台中,它将服务器密钥显示为空。此外,我尝试添加我的I