从 docker 容器执行时,SpringBoot RestTemplate 返回 403 禁止

Posted

技术标签:

【中文标题】从 docker 容器执行时,SpringBoot RestTemplate 返回 403 禁止【英文标题】:SpringBoot RestTemplate return 403 forbidden when executing from docker container 【发布时间】:2020-11-14 23:09:33 【问题描述】:

我正在尝试使用 Java 代码实现 Spring Boot RestTemplate 并调用外部 REST 服务。这是作为 java 应用程序工作,但是当我 在 docker 容器中部署相同的代码时出现错误

org.springframework.web.client.HttpClientErrorException$Forbidden: 403 Forbidden: [error code: 1010]

这是我的代码..独立运行..

@RequestMapping(value = "/extservice", 
                    produces = MediaType.APPLICATION_JSON_VALUE, 
                    method = RequestMethod.GET)
    public User httpcall() 
        
        ResponseEntity<User> result = null;
         
        try 
             
            HttpHeaders headers = new HttpHeaders();
            headers.add("user-agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (Khtml, like Gecko) Chrome/54.0.2840.99 Safari/537.36");
            headers.setAccept(Arrays.asList(MediaType.APPLICATION_JSON));
            headers.setContentType(MediaType.APPLICATION_JSON);
            HttpEntity<Object> entity = new HttpEntity<Object>(headers);
            final String uri = "https://reqres.in/api/users/2";
            RestTemplate restTemplate = new RestTemplate();
             
            result = restTemplate.getForEntity(uri, User.class);
             
            System.out.println(result.toString());
         

         catch (Exception e) 

            e.printStackTrace();
        
        
        return result.getBody();

    

这是错误堆栈跟踪

org.springframework.web.client.HttpClientErrorException$Forbidden: 403 Forbidden: [error code: 1010]
    at org.springframework.web.client.HttpClientErrorException.create(HttpClientErrorException.java:109)
    at org.springframework.web.client.DefaultResponseErrorHandler.handleError(DefaultResponseErrorHandler.java:170)
    at org.springframework.web.client.DefaultResponseErrorHandler.handleError(DefaultResponseErrorHandler.java:112)
    at org.springframework.web.client.ResponseErrorHandler.handleError(ResponseErrorHandler.java:63)
    at org.springframework.web.client.RestTemplate.handleResponse(RestTemplate.java:782)
    at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:740)
    at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:674)
    at org.springframework.web.client.RestTemplate.getForEntity(RestTemplate.java:342)
    at com.dockerforjavadevelopers.hello.HelloController.httpcall(HelloController.java:38)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

....

2020-07-25 04:52:17.578 ERROR 1 --- [nio-9898-exec-4] o.a.c.c.C.[.[.[.[dispatcherServlet]      : Servlet.service() for servlet [dispatcherServlet] in context with path [/opa-test] threw exception [Request processing failed; nested exception is java.lang.NullPointerException] with root cause

java.lang.NullPointerException: null
    at com.dockerforjavadevelopers.hello.HelloController.httpcall(HelloController.java:48) ~[classes!/:0.1.0]
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_212]
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_212]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_212]
    at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_212]
    at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:190) ~[spring-web-5.2.6.RELEASE.jar!/:5.2.6.RELEASE]
    at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:138) ~[spring-web-5.2.6.RELEASE.jar!/:5.2.6.RELEASE]

这是我的 docker 文件

# Maven build container 

FROM maven:3.6.3-jdk-11-slim as mavenbuild

COPY pom.xml /tmp/

COPY src /tmp/src/

WORKDIR /tmp/

RUN mvn package

#pull base image

FROM openjdk:8-jdk-alpine

EXPOSE 9898

#default command
CMD java -jar /data/opa-test-0.1.0.jar

#copy hello world to docker image from builder image

COPY --from=mavenbuild /tmp/target/opa-test-0.1.0.jar /data/opa-test-0.1.0.jar

【问题讨论】:

你能显示docker文件吗 添加有问题..供参考..我可以从同一个微服务访问 ping 方法..它正在返回响应.. 你能卷曲你试图通过RestTemplate调用的endpoint吗? 另外,请在您使用 HTTPS 时查看此内容,it 可能会有所帮助。 我正在尝试这样做..但令人惊讶的是,它在作为应用程序运行 [不在容器中] 但在 docker 容器中失败时工作正常 【参考方案1】:

您已创建 HttpHeaders 对象但未使用。 请使用 RestTemplate 的交换方式。

HttpHeaders headers = new HttpHeaders();
headers.add("user-agent", "Application");
headers.setAccept(Arrays.asList(MediaType.APPLICATION_JSON));
headers.setContentType(MediaType.APPLICATION_JSON);
HttpEntity<String> entity = new HttpEntity<>(headers);
ResponseEntity<String> responseJson = restTemplate.exchange(resourceUrl, HttpMethod.GET, entity, String.class);

【讨论】:

以上是关于从 docker 容器执行时,SpringBoot RestTemplate 返回 403 禁止的主要内容,如果未能解决你的问题,请参考以下文章

SpringBoot @RestController 无法从 docker 容器外部访问

如何从不同的 docker 容器中读取 Spring Boot 应用程序属性?

无法从 docker 容器内的 Spring Boot 连接到 Redis

『中级篇』docker之java容器运行外置springboot-jar(番外篇)(79)

Docker:Springboot 容器无法连接到 PostgreSql 容器

docker生成springboot镜像