프로그래매틱 방식으로 SAML 및 OIDC 제공업체 관리

이 문서에서는 Identity Platform Admin SDK를 사용하여 프로그래매틱 방식으로 보안 보장 마크업 언어(SAML) 2.0 및 OpenID Connect(OIDC) 공급업체 구성을 관리하는 방법을 보여줍니다.

Admin SDK를 사용하면 공급업체를 자동으로 구성하고, 기본 CRUD 작업을 수행하고, 인증서를 순환하는 등의 작업을 할 수 있습니다. 이 방법은 공급업체 수가 너무 많아 Google Cloud Console을 사용하여 수동으로 관리하기 어려운 경우에 유용합니다.

시작하기 전에

SAML 공급업체 작업

SAML 공급업체 구성 만들기

SAML 공급업체 구성을 만들 때 다음 매개변수를 제공해야 합니다. 일부 값을 가져 오는 방법에 대한 자세한 내용은 ID 공급업체의 문서를 참조하세요.

표시 이름
구성의 사용자 친화적인 표시 이름입니다. 이 이름은 Google Cloud Console의 공급업체 라벨이기도 합니다.
사용 설정됨
현재 공급업체 구성의 사용 설정 또는 중지 여부입니다. 사용자는 사용 중지된 공급업체로 로그인할 수 없습니다.
공급업체 ID
saml.로 시작하는 공급업체의 고유 식별자입니다.
ID 공급업체 엔티티 ID
공급업체의 엔티티 ID입니다.
SSO URL
공급업체의 SAML SSO URL입니다. 유효한 URL이어야 합니다.
X.509 인증서

-----BEGIN CERTIFICATE----- 문자열과 -----END CERTIFICATE---- 문자열을 포함한 SAML 공급업체 X.509 인증서 목록입니다. ID 공급업체의 토큰 서명에 사용됩니다.

Identity Platform은 SAML 응답을 수신하면 레코드에 있는 인증서를 사용하여 서명을 확인합니다. 확인에 실패하면 응답이 거부됩니다. 키가 순환되면 이러한 인증서를 업데이트해야 합니다. 순환 중에 서비스 중단을 방지하기 위해 여러 인증서를 업로드하는 것이 좋습니다.

당사자 엔티티 ID 릴레이
SAML을 사용하는 당사자(RP/SP) 엔티티 ID입니다. 일반적으로 앱의 URL입니다. SAML ID 공급업체에서는 이를 대상이라고 합니다.
콜백 URL

인증이 완료될 때 반환할 URL입니다. SAML 공급업체는 일반적으로 이를 어설션 소비자 서비스(ACS) URL이라 합니다. 이 URL을 SAML 공급업체에 등록해야 합니다. Google Cloud Console에 표시되는 URL과 유사한 https://PROJECT-ID.firebaseapp.com/__/auth/handler와 같은 형태입니다. 자세한 내용은 SAML로 사용자 로그인을 참조하세요.

기본 콜백 URL을 사용하면 SAML 응답 확인의 복잡성이 줄어듭니다. 하지만 커스텀 도메인을 표시하도록 선택할 수도 있습니다. 이 경우 프로젝트의 Identity Platform 콜백 URL이 SAML ID 공급업체에 올바르게 구성되었는지 확인하세요. 일반적으로 https://AUTH-DOMAIN/__/auth/handler와 비슷합니다.

다음 예시에서는 SAML 공급업체 구성을 만드는 방법을 보여줍니다.

Node.js

const newConfig = {
  displayName: 'SAML provider name',
  enabled: true,
  providerId: 'saml.myProvider',
  idpEntityId: 'IDP_ENTITY_ID',
  ssoURL: 'https://example.com/saml/sso/1234/'
  x509Certificates: [
    '-----BEGIN CERTIFICATE-----\nCERT1...\n-----END CERTIFICATE-----',
    '-----BEGIN CERTIFICATE-----\nCERT2...\n-----END CERTIFICATE-----',
  ],
  rpEntityId: 'RP_ENTITY_ID',
  // Using the default callback URL.
  callbackURL: 'https://project-id.firebaseapp.com/__/auth/handler',
};
admin.auth().createProviderConfig(newConfig).then(() => {
  // Successful creation.
}).catch((error) => {
  // Handle error.
});

Go

