Java/오류노트

[Java/오류노트] Solved - Keycloak : HTTP 409 Conflict 해결방법

adjh54 2025. 2. 4. 20:02
728x170
해당 글에서는 Keycloak 통신 중에 발생하는 HTTP 409 Conflict 오류에 대해 해결 방법에 대해 알아봅니다.


 

1) 문제점


💡 문제점

- Keycloak에 사용자 정보를 수정하는 중에 아래와 같은 HTTP 409 Conflict 에러가 발생하였습니다.
- 이는 리소스 충돌이 발생할때 나타나는 HTTP 상태 코드입니다.

 

💡 아래와 같이 이메일을 변경하는 중에 발생하였습니다.

- Keycloak Admin Client를 통해서 이메일을 변경하려고 할때, 디버깅 중 아래와 같은 오류가 발생하였습니다,
UserRepresentation emailCredential = new UserRepresentation();
emailCredential.setEmail(chgDecodeEmail);
try {
  // Keycloak Admin API를 사용해 이메일 재설정
  keycloak.realm(realmName)
          .users()
          .get(infoUserUUid)
          .update(emailCredential); // 변경정보
} catch (Exception e) {
  result.setRtnMsg("이메일 변경 중 오류가 발생했습니다.");
  return result;
}

 

 

 

2) 해결방법


 💡 해결방법

- 해당 문제는 아래와 같은 경우에 발생할 수 있습니다.

1. 이미 다른 사용자가 사용 중인 이메일 주소로 변경을 시도할 때
2. 이메일 변경 요청과 동시에 다른 업데이트가 발생하여 데이터 충돌이 발생할 때
3. Keycloak의 이메일 고유성(Uniqueness) 제약 조건 위반

- 이를 위해서는 해당 처리에 대해서 Exception 처리가 추가적으로 필요합니다.

 

💡 적용 예시

- 아래와 같이, 사용자 이름(username)과 이메일 주소(email)을 변경하는 경우 409 에러에 대한 중복 발생에 따라 클라이언트에게 전달을 해주도록 변경해야합니다.

- 이 중, WebApplicationException를 통해서 HTTP 기반 통신에서 발생하는 오류를 처리하기 위한 기본 예외 클래스를 적용하였습니다.
UserRepresentation emailCredential = new UserRepresentation();
emailCredential.setEmail(chgDecodeEmail);
try {
    // Keycloak Admin API를 사용해 이메일 재설정
    keycloak.realm(realmName)
            .users()
            .get(infoUserUUid)
            .update(emailCredential); // 변경 정보
} catch (WebApplicationException e) {
    if (e.getResponse().getStatus() == 409) {
        result.setRtnMsg("이미 사용 중인 이메일 주소입니다.");
    } else {
        result.setRtnMsg("사용자 정보 업데이트 중 오류가 발생했습니다.");
    }
    return result;
}

 

💡 [참고] Keycloak에서 중복을 허용하지 않는 사용자 항목은?

- Username (사용자 이름), Email (이메일 주소)

- 이러한 제약은 사용자 식별과 보안을 위해 필수적이며, 이는 대부분의 IAM(Identity and Access Management) 시스템에서 공통적으로 적용되는 정책입니다.

 

 

💡사전 작업 필요

- 사전에 이메일을 변경하기 직전에 이메일 중복 체크를 수행하는 부분을 추가해주어야 합니다.
 // [Keycloak] 이메일 중복 조회
  List<UserRepresentation> existingUsers;
  try {
      existingUsers = keycloak.realm(realmName)
              .users()
              .searchByEmail(paramEmail, true);
  } catch (Exception e) {
      result.setRtnMsg("이메일 중복 조회 중 오류가 발생했습니다.");
      return result;
  }

  // [Valid] 중복되는 이메일 확인
  if (!existingUsers.isEmpty()) {
      result.setRtnMsg("중복되는 이메일이 있습니다.");
      return result;
  }

 

 

 

 

오늘도 감사합니다 😀

그리드형