Keycloak SSO 통합
개요
이 가이드는 오프라인(air-gapped) 온프레미스 환경에서 Keycloak Single Sign-On (SSO)을 Glasswall Halo 플랫폼과 통합하기 위한 단계별 지침을 제공합니다.
이 가이드는 이미 Single Node Halo 플랫폼(예: Proxmox 또는 ESXi를 통해 VM에)을 배포했으며, 이제 Keycloak을 사용해 OIDC 기반 SSO를 활성화하려는 상황을 전제로 합니다.
다음 방법을 알아봅니다:
- 오프라인 환경에서 HTTPS를 사용하는 Keycloak 서버를 설정합니다(사전 로드된 컨테이너 이미지 사용 또는 수동 VM 설치).
- 제공된
glasswall-realm.jsonKeycloak 구성을 가져와 사용자 지정합니다. - Keycloak와 Halo 모두에 대해 TLS 인증서 및 DNS/호스트 이름 확인을 구성합니다.
- Deploy the Halo portal and related services:
cdrplatform-portalcdrplatform-portalaccesscdrplatform-api-access
Glasswall Halo의 Keycloak SSO 통합 가이드
- 사전 요구 사항
- 1단계 - Glasswall Halo SSO용 keycloak 구성
- 2단계 - TLS 인증서 및 DNS 고려 사항
- 3단계 - Keycloak SSO로 Halo 서비스 배포(Helm 구성)
- 4단계 - SSO 통합 검증 및 테스트
- 5단계 - 문제 해결
필수 조건
환경 요구 사항
- 이 설정은 에어갭 환경 또는 엄격한 온프레미스 환경을 대상으로 합니다.
- Single Node Halo 클러스터가 이미 배포되어 있어야 합니다.
- 내부 DNS 확인이 구성되어 있어야 하며, 로컬 DNS 서버를 사용하거나
/etc/hosts항목을 통해 수동으로 설정할 수 있습니다. - Keycloak은 호스트 또는 가상 머신에 로컬로 설치되어 있어야 합니다. → Keycloak 문서 및 설치
필수 리소스
- Glasswall Support에서 제공하는 사전 구성된 realm 파일(
glasswall-realm.json)입니다, Glasswall Support. - Single Node Halo cluster 내 배포를 위한 Halo Helm charts에 대한 로컬 액세스.
DNS/hosts 구성
Keycloak 서버의 hostname이 클라이언트 머신과 Halo platform 구성 요소 모두에서 확인 가능하도록 하십시오.
- 내부 DNS 사용 시: Keycloak 서버의 IP address를 가리키는
keycloak.dev.local용 A record를 생성합니다. - 내부 DNS가 없는 경우: 액세스가 필요한 각 머신의
hosts파일에 다음 항목을 추가합니다:
1단계 - Glasswall Halo SSO용 Keycloak 구성
Glasswall는 Halo의 SSO에 필요한 realm, clients, roles 및 scopes를 정의하는 Keycloak realm 구성(JSON 파일 형식)을 제공합니다.
수동 설정을 피하기 위해 이 구성을 가져올 수 있습니다. 오프라인 설정에서는 Keycloak Admin UI를 통해 이를 수행하십시오.
1.1 - Glasswall realm 구성 가져오기
A. realm export 가져오기: glasswall-realm.json라는 이름의 파일이 있어야 합니다. 이 파일에는 Halo의 SSO용 realm 설정이 포함되어 있습니다.
Glasswall realm 요약
Glasswall realm에는 다음과 같은 사전 구성 항목이 포함되어 있습니다:
-
Realm ID: Glasswall
-
클라이언트
- Halo-portal-client
- Halo-API-access
- Halo-portal-access
-
주요 역할
- Realm 수준: admin, user
- 클라이언트 수준: Halo 클라이언트 admin 및 user 역할.
- 클라이언트 scope(매퍼로 사전 구성됨):
- Portaluserscope: 토큰에 필요한 클레임(roles, email).
-
토큰 수명
- SSO 세션 유휴 시간 초과: 30분
-
인증: 표준 사용자 이름/비밀번호.
B. Keycloak Admin에 로그인
- 웹 브라우저를 사용하여
https://<KEYCLOAK_HOST>:8443/의 Keycloak Admin Console로 이동한 다음 master admin 계정으로 로그인합니다.

C. realm 가져오기.
- 관리자 콘솔에서 현재 "Master"로 표시된 드롭다운을 선택한 다음 Create realm을 클릭합니다.

- Create realm 화면에서 Import를 선택하고
glasswall-realm.json파일을 업로드합니다.

