인프런 커뮤니티 질문&답변

Truestar님의 프로필 이미지

작성한 질문수

Spring Cloud로 개발하는 마이크로서비스 애플리케이션(MSA)

User Microservice

도커 컨테이너 기동 후 `user-service` 회원 생성 시 `403 Forbidden` 원인

해결된 질문

작성

·

986

1

강사님  좋은 강의 감사합니다.


1달간 긴 클라우드 스터디 장정끝에 마지막 순간에 멈춰버렸습니다.ㅠㅠ 유저 생성시점에서 접근이 안되는 이유가 분명 설정의 문제라 생각이 들지만, 어디서 부터 찾아 고쳐야 될지 찾지못해, 부득이 하게 질문을 남기게 되었습니다.

문제 :
로컬에서 테스트를 마친 후 정상상태로 도커 마운트 시점 이후회원등록이 안됩니다. Access Denied 가 아닌것이라서 더욱 찾기가 애매해집니다

403 Forbidden 은 Client 가 URI 도달이 가능함에도
Server 에서 접근금지 처리가 된 상태라고 알게 되었습니다.

그래서 Gateway 설정에 의심이 갔었는데요, 어찌 바꿔야 될지 갈피가 잡히지 않습니다.

  • api-gatewayu-service > application.yml > 라우트설정
    - id: user-service
    uri: lb://USER-SERVICE
    predicates:
    - Path=/user-service/login
    - Method=POST
    filters:
    - RemoveRequestHeader=Cookie
    - RewritePath=/user-service/(?<segment>.*), /$\{segment}
    - id: user-service
    uri: lb://USER-SERVICE
    predicates:

    - Path=/user-service/users
    - Method=GET, POST
    filters:

    - RemoveRequestHeader=Cookie
    -
    RewritePath=/user-service/(?<segment>.*), /$\{segment}
    - id: user-service
    uri: lb://USER-SERVICE
    predicates:
    - Path=/user-service/actuator/**
    - Method=GET
    filters:
    - RemoveRequestHeader=Cookie
    - RewritePath=/user-service/(?<segment>.*), /$\{segment}
    - id: user-service
    uri: lb://USER-SERVICE
    predicates:
    - Path=/user-service/**
    - Method=GET
    filters:
    - RemoveRequestHeader=Cookie
    - RewritePath=/user-service/(?<segment>.*), /$\{segment}
    - AuthorizationHeaderFilter



아래는 깃헙Config 설정상태 입니다.

저의 PC IP 입니다 - 192.168.1.197

    • GitHub 설정 상태 - link: GitHub: spring-cloud-config

      gateway: ip: 설정값 요약
        • 172.18.0.1
          - application.yml
          - ecommerce.yml

        • 172.18.0.5(실패)
          192.168.1.197(실패)

          - user-service.yml
          - order-service.yml

  • HTTP Request 테스트

    POST  
    192.168.1.197/user-service/users 요청 Response
    HTTP/1.1 403 Forbidden
    transfer-encoding: chunked
    Set-Cookie: JSESSIONID=286DBBDF9D7EF3B4F96C4D7F9E8C7C62; Path=/; HttpOnly
    X-Content-Type-Options: nosniff
    X-XSS-Protection: 1; mode=block
    Cache-Control: no-cache, no-store, max-age=0, must-revalidate
    Pragma: no-cache
    Expires: 0
    Content-Type: application/json
    Date: Sun, 27 Jun 2021 07:37:13 GMT

    {
    "status": 403,
    "error": "Forbidden",
    "message": "",
    "path": "/users"
    }
  • api-gateway-service 서버 로그
    : 회원 가입데이터 요청시점

    • Global POST filter End: response status code -> 403 FORBIDDEN
      Global PRE filter base message: Spring Cloud Gateway Global Filter
      Global PRE filter Start: request id -> d7f70d5e-1

  • user-servercie 서버 로그
    • 도달하지 못했으므로, 로그 없음


놓친것은 없는데, 사소한 어딘가의 IP 미스매치로, 접근 금지 필터링이 된듯한 느낌같은 느낌이 참 힘이듭니다...
이것에 대해 조언을 구할 수 있을까요?

애러 해결 시도

      • 깃허브의 yml 파일 의 gateway: ip: 실패한 케이스
          • - user-service.yml
            - order-service.yml
              • 172.18.0.5(실패)
              • 172.18.0.5  --->   127.0.0.1(실패)
              • 172.18.0.5  --->   192.168.1.197(실패)

이번에도 메일에 프로젝트 파일 첨부해 보내드렸습니다.

읽어주셔서 감사합니다.

답변 2

0

lulala님의 프로필 이미지

2021. 07. 28. 20:52

저도 같은 오류가 뜨는데 혹시 해결하셨나요??

Truestar님의 프로필 이미지
Truestar
질문자

2021. 07. 30. 20:55

아직 해결은 안됬습니다.
클론코딩은 끝난 상태라, 미뤄뒀는데 딱 봐도 Security 설정 문제인 듯 해서
Security 공부중인데요, 해결되면 또 글 남겨놓으려구요.

lulala님의 프로필 이미지

2021. 07. 31. 13:34

같은 오류였는지 모르겠지만 저는 해결을 하였습니다.

스프링 시큐리티 문제였는데요

hasIpAddress 에 user-service의 ip가 들어가야 하기 때문에 docker에서 실행시킬때 동적으로 ip가 들어가야 한다고 생각하였습니다. 이게 좀 번거러워서 저는 peramitAll()을 하여 403에러는 해결하였습니다.

Truestar님의 프로필 이미지
Truestar
질문자

2021. 07. 31. 14:31

저도 permitAll은 가능하지만 아닌방법으로 해결되면 올려보려구요

cnw529님의 프로필 이미지

2021. 10. 06. 18:22

hasIpAddress에 전달되는 값으로는 IP Address뿐만이 아닌 Local Subnet이 전달될 수 있습니다.

따라서 다음과 같이 도커 네트워크 생성 시 설정한 서브넷을 전달하는 것으로 해결 가능합니다.

.hasIpAddress("172.18.0.0/16")

이렇게 전달하게 되면 apigateway-service 할당되는 ip에 관계없이 문제를 해결할 수 있으리라 생각합니다.

Truestar님의 프로필 이미지
Truestar
질문자

2021. 10. 10. 17:07

cnw529 님의 가이드 덕분에 완벽히 잘 작동합니다!
좋은 정보 공유 감사드립니다
저는 엄한 Security 문제라고만 생각해서 Security  를 파고있었네요..ㅠ

서브넷과 관련된 건 도커 내부 네트워크 구조와 같은것을 추가적으로 공부해야 되는건가요?

cnw529님의 프로필 이미지

2021. 10. 11. 19:47

저도 공부하는 입장이라 정확한 답변을 드릴 수는 없겠지만, 제가 이해한 바에 대해 말씀드리겠습니다.

hasIpAddress 메소드의 파라미터로 IP Address뿐만이 아닌 Local Subnet도 전달될 수도 있었으니 Security의 문제였다고 말할 수도 있겠네요 :D

우선 도커 컨테이너는 Host OS 위에서 동작하는 도커 엔진이라는 가상화된 논리적 플랫폼 위에서 동작하고 있습니다.  즉, Host PC의 자원 역시도 가상화되어 공유한 채로 사용하게 됩니다. 이러한 측면에서 Docker Container 들은 도커 내부적으로 논리적 IP를 부여받게 되고, 이를 외부에 노출하기 위해서는 Host PC의 포트와 포트 포워딩을 하게 됩니다.

또한 본 강의에서 만든 User-Service는 ApiGateway-Service를 통해 모든 요청을 전달 받게 됩니다.

즉, Host PC 외부와의 통신이 아닌 도커 상의 ecommerce-network라는 동일한 네트워크를 사용하는 컨테이너 간의 통신이기 때문에 저는 hasIpAddress 메소드의 파라미터로 ecommerce-network의 Local Subnet을 전달하면 되겠다고 판단하였습니다.

만약 User-Service가 Host PC 외부의 Client로 부터 직접 요청을 받게 되거나, 도커 상에서 다른 네트워크를 사용하는 서비스와의 통신을 하게된다면  hasIpAddress 메소드의 파라미터 ecommerce-network의 Local Subnet이 아닌 다른 IP Address나 Subnet을 전달하게 될 것 입니다.

따라서, 만들고 계신 서비스들의 구조와 통신 과정을 잘 판단해서 hasIpAddress 메소드의 파라미터를 설정하시는 것이 맞다고 생각합니다.

 

Truestar님의 프로필 이미지
Truestar
질문자

2021. 10. 11. 20:56

디테일한 설명 감사드립니다. 도커 서브넷구성이 로컬환경의 연동에 핵심이었군요..

많은 도움이 되었습니다^^

0

Truestar님의 프로필 이미지
Truestar
질문자

2021. 06. 28. 13:12

  • 도커 내부 apigateway-service 할당 IP 상황
    $ docker inspect api-gateway-service


  • config-service 의 웹 상의 user-service configuation 정보
    http://192.168.1.197:8888/user-service/default



  • user-service 의 WebSecurity.java
    .hasIpAddress("127.0.0.1") 실패
    .hasIpAddress("172.18.0.5") 실패
    public class WebSecurity extends WebSecurityConfigurerAdapter {
    ...
    ...
    protected void configure(HttpSecurity http) throws Exception {
    http.authorizeRequests().antMatchers("/actuator/**").permitAll();
    http.authorizeRequests().antMatchers("/**")
    .hasIpAddress("192.168.1.197")
    ...
    ...
    }
    }

추가 적으로 user-service/actuator/info  는 잘 접근합니다.

미흡한 설정 정보를 추가했습니다

Truestar님의 프로필 이미지

작성한 질문수

질문하기