본문 바로가기

개발이야기

[Spring Security] 테스트 환경에서 동작하는 로그인인증이 운영서버에 적용시 안되는 경우 확인작업

spring security로 프로젝트를 진행했었는데, 로그인시 개발 PC에서는 문제가 없는데, 운영서버에 적용할때  일부 사용자들이 로그인할 때 문제가 발생함. 
몇가지 테스트 진행하다가 원인을 못찾아서 우선 CustomAuthenticationProvider를 추가해서 해당 회원들의 경우에 대해서 우선 몇가지 인증을 더 추가해서 로그인하게 만들어놨으나, 찝찝하다. 
 
우선 chatgpt의 도움을 받아서 정리를 해놓았는데, 내가 확인한 부분도 있고, 아직 확인을 못한부분도 있어서 정리해놓음.
 
ChatGPT

BCryptPasswordEncoder를 사용하여 Spring Security로 암호화된 비밀번호 인증을 할 때, 로컬 개발 환경에서는 문제가 없지만 운영 서버에서 인증이 안 되는 경우가 발생하는 주요 원인은 다음과 같습니다:

1. BCryptPasswordEncoder 버전 차이

  • 원인: 로컬과 운영 서버에서 사용 중인 BCryptPasswordEncoder의 버전이 다를 수 있습니다. Spring Security 버전에 따라 BCryptPasswordEncoder의 동작이 미묘하게 달라질 수 있는데, 특히 인코딩된 해시 문자열 포맷이 달라질 수 있습니다.
  • 해결 방법: 로컬과 운영 서버에서 동일한 버전의 Spring Security 및 BCryptPasswordEncoder를 사용하고 있는지 확인하세요. 의도치 않게 서로 다른 버전이 사용되고 있다면, 동일한 버전으로 맞춰야 합니다.

2. Salt 값 및 해시 결과의 차이

  • 원인: BCryptPasswordEncoder는 내부적으로 랜덤한 salt 값을 사용하여 암호화합니다. 일반적으로 동일한 비밀번호를 매번 암호화하더라도 결과가 다르게 나타납니다. 그러나 이 과정에서 운영 환경의 서버 설정이나 JVM 환경에 따라 비밀번호 해시 생성이 제대로 이루어지지 않거나, 일관성이 없을 수 있습니다.
  • 해결 방법: BCryptPasswordEncoder는 비밀번호와 해시를 비교할 때 자동으로 salt를 고려하므로, salt 값을 수동으로 관리할 필요는 없습니다. 다만, 운영 환경에서 JVM 버전이나 다른 설정이 문제가 될 수 있으므로, 로컬 환경과 운영 환경이 동일한 설정을 갖추도록 확인합니다.

3. 비밀번호 저장 방식의 문제 (평문 vs 해시)

  • 원인: 운영 서버의 데이터베이스에 저장된 비밀번호가 BCrypt로 암호화되지 않은 경우가 있습니다. 예를 들어, 비밀번호를 평문으로 저장했거나, 다른 방식으로 해시된 비밀번호가 저장된 경우 인증이 실패하게 됩니다.
  • 해결 방법: 데이터베이스에 저장된 비밀번호가 반드시 BCryptPasswordEncoder로 암호화된 상태인지 확인하세요. 이를 위해 BCrypt로 인코딩된 비밀번호는 $2a$로 시작하는 문자열 형식을 가지므로, 저장된 비밀번호가 이 형식을 따르는지 확인해 볼 수 있습니다.

4. 환경 변수 차이

  • 원인: BCryptPasswordEncoder는 인코딩 작업에 많은 리소스를 요구하는데, 운영 환경에서는 시스템 환경 변수나 보안 설정 등에서 제한을 걸어둘 가능성이 있습니다. 특히 Strength(강도) 값을 높게 설정한 경우, 인코딩이나 매칭 과정이 느려져 인증이 실패할 수 있습니다.
  • 해결 방법: BCryptPasswordEncoder의 강도 인자 (constructor parameter)로 지정된 숫자가 너무 높은 경우(예: 12 이상), 이를 10 이하로 낮춰 리소스를 줄여보세요. 기본값은 보통 10입니다.

5. 운영 서버의 Charset 문제

  • 원인: 운영 서버와 로컬 환경의 Charset 설정이 다를 수 있습니다. 예를 들어, 로컬에서는 UTF-8이지만 운영 서버에서는 다른 문자 인코딩을 사용할 경우, BCryptPasswordEncoder가 암호화된 문자열을 다르게 해석할 수 있습니다.
  • 해결 방법: 서버에서 JVM의 문자 인코딩 설정을 로컬 환경과 동일하게 설정하세요 (-Dfile.encoding=UTF-8).

6. 데이터베이스의 마이그레이션 문제

  • 원인: 로컬에서 암호화된 비밀번호를 데이터베이스에 저장한 후 운영 서버로 마이그레이션할 때, 인코딩 과정에서 데이터가 잘못되었거나 일부가 손실될 수 있습니다. 예를 들어, 운영 서버로 데이터를 옮기는 과정에서 인코딩 설정이 달라지거나 데이터가 손상될 수 있습니다.
  • 해결 방법: 데이터베이스 마이그레이션 시 모든 비밀번호 필드가 올바르게 이동되었는지, 인코딩 오류 없이 저장되었는지 검토합니다.

7. 서버 간의 JVM 환경 차이

  • 원인: BCryptPasswordEncoder의 동작은 JVM의 특정 설정에 영향을 받을 수 있습니다. 예를 들어 운영 서버의 JVM이 로컬과 다른 버전을 사용하거나, 특정 보안 패치로 인해 동작이 달라질 수 있습니다.
  • 해결 방법: 운영 서버와 로컬 개발 환경의 JVM 버전을 일치시키고, 동일한 JVM 옵션을 사용하는 것이 좋습니다.

문제 해결을 위한 점검 체크리스트

  1. Spring Security 버전을 운영 서버와 로컬이 동일하게 사용하고 있는지 확인합니다.
  2. 데이터베이스의 비밀번호 필드가 BCrypt로 인코딩된 문자열인지 확인합니다.
  3. Charset 설정이 로컬 환경과 운영 환경에서 동일한지 확인합니다.
  4. BCryptPasswordEncoder의 강도 인자가 지나치게 높지 않은지 확인합니다.
  5. JVM 환경 (버전, 옵션 등)이 일치하는지 점검합니다.

이렇게 각 부분을 하나씩 점검해 보면 원인을 파악할 수 있을 것입니다.