HTTPS 리다이렉트와 톰캣 서버 충돌 문제

Soyun_p·2025년 3월 19일

💣🔧트러블슈팅

목록 보기
3/5
post-thumbnail

코드

💡

Spring Boot 애플리케이션에서 HTTPS(SSL/TLS)를 활성화하고, HTTP 요청을 HTTPS로 자동 리다이렉트 하도록 설정하는 역할을 한다

	@Bean
	public ServletWebServerFactory servletContainer() {
		
		TomcatServletWebServerFactory tomcat = new TomcatServletWebServerFactory() {
			
			@Override
			protected void postProcessContext(Context context) {
				SecurityConstraint securityConstraint = new SecurityConstraint();
				securityConstraint.setUserConstraint("CONFIDENTIAL");
				SecurityCollection collection = new SecurityCollection();
				collection.addPattern("/*");
				securityConstraint.addCollection(collection);
				context.addConstraint(securityConstraint);
			}
		};
		tomcat.addAdditionalTomcatConnectors(httpToHttpsRedirectConnector());

		return tomcat;
	}

🔹 @Bean 어노테이션을 통해 Spring 컨테이너에서 ServletWebServerFactory 빈을 등록한다

🔹 Tomcat 서블릿 웹 서버 팩토리를 생성하고 설정한다

🔹 postProcessContext 메서드를 오버라이드하여 보안 제약 조건을 설정한다

🔹 SecurityConstrait 를 생성하고 ‘CONFIDENTIAL” 제약 조건을 설정한다. 이는 해당 URL 패턴에 대해 보안 연결(HTTPS)이 필요함을 의미한다

🔹SecurityCollection 를 생성하고 “/*” 패턴(모든 URL)을 추가한다

🔹 이 보안 컬렉션을 보안 제약 조건에 추가한다

🔹 최종적으로 이 보안 제약 조건은 Tomcat 컨텍스트에 추가한다

🔹 HTTP에서 HTTPS로의 리다이렉트 커넥터를 추가한다

private Connector httpToHttpsRedirectConnector() {
		Connector connector = new Connector(TomcatServletWebServerFactory.DEFAULT_PROTOCOL);
		connector.setScheme("http");
		connector.setPort(8080);
		connector.setSecure(false);
		connector.setRedirectPort(443);

		return connector;
	}

🔹 HTTP 프로토콜을 사용하는 새로운 Tomcat 커넥터를 생성한다

🔹 이 커넥터의 스킴을 ‘http’로 설정한다

🔹 이 커넷터가 8080 포트에서 HTTP 요청을 수신하도록 설정한다

🔹 이 커넥터는 보안 연결이 아님을 명시한다(setSecure(false))

🔹 리다이렉트 포트를 443(HTTPS의 기본 포트)으로 설정한다. 이는 HTTP 요청이 들어오면 HTTPS(433 포트)로 자동 리다이렉트됨을 의미한다


문제

📌 Application을 Run 하니 8080 포트를 사용 중이라고 뜬다

***************************
APPLICATION FAILED TO START
***************************

Description:

Web server failed to start. Port 8080 was already in use.

Action:

Identify and stop the process that's listening on port 8080 or configure this application to listen on another port.

8080 포트 충돌이 발생하는 원인

✅ 코드 구조로 인한 문제

🔹 위 코드에서 httpToHttpsRedirectionConnector() 메서드를 통해 명시적으로 8080 포트를 HTTP 연결용으로 설정하고 있다

🔹 Spring Boot 는 기본적으로 8080 포트를 사용하려고 시도한다

🔹 따라서 Spring Boot 가 기본 커넥터를 위해 8080 포트를 바인딩하려고 시도하는 동시에, 코드에서 추가한 HTTP 리다이렉트 커넥터도 8080 포트를 사용하려고 시도할 수 있다

✅ 서버 구성 충돌

🔹 Tomcat 은 기본적으로 8080 포트를 사용하려고 한다

🔹코드에서 TomcatServletWebServeFactory 를 커스터마이징하면서 추가 커넥터를 설정했지만, 기본 커넥터와 포트 설정이 충돌할 수 있다


내가 한 삽질

📌 처음에는 해당 코드를 localhost:8080으로 접속하면 https로 리다이렉트하는 단순한 코드로 생각했다
📌 그런데 알고 보니 내부에서 톰캣을 띄우는 코드였고, 점심 먹고 온 후 갑자기 동작하지 않아 원인을 찾는 데 어려움을 겪었다

문제 상황
1️⃣ 서버 포트를 8081로 변경하니 정상 동작했다
2️⃣ 그 후 "http → https"로 리다이렉트하는 부분도 8081로 변경 (변경해야하는 줄 알았다ㅠ)

connector.setPort(8080); => connector.setPort(8081);

3️⃣ 하지만 계속 "포트가 사용 중"이라는 오류 발생

해결 과정
1️⃣ 문제를 2시간 동안 반복해서 점검하다가 코드 자체에 문제가 있음을 인지했다
2️⃣ 내부 톰캣을 실행하는 부분을 주석 처리하니 정상 동작!!!

✨결론: 잘 작동하던 코드가 갑자기 안 되니 원인을 쉽게 파악하기 어려웠다. 결국 내부 톰캣 실행 코드가 문제였음을 발견하고 해결했다.

해결 방법

✅ application.properties 또는 application.yml 에서 서버 포트 변경

server.port=8443
server:
	port:8443

🔹 이렇게 하면 Spring Boot 의 기본 커넥터가 8443 포트를 사용하게 되어 8080 포트와의 충돌을 피할 수 있다 ⇒ 굳이 8443 아니어도 된다 (8080만 아니면 되는듯)

✅ 실행 중인 프로세스 확인 및 종료

🔹 Windows: 명령 프롬프트(powershell에서 진행했다) : netstat -ano | findstr 8080 으로 8080 포트를 사용중인 프로세스 확인 후 종료

🔹 Mac/Linux : 터미널에서 lsof -i 8080 으로 확인 후 종료

✅ 코드 수정

🔹 HTTP 리다이렉트 커넥터에 다른 포트 번호 사용

connector.setPort(8081);

0개의 댓글