강의

멘토링

커뮤니티

Cộng đồng Hỏi & Đáp của Inflearn

Hình ảnh hồ sơ của ddolddoli
ddolddoli

câu hỏi đã được viết

Ứng dụng kiến trúc microservice (MSA) phát triển với Spring Cloud

Kiểm tra

도커 컨테이너로 동작할 때 user-service에서 403 forbidden 오류 관련

Viết

·

321

1

유사한 질문이 있어서 도움이 될 수 있을까 찾아 봤지만 해당 github에 접근할 수 없었고(아마 삭제한 듯), chat GPT를 통해서 답을 얻을 수 있을까 질문을 해 봤지만 해결책이 나오지 않아서 대략 1주일 이상을 헤매고 있었습니다.

그런데 강사님이 다른 분의 질문에 답을 주신 것을 보고 user-service의 SecurityConfig.java 파일에서

.requestMatchers("/**").access(
        new WebExpressionAuthorizationManager("hasIpAddress('127.0.0.1') or hasIpAddress('172.18.0.5') or hasIpAddress('192.168.0.172')")) // ip address of my pc
.anyRequest().authenticated()

위의 코드처럼 나의 pc의 ip address를 포함하니 더이상 403 오류가 발생하지 않더군요. 그래서 결국에는 내 pc의 ip address를 포함해야 하는구나라고 생각했습니다. 그런데 동일한 코드를 다른 pc(이 pc에서도 계속해서 403 오류 발생했었음)에서 구동시켰더니 내 pc의 ip address를 변경시키지 않았음에도 403 오류 발생 없이 잘 동작하더군요. 그동안 무엇이 문제였을까요? 물론 github에 올라가 있는 configuration 파일에서도 gateway의 ip adddress를 172.18.0.5로 지정했고, SecurityConfig.java에서도 위의 코드같이 172.18.0.5를 포함했었습니다.

spring-bootspring-cloudmsadocker-container403-forbidden

Câu trả lời 2

0

저는 도커로 배포할때 도커 내부 네트워크 ip 지정 안해주니까 게이트웨이에서 user-service 로 로드 밸런싱이 안되더라구요

아래 코드처럼 내부 아이피도 추가 해주니까 도커에서 정상동작하기 시작했습니다!

이틀만에 해결한거라,, 처음으로 q&n올려봅니다!

@Bean
    protected SecurityFilterChain configure(HttpSecurity http) throws Exception
    {// 권한 관련 메소드
        // Configure AuthenticationManagerBuilder
        AuthenticationManagerBuilder authenticationManagerBuilder =
                http.getSharedObject(AuthenticationManagerBuilder.class);
        authenticationManagerBuilder.userDetailsService(userService).passwordEncoder(bCryptPasswordEncoder);

        AuthenticationManager authenticationManager = authenticationManagerBuilder.build();
        http.csrf( (csrf) -> csrf.disable());

        http.authorizeHttpRequests((authz) -> authz
                                .requestMatchers(new AntPathRequestMatcher("/actuator/**")).permitAll()
                                .requestMatchers(new AntPathRequestMatcher("/actuator/**")).permitAll()
                                .requestMatchers(new AntPathRequestMatcher("/h2-console/**")).permitAll()
                                .requestMatchers(new AntPathRequestMatcher("/users", "POST")).permitAll()
                                .requestMatchers(new AntPathRequestMatcher("/welcome")).permitAll()
                                .requestMatchers(new AntPathRequestMatcher("/health-check")).permitAll()
                                .requestMatchers(new AntPathRequestMatcher("/swagger-ui/**")).permitAll()
                                .requestMatchers(new AntPathRequestMatcher("/swagger-resources/**")).permitAll()
                                .requestMatchers(new AntPathRequestMatcher("/v3/api-docs/**")).permitAll()
//                        .requestMatchers("/**").access(this::hasIpAddress)
//                                .requestMatchers("/**").access(
//                                        new WebExpressionAuthorizationManager(
//                                                "hasIpAddress('127.0.0.1') " +
//                                                "or hasIpAddress('192.168.45.83')"+
//                                                "or hasIpAddress('172.17.0.0/32')")) // host pc ip address
//                                .anyRequest().authenticated()
                // IP 주소 체크와 로그 찍기
                            .requestMatchers("/**").access((authentication, httpServletRequest) -> {
                                    // 클라이언트 IP 주소 가져오기
                                    String clientIp = httpServletRequest.getRequest().getRemoteAddr();
                                    log.info("Request from IP: {}", clientIp);  // 로그 출력

                                    // IP 주소가 허용된 범위 내인지 확인
                                    if (clientIp.equals("127.0.0.1") || clientIp.equals("192.168.45.83") || clientIp.startsWith("172.18.")) {
                                        log.info("Access granted for IP: {}", clientIp);  // 허용된 IP에 대한 로그
                                        return new AuthorizationDecision(true);  // 인증 통과
                                    } else {
                                        log.warn("Access denied for IP: {}", clientIp);  // 허용되지 않은 IP에 대한 로그
                                        return new AuthorizationDecision(false);  // 인증 실패
                                    }
                                })
                                .anyRequest().authenticated()
                )
                .formLogin(Customizer.withDefaults())
                .authenticationManager(authenticationManager);
//                .sessionManagement((session) -> session
//                        .sessionCreationPolicy(SessionCreationPolicy.STATELESS));

        http.addFilter(getAuthenticationFilter(authenticationManager));
        http.headers((headers) -> headers.frameOptions((frameOptions) -> frameOptions.sameOrigin()));

        return http.build();
    }

0

Dowon Lee님의 프로필 이미지
Dowon Lee
Người chia sẻ kiến thức

안녕하세요, 이도원입니다.

답변이 늦어 죄송합니다.

먼저, WebExpressionAuthorizationManager 에 등록 된 IP Address 가 어떤 주소인지 확인해 보는 게 필요할 것 같습니다. 127.0.0.1은 Loopback이니까 생략하도록 하고, 172.18.0.5 하고 192.168.0.172 2개가 PC1 번의 물리적인 Network(Wireless 등)IP 인지? Docker 컨테이너에 발급 된 IP 인지? Gateway의 IP를 지정했기 때문인지? 등을 확인해 봐야할 것 같습니다. PC2번과 IP 또는 컨테이너의 IP 등의 확인이 필요할 것 같습니다. 만약 같은 공유기에 연결 된 PC가 아니라, 다른 공유기나 다른 장소의 PC라면 말씀하신 것처럼 작동되지는 않을 거라 생각됩니다.

추가 질문사항 있으시면 다시 글 남겨 주세요.

감사합니다.

Hình ảnh hồ sơ của ddolddoli
ddolddoli

câu hỏi đã được viết

Đặt câu hỏi