newConfig := (&auth.SAMLProviderConfigToCreate{}).
	DisplayName("SAML provider name").
	Enabled(true).
	ID("saml.myProvider").
	IDPEntityID("IDP_ENTITY_ID").
	SSOURL("https://example.com/saml/sso/1234/").
	X509Certificates([]string{
		"-----BEGIN CERTIFICATE-----\nCERT1...\n-----END CERTIFICATE-----",
		"-----BEGIN CERTIFICATE-----\nCERT2...\n-----END CERTIFICATE-----",
	}).
	RPEntityID("RP_ENTITY_ID").
	CallbackURL("https://project-id.firebaseapp.com/__/auth/handler")
saml, err := client.CreateSAMLProviderConfig(ctx, newConfig)
if err != nil {
	log.Fatalf("error creating SAML provider: %v\n", err)
}

log.Printf("Created new SAML provider: %s", saml.ID)

Python

saml = auth.create_saml_provider_config(
    display_name='SAML provider name',
    enabled=True,
    provider_id='saml.myProvider',
    idp_entity_id='IDP_ENTITY_ID',
    sso_url='https://example.com/saml/sso/1234/',
    x509_certificates=[
        '-----BEGIN CERTIFICATE-----\nCERT1...\n-----END CERTIFICATE-----',
        '-----BEGIN CERTIFICATE-----\nCERT2...\n-----END CERTIFICATE-----',
    ],
    rp_entity_id='P_ENTITY_ID',
    callback_url='https://project-id.firebaseapp.com/__/auth/handler')

print('Created new SAML provider:', saml.provider_id)

자바

SamlProviderConfig.CreateRequest request = new SamlProviderConfig.CreateRequest()
    .setDisplayName("SAML provider name")
    .setEnabled(true)
    .setProviderId("saml.myProvider")
    .setIdpEntityId("IDP_ENTITY_ID")
    .setSsoUrl("https://example.com/saml/sso/1234/")
    .addX509Certificate("-----BEGIN CERTIFICATE-----\nCERT1...\n-----END CERTIFICATE-----")
    .addX509Certificate("-----BEGIN CERTIFICATE-----\nCERT2...\n-----END CERTIFICATE-----")
    .setRpEntityId("RP_ENTITY_ID")
    .setCallbackUrl("https://project-id.firebaseapp.com/__/auth/handler");
SamlProviderConfig saml = FirebaseAuth.getInstance().createSamlProviderConfig(request);
System.out.println("Created new SAML provider: " + saml.getProviderId());

완료되면 이 메서드는 새로 만든 구성에 대해 SAMLAuthProviderConfig 객체를 반환합니다.

SAML 공급업체 구성 업데이트

다음 예시에서는 SAML 공급업체 구성을 수정하는 방법을 보여줍니다. 공급업체 ID를 제외한 모든 필드를 업데이트할 수 있습니다.

Node.js

const updatedConfig = {
  x509Certificates: [
    '-----BEGIN CERTIFICATE-----\nCERT2...\n-----END CERTIFICATE-----',
    '-----BEGIN CERTIFICATE-----\nCERT3...\n-----END CERTIFICATE-----',
  ],
};
admin.auth().updateProviderConfig('saml.myProvider', updatedConfig).then(() => {
  // Successful update.
}).catch((error) => {
  // Handle error.
});

Go

updatedConfig := (&auth.SAMLProviderConfigToUpdate{}).
	X509Certificates([]string{
		"-----BEGIN CERTIFICATE-----\nCERT2...\n-----END CERTIFICATE-----",
		"-----BEGIN CERTIFICATE-----\nCERT3...\n-----END CERTIFICATE-----",
	})
saml, err := client.UpdateSAMLProviderConfig(ctx, "saml.myProvider", updatedConfig)
if err != nil {
	log.Fatalf("error updating SAML provider: %v\n", err)
}

log.Printf("Updated SAML provider: %s", saml.ID)

Python

saml = auth.update_saml_provider_config(
    'saml.myProvider',
    x509_certificates=[
        '-----BEGIN CERTIFICATE-----\nCERT2...\n-----END CERTIFICATE-----',
        '-----BEGIN CERTIFICATE-----\nCERT3...\n-----END CERTIFICATE-----',
    ])

print('Updated SAML provider:', saml.provider_id)

자바

SamlProviderConfig.UpdateRequest request =
    new SamlProviderConfig.UpdateRequest("saml.myProvider")
      .addX509Certificate("-----BEGIN CERTIFICATE-----\nCERT2...\n-----END CERTIFICATE-----")
      .addX509Certificate("-----BEGIN CERTIFICATE-----\nCERT3...\n-----END CERTIFICATE-----");