- Keycloak will parse the file and populate the realm name (e.g.,
glasswall).- 가져오기를 확인합니다.

D. realm 설정 확인
- After import, review key settings and ensure:
- Realm 이름은
glasswall입니다. - Realm이 활성화되어 있습니다.
- SSL required: 일반적으로
external로 설정됩니다. - Clients should include:
halo-portal-clienthalo-portal-accesshalo-api-access
- Realm 이름은

1.2 클라이언트 설정 사용자 지정(호스트 이름 및 리디렉션 URI)
다음으로, 각 Halo 클라이언트에 대해 환경에 맞게 구성을 업데이트합니다.
Halo-portal-client (포털 프런트엔드)

Valid redirect URIs: realm JSON의 placeholder 도메인을 실제 포털 도메인으로 바꾸십시오. 샘플 구성은 테스트 도메인(예: https://pvetest.cdr.glasswall.dev/authentication/login-callback)을 사용합니다. 사용자가 Halo 포털에 액세스할 때 사용할 URL과 일치하도록 이 값을 업데이트하십시오.
예를 들어, Halo 포털이 https://halo.dev.local/에서 사용 가능하고 애플리케이션의 로그인 콜백 경로가 /authentication/login-callback인 경우 다음과 같이 설정합니다:
- Valid redirect URIs:
https://halo.dev.local/authentication/* - Web origins:
https://halo.dev.local - 루트 URL (선택 사항):
https://halo.dev.local - 유효한 로그아웃 후 리디렉션 URI:
https://halo.dev.local/authentication/logout-callback

Halo-portal-access (포털 백엔드)
- Valid redirect URIs: (e.g.,
https://pvetest.cdr.glasswall.dev/*)- 이를 포털 도메인으로 업데이트합니다.
- Web origins:
https://halo.dev.local
Halo-API-access
- 리디렉션 설정은 그대로 두고, 각 클라이언트의 설정을 저장합니다.

1.3 사용자 생성 및 역할 할당
이제 사용자를 생성하고 Halo 역할을 할당합니다.

A. glasswall realm에서 Users → Add user로 이동합니다.
B. Username 및 세부 정보를 입력합니다.
C. Credentials 섹션에서 비밀번호를 설정하고 "Temporary"를 선택 해제합니다.
D. Role mappings에서 다음을 할당합니다:
- Realm roles:
AdminUser
- Client roles:
halo-portal-client[Admin, user]halo-api-access[Admin, user]halo-portal-access[Admin, user]

Admin 사용자는 다음을 볼 수 있습니다:

그리고 다음을 관리할 수 있습니다:

포함:

2단계 - TLS 인증서 및 DNS 고려 사항
모든 구성 요소에 대해 올바른 TLS 신뢰 및 DNS가 설정되어 있는지 확인합니다.
2.1 TLS 신뢰
Halo 플랫폼 서비스(Portal, Portal-Access, API-Access)는 Keycloak의 인증서를 신뢰해야 합니다.
2.2 DNS 및 /etc/hosts
다음을 확인합니다:
- 모든 서비스와 사용자에 대해 Keycloak 호스트명이 확인되어야 합니다.
- Halo 도메인도 확인되어야 합니다.
3단계 - Keycloak SSO와 함께 Halo 서비스 배포(Helm 구성)
Halo는 Helm을 통해 배포되며, 오프라인 환경에서는 시스템과 함께 번들된 차트를 사용합니다.
Halo portal 배포
portal_image_tag=$(k get deploy portal -o json | jq -r '.spec.template.spec.containers[0].image' | cut -d":" -f2)
portal_domain="glasswall.example.com"
keycloak_domain="keycloak.example.com"
helm upgrade --install cdrplatform-portal ./cdrplatform-portal \
--set image.tag="${portal_image_tag:?}" \
--set image.pullPolicy=IfNotPresent \
--set ingress.tls.enabled=true \
--set ingress.tls.domain="${portal_domain:?}" \
--set ingress.tls.secretName="tls-secret" \
--set configuration.BackendUrl="https://${portal_domain:?}" \
--set configuration.HaloVersion="2.12.0" \
--set configuration.EnabledPages="SystemSettings\,PolicySettings\,ValidationSettings" \
--set configuration.OIDC.ProviderOptions.Authority="https://${keycloak_domain:?}/realms/glasswall" \
--set configuration.OIDC.ProviderOptions.ClientId="halo-portal-client" \
--set configuration.OIDC.ProviderOptions.RedirectUri="https://${portal_domain:?}/authentication/login-callback" \
--set configuration.OIDC.ProviderOptions.PostLogoutRedirectUri="https://${portal_domain:?}/authentication/logout-callback" \
--set configuration.OIDC.ProviderOptions.Scope="openid profile api://cdrplatform-portal-access/PortalUserScope" \
--set configuration.OIDC.ProviderOptions.SilentCheckSsoRedirectUri="https://${portal_domain:?}/silent-check-sso.html" \
--set appenvironment.HTTP_CSP_FRAME_SRC="'self' https://${keycloak_domain:?} https://${portal_domain:?}/silent-check-sso.html" \
--set appenvironment.HTTP_CSP_CONNECT_SRC="'self' https://${keycloak_domain:?}" \
--set configuration.Authentication__Schemes__Bearer__RequireHttpsMetadata=true \
--set configuration.Authentication__Schemes__Bearer__MetadataAddress="https://${keycloak_domain:?}/realms/glasswall/.well-known/openid-configuration" \
--set configuration.Logging__LogLevel__Keycloak="Debug" \
--atomic
portal-access 배포
image_tag=$(k get deploy portal-access -o json | jq -r '.spec.template.spec.containers[0].image' | cut -d":" -f2)
portal_domain="glasswall.example.com"
keycloak_domain="keycloak.example.com"
helm upgrade --install cdrplatform-portal-access ./cdrplatform-portal-access \
--set image.tag="${image_tag:?}" \
--set image.pullPolicy=IfNotPresent \
--set ingress.tls.domain="${portal_domain:?}" \
--set ingress.tls.enabled=true \
--set ingress.tls.secretName="tls-secret" \
--set configuration.AuthenticationScheme="Bearer" \
--set configuration.Authentication__Schemes__Bearer__ValidAudiences__0="api://cdrplatform-portal-access" \
--set configuration.Authentication__Schemes__Bearer__ValidIssuer="https://${keycloak_domain:?}/realms/glasswall" \
--set configuration.Authentication__Schemes__Bearer__Authority="https://${keycloak_domain:?}/realms/glasswall" \
--set configuration.Authentication__Schemes__Bearer__RequireHttpsMetadata=true \
--set configuration.Authentication__Schemes__Bearer__MetadataAddress="https://${keycloak_domain:?}/realms/glasswall/.well-known/openid-configuration" \
--set configuration.Authentication__Schemes__Bearer__JwksUri="https://${keycloak_domain:?}/realms/glasswall/protocol/openid-connect/certs" \
--atomic
API-access 배포
api_access_image_tag=$(k get deploy api-access -o json | jq -r '.spec.template.spec.containers[0].image' | cut -d":" -f2)
portal_domain="test.cdr.glasswall.dev"
keycloak_domain="pbkc.cdr.glasswall.dev"
helm upgrade --install cdrplatform-api-access ./cdrplatform-api-access \
--set image.tag="${api_access_image_tag:?}" \
--set image.pullPolicy=IfNotPresent \
--set ingress.tls.enabled=true \
--set ingress.tls.secretName="tls-secret" \
--set ingress.tls.domain="${portal_domain:?}" \
--set configuration.AuthenticationScheme="Bearer" \
--set configuration.Authentication__Schemes__Bearer__ValidAudiences__0="api://cdrplatform-api-access" \
--set configuration.Authentication__Schemes__Bearer__ValidIssuer="https://${keycloak_domain:?}/realms/glasswall" \
--set configuration.Authentication__Schemes__Bearer__Authority="https://${keycloak_domain:?}/realms/glasswall" \
--set configuration.Authentication__Schemes__Bearer__RequireHttpsMetadata=true \
--set configuration.Authentication__Schemes__Bearer__MetadataAddress="https://${keycloak_domain:?}/realms/glasswall/.well-known/openid-configuration" \
--set configuration.Authentication__Schemes__Bearer__JwksUri="https://${keycloak_domain:?}/realms/glasswall/protocol/openid-connect/certs" \
--atomic
3.1 배포 후 체크리스트
- pod가 실행 중인지 확인합니다(
CrashLoopBackOff없음). - 또한 로그에 Keycloak OIDC 구성이 성공적으로 표시되는지 확인합니다.

4단계 - SSO 통합 검증 및 테스트

4.1 브라우저 로그인 테스트
A. Halo 포털을 실행합니다. B. Keycloak 로그인으로 리디렉션됩니다.

C. 계정에 로그인합니다.

D. 인증 후 Halo로 돌아갑니다.

5단계 - 문제 해결
잘못 구성된 리디렉션 URI
포털과 Keycloak 간 URI가 일치하는지 확인합니다.
시계 오차
시스템 시계를 동기화합니다.
TLS 신뢰 오류
Halo가 Keycloak의 인증서를 신뢰하는지 확인합니다.