LDAP 인증 성공 뒤 발생한 사용자 정보 누락 처리

사용자 입력을 LDAP에서 확인하고 애플리케이션 세션과 속성 검증으로 이어가는 인증 흐름

실무에서 LDAP 로그인을 처음 다룰 때는 인증을 외부 디렉터리에 위임하면 로그인 흐름 대부분이 끝난다고 생각했다. 실제 장애는 비밀번호 확인 다음 단계에서 발생했다. LDAP bind는 성공했지만, 애플리케이션이 사용자 화면을 구성하는 데 필요했던 displayName 속성이 응답에 없어서 로그인 처리가 NullPointerException으로 끝났다.

고객사의 HR 시스템이 직원 정보를 관리하고 LDAP과 동기화하는 구조였다. 우리 쪽에서는 고객사 직원 정보를 임의로 만들거나 수정할 수 없었다. 인증은 성공했는데 로그인 후처리가 실패한 이유는, 애플리케이션이 LDAP 속성의 존재를 보장된 조건으로 취급했기 때문이다.

LDAP이 맡은 일과 애플리케이션이 맡은 일

이 구성에서 LDAP은 사용자가 보낸 자격 증명을 확인하고 디렉터리 속성을 제공했다. 로그인 성공 이후 세션이나 애플리케이션 토큰을 발급하고, 서비스 안의 권한을 결정하는 일은 애플리케이션 책임으로 남았다.

사용자 ID와 비밀번호
  → LDAP bind로 자격 증명 확인
  → 필요한 디렉터리 속성 조회
  → 애플리케이션 내부 사용자 식별·권한 연결
  → 세션 또는 토큰 생성

이 경계를 분리하면 LDAP 응답의 속성이 바뀌거나 누락될 때 어느 단계가 실패했는지 추적하기 쉽다. bind 성공만 확인하고 다음 단계로 넘기기보다, 애플리케이션이 반드시 필요로 하는 속성과 선택 가능한 속성을 구분해야 한다.

장애 원인과 당시 임시 대응

운영 로그를 확인했을 때 누락된 displayName은 이메일 주소의 @ 앞부분과 일치하는 값으로 보완할 수 있었다. 서비스가 로그인 화면을 계속 제공해야 했기 때문에, 해당 속성이 비어 있을 때 이메일의 로컬 부분을 표시 이름으로 쓰는 임시 대응을 적용했다.

String displayName = ldapAttributes.get("displayName");
if (displayName == null || displayName.isBlank()) {
    String email = ldapAttributes.get("mail");
    displayName = email != null && !email.isBlank()
            ? email.split("@", 2)[0]
            : "unknown";
}

이 코드는 로그인 중단을 피하기 위한 표시값 fallback이지, LDAP의 원본 데이터가 복구됐다는 뜻은 아니다. 고객사와 속성 동기화 원인을 확인하는 동안 서비스 연속성을 확보한 임시 조치로 봐야 한다.

표시 이름을 계정 식별자로 쓰지 않는다

이메일의 @ 앞부분은 사람이 보는 이름으로 편리할 수 있지만, 계정의 고유 식별자로 쓰기에는 위험하다. 이메일 주소가 바뀌거나 로컬 부분이 중복될 수 있고, 빈 값·예상하지 못한 형식이 들어올 수도 있다. 권한 부여와 계정 연결은 변경되지 않는 사번이나 디렉터리 고유 ID처럼 별도로 합의된 식별자를 사용하고, displayName은 화면 표시 목적으로만 취급하는 편이 안전하다.

또한 "unknown" 같은 기본값을 여러 사용자에게 그대로 저장하면 검색·중복 검사에서 모든 사용자가 같은 이름처럼 보일 수 있다. 표시할 기본 문자열과 영속 사용자 프로필의 값을 구분하고, 누락된 속성과 대체값 사용 여부를 개인정보가 드러나지 않는 방식으로 기록해야 한다.

다음에 같은 연동을 설계한다면

로그인 전후의 필수 속성 목록과 누락 처리 정책을 고객사와 함께 정하고, 개발·운영 환경에서 속성 누락 응답을 테스트하겠다. LDAP bind 성공 여부, 속성 조회 여부, 내부 사용자 연결 여부를 서로 다른 단계로 로그에 남기되 비밀번호와 민감한 디렉터리 값을 기록하지 않는다.

당시에는 fallback으로 로그인 흐름을 살리는 것이 급했다. 지금 다시 보면 외부 인증 시스템의 응답을 그대로 믿지 않고, 속성 계약을 검증한 뒤 우리 서비스의 사용자 모델로 변환하는 경계가 필요했다. 토큰을 발급한 뒤 이전 토큰이 다시 허용되는 문제는 Access Token 세대 검증 기록에 정리했다.