SamlProviderConfig saml = FirebaseAuth.getInstance().updateSamlProviderConfig(request);
System.out.println("Updated SAML provider: " + saml.getProviderId());

완료되면 이 메서드는 업데이트된 구성의 SAMLAuthProviderConfig 객체를 반환합니다.

SAML 공급업체 구성 가져오기

SAML 구성을 식별하는 기본 방법은 공급업체 ID를 사용하는 것입니다. 다음 예시에서는 SAML 공급업체 구성을 가져오는 방법을 보여줍니다.

Node.js

admin.auth().getProviderConfig('saml.myProvider').then((config) => {
  // Get display name and whether it is enabled.
  console.log(config.displayName, config.enabled);
}).catch((error) => {
  // Handle error. Common error is that config is not found.
});

Go

saml, err := client.SAMLProviderConfig(ctx, "saml.myProvider")
if err != nil {
	log.Fatalf("error retrieving SAML provider: %v\n", err)
}

log.Printf("%s %t", saml.DisplayName, saml.Enabled)

Python

saml = auth.get_saml_provider_config('saml.myProvider')
print(saml.display_name, saml.enabled)

자바

SamlProviderConfig saml = FirebaseAuth.getInstance().getSamlProviderConfig("saml.myProvider");
System.out.println(saml.getDisplayName() + ": " + saml.isEnabled());

지정된 ID를 가진 공급업체가 존재하는 경우 이 메서드는 SAMLAuthProviderConfig 객체를 반환합니다.

SAML 공급업체 구성 삭제

다음 예시에서는 SAML 공급업체 구성을 삭제하는 방법을 보여줍니다.

Node.js

admin.auth().deleteProviderConfig('saml.myProvider').then(() => {
  // Successful deletion.
}).catch((error) => {
  // Handle error.
});

Go

if err := client.DeleteSAMLProviderConfig(ctx, "saml.myProvider"); err != nil {
	log.Fatalf("error deleting SAML provider: %v\n", err)
}

Python

auth.delete_saml_provider_config('saml.myProvider')

자바

FirebaseAuth.getInstance().deleteSamlProviderConfig("saml.myProvider");

SAML 공급업체 구성 나열

다음 예시에서는 기존 SAML 공급업체 구성을 나열하는 방법을 보여줍니다.

Node.js

// Returns 10 SAML provider configs starting from the specified nextPageToken offset.
admin.auth().listProviderConfigs({type: 'saml', maxResults: 10, pageToken: 'nextPageToken'}).then((results) => {
  results.providerConfigs.forEach((config) => {
    console.log(config.providerId);
  });
  // To list the next 10:
  // return admin.auth().listProviderConfigs(
  //     {type: 'saml', maxResults: 10, pageToken: results.pageToken});
}).catch((error) => {
  // Handle error.
});

Go

iter := client.SAMLProviderConfigs(ctx, "nextPageToken")
for {
	saml, err := iter.Next()
	if err == iterator.Done {
		break
	}
	if err != nil {
		log.Fatalf("error retrieving SAML providers: %v\n", err)
	}

	log.Printf("%s\n", saml.ID)
}

Python

for saml in auth.list_saml_provider_configs('nextPageToken').iterate_all():
    print(saml.provider_id)

자바

ListProviderConfigsPage<SamlProviderConfig> page = FirebaseAuth.getInstance()
    .listSamlProviderConfigs("nextPageToken");
for (SamlProviderConfig config : page.iterateAll()) {
  System.out.println(config.getProviderId());
}

각 결과 배치에는 공급업체 구성 목록과 함께 다음 배치를 가져오는 데 사용되는 다음 페이지 토큰이 들어 있습니다. 모든 공급업체가 나열되면 토큰이 반환되지 않습니다.

기본적으로 100개의 공급업체가 각 배치와 함께 반환됩니다. 이는 배치당 최대 공급업체 수이기도 합니다.

OIDC 공급업체 작업

OIDC 공급업체 구성 만들기

OIDC 공급업체 구성을 만들 때 다음 매개변수를 제공해야 합니다. 일부 값을 가져 오는 방법에 대한 자세한 내용은 ID 공급업체의 문서를 참조하세요.

