IAP(Identity-Aware Proxy)로 외부 ID를 사용하려면 앱에 로그인 페이지가 필요합니다. IAP는 사용자를 보안 리소스에 액세스하기 전에 이 페이지로 리디렉션하여 인증합니다.
이 문서에서는 Cloud Run을 사용하여 사전 빌드된 로그인 페이지를 배포하고 맞춤설정하는 방법을 보여줍니다. 외부 ID를 시작하는 가장 빠른 방법이며 코드를 작성할 필요가 없습니다.
로그인 페이지를 직접 만들 수도 있습니다. 자체 페이지를 빌드하는 것이 더 복잡하지만 인증 흐름 및 사용자 환경을 보다 세밀하게 제어할 수 있습니다. 자세한 내용은 FirebaseUI로 로그인 페이지 만들기 및 커스텀 로그인 페이지 만들기를 참조하세요.
로그인 페이지 제한사항
프로젝트에 이메일 열거 보호가 사용 설정된 경우 사전 빌드된 로그인 페이지를 사용할 수 없습니다.
프로젝트에 이메일 열거 보호가 사용 설정된 경우 이 문서의 절차를 계속하기 전에 email-enumeration-protection을 사용 중지합니다.
시작하기 전에
Compute Engine API를 사용 설정합니다.
외부 ID를 사용 설정하고 설정 중에 자동으로 로그인 페이지 만들기 옵션을 선택합니다. 그러면 Cloud Run 및 FirebaseUI에서 로그인 페이지를 자동으로 만들어 줍니다.
Cloud Run에서 사용하는 서비스 계정인 PROJECT_NUMBER-compute@developer.gserviceaccount.com에 다음의 사전 정의된 역할이 있는지 확인합니다.
roles/identitytoolkit.viewer
roles/iap.settingsAdmin
roles/compute.networkViewer
Identity Platform 제공업체의 승인된 리디렉션 URI 설정
로그인 리디렉션(외부 IdP 로그인 페이지로 리디렉션)이 필요한 Identity Platform 공급업체를 사용하는 경우 호스팅된 로그인 페이지의 URL을 제공업체 구성에서 승인된 리디렉션 URL로 추가해야 합니다.
예를 들어 Google 공급업체의 경우 다음을 수행해야 합니다.
IAP 보안 애플리케이션을 선택한 후 로그인 URL을 복사합니다.
Google Cloud 콘솔에서 사용자 인증 정보 페이지로 이동합니다.
LOGIN_URL/__/auth/handler
를 앱의 OAuth 2.0 클라이언트에 대해 승인된 리디렉션 URI 중 하나로 추가합니다. Google 공급업체를 구성할 때 사용한 것과 동일한 OAuth 클라이언트 ID를 선택합니다.
다른 SAML 및 OIDC 제공업체의 경우 LOGIN_URL/__/auth/handler
를 승인된 리디렉션 URI 또는 ACS URL로 추가하여 동일한 작업을 수행합니다.
로그인 페이지 테스트
IAP에서 생성되는 초기 로그인 페이지는 정상적으로 작동합니다. 테스트하려면 다음 안내를 따르세요.
IAP로 보호되는 리소스로 이동합니다. 로그인 페이지로 자동 리디렉션되어야 합니다.
로그인할 테넌트 및 공급업체를 선택합니다. 테넌트 또는 공급업체가 나열되지 않으면 Identity Platform을 사용하여 구성했는지 확인하세요.
사용자 인증 정보로 로그인합니다.
보호된 리소스로 리디렉션되어야 합니다.
로그인 페이지 맞춤설정
JSON 구성 파일을 사용하여 로그인 페이지를 맞춤설정할 수 있습니다. 다음은 몇 가지 옵션입니다.
- 로그인 페이지에 헤더와 로고 추가
- 사용 가능한 테넌트 및 공급업체 지정
- 각 테넌트 및 공급업체 버튼의 아이콘 및 스타일 맞춤설정
- 앱의 개인정보처리방침 및 서비스 약관에 대한 링크 추가
다음 섹션에서는 JSON 구성 파일에 액세스하고 업데이트하는 방법을 설명합니다.
액세스 토큰 가져오기
로그인 페이지를 관리하려면 Google 액세스 토큰이 필요합니다. Google 액세스 토큰을 얻는 가장 쉬운 방법은 Google을 Identity Platform의 제공업체로 사용 설정하는 것입니다. 앱에서 이미 Google을 ID 공급업체로 사용하고 있다면 이 섹션을 건너뛸 수 있습니다.
Google Cloud 콘솔에서 Identity Platform 공급업체 페이지로 이동합니다.
제공자 추가를 클릭합니다.
공급업체 목록에서 Google을 선택합니다.
웹 클라이언트 ID 및 웹 클라이언트 보안 비밀번호를 구성합니다.
Google Cloud 콘솔에서 사용자 인증 정보 페이지로 이동합니다.
기존 OAuth 2.0 클라이언트를 사용하거나 새 클라이언트를 만듭니다.
Client ID
및Client secret
을 웹 클라이언트 ID 및 웹 클라이언트 보안 비밀번호로 구성합니다.LOGIN_URL/__/auth/handler
을 OAuth 2.0 클라이언트에 승인된 리디렉션 URI 중 하나로 추가합니다.LOGIN_URL
은 자동으로 로그인 페이지 만들기 옵션을 선택한 후에 IAP에서 만든 로그인 URL입니다. IAP 보안 리소스를 선택하여 Google Cloud 콘솔의 IAP 페이지에서 찾을 수 있습니다.
두 페이지 모두 저장을 클릭합니다.
관리자 패널에 로그인
LOGIN_URL/admin
패널에서 Cloud Run이 호스팅하는 로그인 페이지의 JSON 구성입니다.
다음 단계는 패널에 액세스하는 방법을 보여줍니다. 스토리지 관리자(roles/storage.admin
) 역할이 필요합니다.
Google Cloud 콘솔에서 IAP 페이지로 이동합니다.
목록에서 리소스를 선택합니다.
정보 패널의 페이지 맞춤설정 아래에 나열된 URL을 실행합니다. 예를 들면 다음과 같습니다.
https://servicename-xyz-uc.a.run.app/admin
IAP를 구성할 때 사용한 것과 동일한 Google 계정으로 로그인합니다. JSON 구성 파일이 포함된 텍스트 편집기가 표시됩니다.
구성 수정
로그인 페이지의 구성 스키마는 FirebaseUI를 기반으로 하며 많은 속성을 상속합니다. IAP에서 만든 LOGIN_URL
을 기본 authDomain으로 사용하는 대신 PROJECT_ID.firebaseapp.com
을 사용할 수 있습니다.
PROJECT_ID.firebaseapp.com
을 authDomain
으로 사용하려면 주요 브라우저에서 서드 파티 스토리지 액세스 문제가 방지되도록 signInFlow
를 popup
으로 변경합니다(서드 파티 스토리지 액세스를 차단하는 브라우저에서 signInWithRedirect를 사용하기 위한 권장사항 참조). 또한 Identity Platform 제공업체의 승인된 리디렉션 URI 설정의 안내를 따라 PROJECT_ID.firebaseapp.com/__/auth/handler
를 사용자가 로그인할 Identity Platform 공급업체의 승인된 리디렉션 URI 또는 ACS URL 중 하나로 추가합니다.
다음 코드는 세 개의 테넌트가 있는 구성 예시를 보여줍니다.
{
"AIzaSyC5DtmRUR...": {
"authDomain": "awesomeco.firebaseapp.com",
"displayMode": "optionFirst",
"selectTenantUiTitle": "Awesome Company Portal",
"selectTenantUiLogo": "https://awesome.com/abcd/logo.png",
"styleUrl": "https://awesome.com/abcd/overrides/stylesheet.css",
"tosUrl": "https://awesome.com/abcd/tos.html",
"privacyPolicyUrl": "https://awesome.com/abcd/privacypolicy.html",
"tenants": {
"tenant-a-id": {
"fullLabel": "Company A Portal",
"displayName": "Company A",
"iconUrl": "https://companya.com/img/icon.png",
"logoUrl": "https://companya.com/img/logo.png",
"buttonColor": "#007bff",
"signInFlow": "popup",
"signInOptions": [
{
"provider": "password",
"requireDisplayName": false,
"disableSignUp": {
"status": true,
"adminEmail": "admin@example.com",
"helpLink": "https://www.example.com/trouble_signing_in"
}
},
"facebook.com",
"google.com",
"microsoft.com",
{
"provider": "saml.okta-cicp-app",
"providerName": "Corp Account",
"fullLabel": "Employee Corporate Login",
"buttonColor": "#ff0000",
"iconUrl": "https://companya.com/abcd/icon-1.png"
},
{
"provider": "oidc.okta-oidc",
"providerName": "Contractor Account",
"fullLabel": "Contractor Account Portal",
"buttonColor": "#00ff00",
"iconUrl": "https://companya.com/abcd/icon-2.png"
}
],
"tosUrl": "https://companya.com/abcd/tos.html",
"privacyPolicyUrl": "https://companya.com/abcd/privacypolicy.html"
},
"tenant-b-id": {
"fullLabel": "Company B Portal",
"displayName": "Company B",
"iconUrl": "https://companyb.com/img/icon.png",
"logoUrl": "https://companyb.com/img/logo.png",
"buttonColor": "#007bff",
"immediateFederatedRedirect": true,
"signInFlow": "popup",
"signInOptions": [
{
"provider": "saml.okta-bla-app",
"providerName": "Corp Account",
"buttonColor": "#0000ff",
"iconUrl": "https://companyb.com/abcd/icon.png"
}
],
"tosUrl": "https://companyb.com/abcd/tos.html",
"privacyPolicyUrl": "https://companyb.com/abcd/privacypolicy.html"
},
"tenant-c-id": {
"fullLabel": "Company C Portal",
"displayName": "Company C",
"iconUrl": "https://companyc.com/img/icon.png",
"logoUrl": "https://companyc.com/img/logo.png",
"buttonColor": "#007bff",
"immediateFederatedRedirect": true,
"signInFlow": "popup",
"signInOptions": [
{
"provider": "password",
"requireDisplayName": false
},
{
"provider": "google.com",
"scopes": ["scope1", "scope2", "https://example.com/scope3"],
"loginHintKey": "login_hint",
"customParameters": {
"prompt": "consent",
},
}
],
"tosUrl": "https://companyc.com/abcd/tos.html",
"privacyPolicyUrl": "https://companyc.com/abcd/privacypolicy.html",
"adminRestrictedOperation": {
"status": true,
"adminEmail": "admin@example.com",
"helpLink": "https://www.example.com/trouble_signing_in"
}
},
}
}
}
사용 가능한 속성의 전체 목록은 참조 문서를 확인하세요.
CSS 재정의
styleUrl
속성을 사용하여 커스텀 CSS 파일을 지정할 수 있습니다. 이 파일의 스타일은 기본 CSS를 재정의합니다. HTTPS를 사용하여 이 파일에 공개적으로 액세스할 수 있어야 합니다(예: Cloud Storage 버킷에서 호스팅하는 경우).
다음 예시는 기본 CSS를 재정의하는 방법을 보여줍니다.
/** Change header title style. */
.heading-center {
color: #7181a5;
font-family: Arial, Helvetica, sans-serif;
font-size: 20px;
font-weight: bold;
}
/** Use round edged borders for container. */
.main-container {
border-radius: 5px;
}
/** Change page background color. */
body {
background-color: #f8f9fa;
}
Cloud Run 인스턴스 재배포
경우에 따라 로그인 페이지를 호스팅하는 Cloud Run 인스턴스를 다시 배포할 수 있습니다. 시나리오의 예시는 다음과 같습니다.
- ID 공급업체 추가, 수정 또는 삭제
- 테넌트 구성 수정
- 환경 변수 설정
- 컨테이너 이미지를 최신 버전으로 업데이트
컨테이너 이미지를 정기적으로 업데이트하고 다시 배포하면 최신 버그 수정 및 보안 패치가 적용됩니다. GitHub에서 버전 간의 변경사항 목록을 확인할 수 있습니다.
/versionz
엔드포인트를 사용하여 배포된 컨테이너의 현재 버전을 가져올 수 있습니다. 예를 들면 다음과 같습니다.
curl 'https://servicename-xyz-uc.a.run.app/versionz'
Cloud Run 인스턴스를 다시 배포하려면 다음 안내를 따르세요.
Google Cloud 콘솔에서 Cloud Run 페이지로 이동합니다.
로그인 페이지를 호스팅하는 인스턴스를 선택합니다.
새 버전 수정 및 배포를 클릭합니다.
선택적으로 버전에 고급 설정을 지정하거나 변수 및 보안 비밀 탭을 클릭하여 환경 변수를 추가합니다.
배포를 클릭합니다.
고급 옵션
프로그래매틱 방식으로 로그인 페이지 맞춤설정
/admin
콘솔을 사용하는 것 외에도 JSON 구성을 프로그래매틱 방식으로 업데이트할 수 있습니다.
현재 구성을 가져오려면 /get_admin_config
엔드포인트를 사용합니다.
예를 들면 다음과 같습니다.
curl -H 'Authorization: Bearer [TOKEN]'
'https://servicename-xyz-uc.a.run.app/get_admin_config'
구성을 업데이트하려면 /set_admin_config
를 사용합니다. 예를 들면 다음과 같습니다.
curl -XPOST -H 'Authorization: Bearer [TOKEN]' -H "Content-type: application/json"
-d '[UPDATED-CONFIG]' 'https://servicename-xyz-uc.a.run.app/set_admin_config'
두 REST 호출 모두 https://www.googleapis.com/auth/devstorage.read_write
범위가 필요하며 유효한 OAuth 토큰을 Authorization
헤더에 연결해야 합니다.
환경 변수 설정
Cloud Run 인스턴스에서 환경 변수를 설정하여 고급 설정을 맞춤설정할 수 있습니다. 사용 가능한 변수는 다음 표에 나와 있습니다.
변수 | 설명 |
---|---|
DEBUG_CONSOLE |
모든 네트워크 요청 오류 및 세부정보를 로깅할지를 나타내는 부울 값 (0 또는 1 )입니다. 민감한 정보는 로깅되지 않습니다. 기본적으로 사용 중지됩니다(0 ).
|
UI_CONFIG |
로그인 페이지의 JSON 구성이 포함된 문자열입니다. /admin 패널 대신 이 변수를 사용하면 구성에 액세스할 때 Cloud Storage를 읽고 쓸 수 없습니다. 잘못된 구성은 무시됩니다. 이 변수를 설정하기 전에 /admin 패널을 사용하여 JSON을 검증하면 구문 오류를 최소화할 수 있습니다.
|
GCS_BUCKET_NAME |
JSON 구성을 저장하는 데 사용되는 기본 Cloud Storage 버킷을 재정의하는 문자열입니다. 이 파일의 이름은 config.json 이고 기본 위치는 gcip-iap-bucket-[CLOUD-RUN-SERVICE-NAME]-[PROJECT-NUMBER] 입니다.
|
ALLOW_ADMIN |
/admin 구성 패널에 대한 액세스 허용 여부를 나타내는 부울 값(0 또는 1 )입니다.
기본적으로 사용 설정됩니다(1 )
|
변수를 업데이트한 후 Cloud Run 인스턴스의 새 버전을 배포해야 변경사항이 적용됩니다. 환경 변수에 대해 자세히 알아보려면 Cloud Run 문서를 참조하세요.
도메인 맞춤설정
기본적으로 로그인할 때 Cloud Run 인스턴스의 URL이 표시됩니다. 대신 커스텀 도메인을 지정하려면 다음 안내를 따르세요.
커스텀 도메인 매핑의 단계를 따라 Cloud Run 인스턴스의 커스텀 도메인을 설정합니다.
새 인증 URL을 사용하도록 IAP를 구성합니다.
Google Cloud 콘솔에서 IAP 페이지로 이동합니다.
IAP로 보호되는 리소스를 선택합니다.
측면 패널에서 로그인 URL 입력란 옆에 있는 수정 아이콘을 선택합니다.
기존 호스팅 로그인 페이지 사용을 선택하고 드롭다운 메뉴에서 도메인을 선택합니다.
저장을 클릭합니다.
여러 IAP 리소스에 단일 로그인 페이지 사용
동일한 로그인 페이지를 사용하여 여러 IAP 리소스를 보호할 수 있습니다. 그러면 여러 구성 관리와 관련된 작업이 줄어듭니다.
로그인 페이지를 다시 사용하려면 다음 단계를 따르세요.
이 문서의 단계에 따라 IAP로 보호되는 첫 번째 리소스의 인증 페이지를 배포합니다.
두 번째 리소스에 IAP를 사용 설정합니다. 로그인 페이지를 지정하라는 메시지가 표시되면 자체 페이지 제공을 선택하고 Cloud Run 서비스의 URL을 URL로 입력합니다.
Cloud Run 서비스를 다시 배포합니다.
문제 해결
브라우저에서 서드 파티 쿠키 및 저장용량 파티셔닝
서드 파티 쿠키를 중지하거나 저장용량 파티셔닝을 구현하는 브라우저에서는 로그인 페이지나 관리 페이지가 제대로 작동하지 않을 수 있습니다. 이 문제를 해결하려면 다음 단계를 따르세요.
최신 버전 1.0.1을 사용하도록 로그인 페이지를 재배포합니다.
로그인 페이지 맞춤설정 기능을 사용하는 경우
authDomain
이 IAP에서 만든LOGIN_URL
로 설정되었는지 확인합니다. 또는signInFlow
가popup
으로 설정된 경우authDomain
을PROJECT_ID.firebaseapp.com
으로 설정할 수 있습니다.{ "AIzaSyC5DtmRUR...": { "authDomain": "LOGIN_URL", ... } }
또는
{ "AIzaSyC5DtmRUR...": { "authDomain": "PROJECT_ID.firebaseapp.com", "tenants": { "tenant-a-id": { ... "signInFlow": "popup" ... } } ... } }
다음 단계
- FirebaseUI로 인증 UI를 만듭니다.
- 커스텀 인증 UI를 만듭니다.
- 외부 ID가 IAP와 어떻게 작동하는지에 대해 자세히 알아보세요.