7장. 사용자 스토리지 SPI
User Storage SPI를 사용하여 Red Hat Single Sign-On에 확장을 작성하여 외부 사용자 데이터베이스 및 자격 증명 저장소에 연결할 수 있습니다. 기본 제공 LDAP 및 ActiveDirectory 지원은 이 SPI를 구현하는 것입니다. Red Hat Single Sign-On은 기본적으로 로컬 데이터베이스를 사용하여 사용자를 생성, 업데이트 및 조회하고 자격 증명을 검증합니다. 하지만 조직에서 Red Hat Single Sign-On의 데이터 모델로 마이그레이션할 수 없는 기존 외부 독점 사용자 데이터베이스가 있는 경우가 많습니다. 이러한 상황에서 애플리케이션 개발자는 User Storage SPI 구현을 작성하여 Red Hat Single Sign-On이 사용자에게 로그인하고 관리하는 데 사용하는 내부 사용자 개체 모델 및 외부 사용자 저장소를 연결할 수 있습니다.
Red Hat Single Sign-On 런타임에서 사용자를 검색해야 하는 경우(예: 사용자가 로그인할 때) 사용자를 찾으려면 여러 단계를 수행합니다. 먼저 사용자가 사용자 캐시에 있는지 확인합니다. 사용자가 발견되면 메모리 내 표현을 사용합니다. 그런 다음 Red Hat Single Sign-On 로컬 데이터베이스 내에서 사용자를 찾습니다. 사용자를 찾을 수 없는 경우 사용자 스토리지 SPI 공급자 구현을 반복하여 런타임 중 원하는 사용자를 반환할 때까지 사용자 쿼리를 수행합니다. 공급자는 외부 사용자 저장소에서 사용자를 쿼리하고 사용자의 외부 데이터 표현을 Red Hat Single Sign-On의 사용자 메타 모델에 매핑합니다.
또한 사용자 스토리지 SPI 공급자 구현은 복잡한 기준 쿼리를 수행하거나, 사용자에 대한 CRUD 작업을 수행하거나, 자격 증명을 검증 및 관리하거나, 여러 사용자의 대규모 업데이트를 한 번에 수행할 수 있습니다. 이는 외부 저장소의 기능에 따라 달라집니다.
사용자 스토리지 SPI 공급자 구현은 패키지화되어 자karta EE 구성 요소와 유사하게 배포됩니다. 기본적으로 활성화되어 있지 않지만 관리 콘솔의 User Federation
탭에서 영역별로 활성화 및 구성해야 합니다.
사용자 공급자 구현에서 일부 사용자 속성을 사용자 ID 연결/설정을 위한 메타데이터 속성으로 사용하는 경우 사용자가 속성을 편집할 수 없고 해당 속성이 읽기 전용인지 확인하십시오. 예시는 LDAP_ID
속성으로, 기본 제공 Red Hat Single Sign-On LDAP 공급자가 LDAP 서버 측에 사용자 ID를 저장하기 위해 사용하고 있는 LDAP_ID 속성입니다. 위협 모델 완화 장에서 자세한 내용을 참조하십시오.
7.1. 공급자 인터페이스
User Storage SPI 구현을 빌드할 때 공급자 클래스 및 공급자 팩토리를 정의해야 합니다. 공급자 클래스 인스턴스는 공급자 팩토리에 의해 트랜잭션별로 생성됩니다. 공급자 클래스는 사용자 조회 및 기타 사용자 작업의 과도한 리프팅을 수행합니다. org.keycloak.storage.UserStorageProvider
인터페이스를 구현해야 합니다.
package org.keycloak.storage; public interface UserStorageProvider extends Provider { /** * Callback when a realm is removed. Implement this if, for example, you want to do some * cleanup in your user storage when a realm is removed * * @param realm */ default void preRemove(RealmModel realm) { } /** * Callback when a group is removed. Allows you to do things like remove a user * group mapping in your external store if appropriate * * @param realm * @param group */ default void preRemove(RealmModel realm, GroupModel group) { } /** * Callback when a role is removed. Allows you to do things like remove a user * role mapping in your external store if appropriate * @param realm * @param role */ default void preRemove(RealmModel realm, RoleModel role) { } }
UserStorageProvider
인터페이스가 상당히 스파스라고 생각할 수 있습니까? 이 장의 뒷부분에서 공급자 클래스에서 사용자 통합의류를 지원하기 위해 구현할 수 있는 다른 혼합 인터페이스가 있음을 확인할 수 있습니다.
UserStorageProvider
인스턴스는 트랜잭션당 한 번 생성됩니다. 트랜잭션이 완료되면 UserStorageProvider.close()
메서드가 호출되고 인스턴스가 가비지 수집됩니다. 인스턴스는 공급자 팩토리에서 생성합니다. 공급자 팩토리에서 org.keycloak.storage.UserStorageProviderFactory
인터페이스를 구현합니다.
package org.keycloak.storage; /** * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a> * @version $Revision: 1 $ */ public interface UserStorageProviderFactory<T extends UserStorageProvider> extends ComponentFactory<T, UserStorageProvider> { /** * This is the name of the provider and will be shown in the admin console as an option. * * @return */ @Override String getId(); /** * called per Keycloak transaction. * * @param session * @param model * @return */ T create(KeycloakSession session, ComponentModel model); ... }
공급자 팩토리 클래스는 UserStorageProviderFactory
를 구현할 때 구체적인 공급자 클래스를 템플릿 매개변수로 지정해야 합니다. 런타임에서 이 클래스를 인트로스펙션하여 해당 기능(구현하는 다른 인터페이스)을 검사하므로 필수입니다. 예를 들어 공급자 클래스 이름이 FileProvider
인 경우 factory 클래스는 다음과 같아야 합니다.
public class FileProviderFactory implements UserStorageProviderFactory<FileProvider> { public String getId() { return "file-provider"; } public FileProvider create(KeycloakSession session, ComponentModel model) { ... }
getId()
메서드는 User Storage 공급자의 이름을 반환합니다. 이 ID는 특정 영역에 대한 공급자를 활성화하려는 경우 관리 콘솔의 사용자 페더 페이지에 표시됩니다.
create()
메서드는 공급자 클래스의 인스턴스를 할당합니다. org.keycloak.models.KeycloakSession
매개변수를 사용합니다. 이 오브젝트는 다른 정보 및 메타데이터를 조회하고 런타임 내의 다른 다양한 구성 요소에 대한 액세스를 제공하는 데 사용할 수 있습니다. ComponentModel
매개변수는 특정 영역 내에서 공급자가 활성화 및 구성된 방법을 나타냅니다. 여기에는 활성화된 공급자의 인스턴스 ID와 관리 콘솔을 통해 활성화할 때 지정할 수 있는 구성이 포함되어 있습니다.
UserStorageProviderFactory
에는 다른 기능이 있으며 이 기능은 이 장의 뒷부분에서 설명합니다.