표시 이름
구성의 사용자 친화적인 표시 이름입니다. 이 이름은 Google Cloud Console의 공급업체 라벨이기도 합니다.
사용 설정됨
현재 공급업체 구성의 사용 설정 또는 중지 여부입니다. 사용자는 사용 중지된 공급업체로 로그인할 수 없습니다.
공급업체 ID
oidc.로 시작하는 공급업체의 고유 식별자입니다.
클라이언트 ID
OIDC 공급업체의 ID 토큰의 대상을 확인하는 데 사용되는 ID입니다.
클라이언트 보안 비밀
OIDC 코드 흐름을 사용 설정하는 데 필요한 클라이언트 보안 비밀번호입니다.
발급자
제공업체의 Issuer입니다. https://example.com과 같이 표시됩니다. Identity Platform은 이 URL을 사용하여 공급업체의 OAuth 엔드포인트와 공개 키를 지정하는 OIDC 검색 문서(일반적으로 /.well-known/openid-configuration에 있음)를 찾습니다. Identity Platform은 OpenID Connect 사양에 따라 ID 토큰을 검증합니다. 공급업체가 검색을 위해 OIDC 사양을 준수하지 않으면 Identity Platform에서 작동하지 않습니다.
응답 유형
OAuth 승인 흐름에 대한 제공업체의 응답 유형입니다. {idToken, code} 중 하나를 true로 설정할 수 있으며, 둘 다 설정할 수는 없습니다. 코드 흐름이 사용 설정된 경우 클라이언트 보안 비밀번호를 제공해야 합니다.

다음 예시에서는 암시적 승인 흐름을 사용하는 OIDC 제공업체 구성을 만드는 방법을 보여줍니다.

Node.js

const newConfig = {
  displayName: 'OIDC provider name',
  enabled: true,
  clientId: 'CLIENT_ID2',
  issuer: 'https://oidc.com/CLIENT_ID2',
  providerId: 'oidc.provider2',
  responseType: {
    idToken: true,
    code: false,
  },
};
admin.auth().createProviderConfig(newConfig).then(() => {
  // Successful creation.
}).catch((error) => {
  // Handle error.
});

Go

newConfig := (&auth.OIDCProviderConfigToCreate{}).
	DisplayName("OIDC provider name").
	Enabled(true).
	ID("oidc.myProvider").
	ClientID("CLIENT_ID2").
	Issuer("https://oidc.com/CLIENT_ID2")
oidc, err := client.CreateOIDCProviderConfig(ctx, newConfig)
if err != nil {
	log.Fatalf("error creating OIDC provider: %v\n", err)
}

log.Printf("Created new OIDC provider: %s", oidc.ID)

Python

oidc = auth.create_oidc_provider_config(
    display_name='OIDC provider name',
    enabled=True,
    provider_id='oidc.myProvider',
    client_id='CLIENT_ID2',
    issuer='https://oidc.com/CLIENT_ID2')

print('Created new OIDC provider:', oidc.provider_id)

자바

OidcProviderConfig.CreateRequest request = new OidcProviderConfig.CreateRequest()
    .setDisplayName("OIDC provider name")
    .setEnabled(true)
    .setProviderId("oidc.myProvider")
    .setClientId("CLIENT_ID2")
    .setIssuer("https://oidc.com/CLIENT_ID2");
OidcProviderConfig oidc = FirebaseAuth.getInstance().createOidcProviderConfig(request);
System.out.println("Created new OIDC provider: " + oidc.getProviderId());

완료되면 이 메서드는 새로 생성된 구성에 대해 OIDCAuthProviderConfig 객체를 반환합니다.

OIDC 공급업체 구성 업데이트

다음 예시에서는 OIDC 공급업체 구성을 수정하는 방법을 보여줍니다. 공급업체 ID를 제외한 모든 필드를 업데이트할 수 있습니다.

Node.js

const updatedConfig = {
  displayName: 'OIDC provider name',
  enabled: true,
  clientId: 'CLIENT_ID',
  clientSecret: 'CLIENT_SECRET'
  issuer: 'https://oidc.com/',
  responseType: {
    code: true,
    idToken: false,
  },
};
admin.auth().updateProviderConfig('oidc.myProvider', updatedConfig).then(() => {
  // Successful update.
}).catch((error) => {
  // Handle error.
});

Go

updatedConfig := (&auth.OIDCProviderConfigToUpdate{}).
	DisplayName("OIDC provider name").
	Enabled(true).
	ClientID("CLIENT_ID").
	Issuer("https://oidc.com")
oidc, err := client.UpdateOIDCProviderConfig(ctx, "oidc.myProvider", updatedConfig)
if err != nil {
	log.Fatalf("error updating OIDC provider: %v\n", err)
}

log.Printf("Updated OIDC provider: %s", oidc.ID)

Python

oidc = auth.update_oidc_provider_config(
    'oidc.myProvider',
    client_id='CLIENT_ID',
    issuer='https://oidc.com')

print('Updated OIDC provider:', oidc.provider_id)

자바

OidcProviderConfig.UpdateRequest request =
    new OidcProviderConfig.UpdateRequest("oidc.myProvider")
        .setDisplayName("OIDC provider name")
        .setEnabled(true)
        .setClientId("CLIENT_ID")
        .setIssuer("https://oidc.com");
OidcProviderConfig oidc = FirebaseAuth.getInstance().updateOidcProviderConfig(request);
System.out.println("Updated OIDC provider: " + oidc.getProviderId());

완료되면 이 메서드는 업데이트된 구성에 대해 OIDCAuthProviderConfig 객체를 반환합니다.

OIDC 공급업체 구성 가져오기

OIDC 구성을 식별하는 기본 방법은 공급업체 ID를 사용하는 것입니다. 다음 예시는 OIDC 공급업체 구성을 가져오는 방법을 보여줍니다.

Node.js

admin.auth().getProviderConfig('oidc.myProvider').then((config) => {
  // Get display name and whether it is enabled.
  console.log(config.displayName, config.enabled);
}).catch((error) => {
  // Handle error. Common error is that config is not found.
});

Go

oidc, err := client.OIDCProviderConfig(ctx, "oidc.myProvider")
if err != nil {
	log.Fatalf("error retrieving OIDC provider: %v\n", err)
}

log.Printf("%s %t", oidc.DisplayName, oidc.Enabled)

Python

oidc = auth.get_oidc_provider_config('oidc.myProvider')

print(oidc.display_name, oidc.enabled)

자바

OidcProviderConfig oidc = FirebaseAuth.getInstance().getOidcProviderConfig("oidc.myProvider");
System.out.println(oidc.getDisplayName() + ": " + oidc.isEnabled());

지정된 ID를 가진 공급업체가 존재하는 경우 이 메서드는 OIDCAuthProviderConfig 객체를 반환합니다.

OIDC 공급업체 구성 삭제

다음 예시에서는 OIDC 공급업체 구성을 삭제하는 방법을 보여줍니다.

Node.js

admin.auth().deleteProviderConfig('oidc.myProvider').then(() => {
  // Successful deletion.
}).catch((error) => {
  // Handle error.
});

Go

if err := client.DeleteOIDCProviderConfig(ctx, "oidc.myProvider"); err != nil {
	log.Fatalf("error deleting OIDC provider: %v\n", err)
}

Python

auth.delete_oidc_provider_config('oidc.myProvider')

자바

FirebaseAuth.getInstance().deleteOidcProviderConfig("oidc.myProvider");

OIDC 공급업체 구성 나열

다음 예는 기존 OIDC 공급업체 구성을 나열하는 방법을 보여줍니다.

Node.js

// Returns 10 OIDC provider configs starting from the specified nextPageToken offset.
admin.auth().listProviderConfigs({type: 'oidc', maxResults: 10, pageToken: 'nextPageToken'}).then((results) => {
  results.providerConfigs.forEach((config) => {
    console.log(config.providerId);
  });
  // To list the next 10:
  // return admin.auth().listProviderConfigs(
  //     {type: 'oidc', maxResults: 10, pageToken: results.pageToken});
}).catch((error) => {
  // Handle error.
});

Go

iter := client.OIDCProviderConfigs(ctx, "nextPageToken")
for {
	oidc, err := iter.Next()
	if err == iterator.Done {
		break
	}
	if err != nil {
		log.Fatalf("error retrieving OIDC providers: %v\n", err)
	}

	log.Printf("%s\n", oidc.ID)
}

Python

for oidc in auth.list_oidc_provider_configs('nextPageToken').iterate_all():
    print(oidc.provider_id)

자바

ListProviderConfigsPage<OidcProviderConfig> page = FirebaseAuth.getInstance()
    .listOidcProviderConfigs("nextPageToken");
for (OidcProviderConfig oidc : page.iterateAll()) {
  System.out.println(oidc.getProviderId());
}

각 결과 배치에는 공급업체 구성 목록과 함께 다음 배치를 가져오는 데 사용되는 다음 페이지 토큰이 들어 있습니다. 모든 공급업체가 나열되면 토큰이 반환되지 않습니다.

기본적으로 100개의 공급업체가 각 배치와 함께 반환됩니다. 이는 배치당 최대 공급업체 수이기도 합니다.

다음 단계