Como gerenciar provedores SAML e OIDC de forma programática

Este documento mostra como usar o SDK Admin do Identity Platform para gerenciar as configurações do provedor de linguagem de marcação para autorização de segurança (SAML, na sigla em inglês) 2.0 e OpenID Connect (OIDC) de maneira programática.

Com o SDK Admin, é possível configurar automaticamente os provedores, executar operações básicas de CRUD, alternar certificados e muito mais. Isso é útil quando há muitos provedores que seriam difíceis de gerenciar manualmente usando o console do Google Cloud.

Antes de começar

Como trabalhar com provedores SAML

Como criar uma configuração de provedor SAML

Você precisará fornecer os seguintes parâmetros ao criar uma configuração de provedor de SAML. Talvez seja necessário consultar a documentação do provedor de identidade para ver detalhes sobre como conseguir alguns valores.

Nome de exibição
Um nome de exibição fácil de usar para a configuração. Esse nome também é o rótulo do provedor no console do Google Cloud.
Ativado
Se a configuração atual do provedor está ativada ou desativada. Os usuários não podem fazer login com provedores desativados.
Código do provedor
O identificador exclusivo do provedor, que começa com saml..
ID de entidade do provedor de identidade
O ID da entidade do provedor.
URL do SSO
O URL do SAML SSO para o provedor. O URL deve ser válido.
Certificados X.509

Uma lista de certificados X.509 do provedor SAML, incluindo as strings -----BEGIN CERTIFICATE----- e -----END CERTIFICATE----. Eles são usados para assinar o token no provedor de identidade.

Quando o Identity Platform recebe uma resposta SAML, ele verifica a assinatura usando um certificado no registro. Se a verificação falhar, a resposta será rejeitada. Você precisará atualizar esses certificados à medida que as chaves forem rotacionadas. Faça upload de vários certificados para evitar interrupções durante as rotações.

ID de entidade da pessoa que fez a transmissão
O ID da entidade de terceira parte confiável (RP/SP). Normalmente, esse é o URL do aplicativo. No provedor de identidade SAML, isso é chamado de público.
URL de retorno da chamada

O URL a ser retornado quando a autenticação for concluída. Os provedores de SAML geralmente se referem a isso como o URL do Assertion Consumer Service (ACS). Você precisará registrar esse URL no provedor SAML. Ele terá esta aparência: https://PROJECT-ID.firebaseapp.com/__/auth/handler, semelhante aos URLs exibidos no console do Google Cloud. Para saber mais, consulte Como fazer login de usuários com SAML.

O uso do URL de callback padrão diminuirá a complexidade da validação das respostas SAML. No entanto, você também pode mostrar um domínio personalizado. Nesse caso, verifique se o URL de callback do Identity Platform para o projeto está configurado corretamente com o provedor de identidade SAML. Normalmente, isso é semelhante a https://AUTH-DOMAIN/__/auth/handler.

O exemplo a seguir demonstra como criar uma configuração de provedor 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)

Java

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());

Após a conclusão, o método retorna um objeto SAMLAuthProviderConfig da configuração recém-criada.

Como atualizar uma configuração de provedor SAML

O exemplo a seguir demonstra como modificar uma configuração de provedor SAML. Você pode atualizar qualquer campo, exceto o ID do provedor.

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)

Java

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());

Na conclusão, o método retorna um objeto SAMLAuthProviderConfig da configuração atualizada.

Como conseguir uma configuração de provedor SAML

A principal maneira de identificar uma configuração SAML é usar o ID do provedor. O exemplo a seguir mostra como receber uma configuração de provedor 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)

Java

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

Se existir um provedor com o ID fornecido, o método retornará um objeto SAMLAuthProviderConfig.

Como excluir a configuração de um provedor de SAML

O exemplo a seguir mostra como excluir uma configuração de provedor 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')

Java

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

Como listar configurações do provedor de SAML

O exemplo a seguir mostra como listar as configurações de provedor SAML atuais:

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)

Java

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

Cada lote de resultados contém uma lista de configurações do provedor e um token de próxima página usado para buscar o próximo lote. Quando todos os provedores tiverem sido listados, nenhum token será retornado.

Por padrão, 100 provedores são retornados com cada lote. Esse também é o número máximo de provedores por lote.

Como trabalhar com provedores OIDC

Como criar uma configuração de provedor OIDC

Será necessário fornecer os seguintes parâmetros ao criar uma configuração de provedor do OIDC. Talvez seja necessário consultar a documentação do provedor de identidade para ver detalhes sobre como conseguir alguns valores.

Nome de exibição
Um nome de exibição fácil de usar para a configuração. Esse nome também é o rótulo do provedor no console do Google Cloud.
Ativado
Se a configuração atual do provedor está ativada ou desativada. Os usuários não podem fazer login com provedores desativados.
Código do provedor
O identificador exclusivo do provedor, que começa com oidc..
ID do cliente
O ID usado para confirmar o público-alvo do token de ID de um provedor OIDC.
Client Secret
A chave secreta do cliente necessária para ativar o fluxo de código do OIDC.
Emissor
O Issuer do provedor. É semelhante a: https://example.com. O Identity Platform usa esse URL para localizar o documento de descoberta OIDC (normalmente fica em /.well-known/openid-configuration) que especifica os endpoints OAuth e as chaves públicas do provedor. O Identity Platform valida tokens de ID de acordo com a especificação OpenID Connect. Se o provedor não obedecer à especificação OIDC para descoberta, ele não funcionará com o Identity Platform.
Tipo de resposta
O tipo de resposta do provedor para o fluxo de autorização do OAuth. É possível definir uma das {idToken, code} como true, mas não ambas. Se o fluxo de código estiver ativado, forneça uma chave secreta do cliente.

O exemplo a seguir demonstra como criar uma configuração de provedor OIDC que use o fluxo de autorização implícito:

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)

Java

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());

Após a conclusão, o método retorna um objeto OIDCAuthProviderConfig da configuração recém-criada.

Como atualizar a configuração do provedor OIDC

O exemplo a seguir demonstra como modificar uma configuração de provedor OIDC: Você pode atualizar qualquer campo, exceto o ID do provedor.

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)

Java

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());

Na conclusão, o método retorna um objeto OIDCAuthProviderConfig da configuração atualizada.

Como receber uma configuração de provedor OIDC

A principal maneira de identificar uma configuração do OIDC é usar o ID de provedor dela. O exemplo a seguir mostra como conseguir uma configuração do provedor 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)

Java

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

Se existir um provedor com o ID fornecido, o método retornará um objeto OIDCAuthProviderConfig.

Como excluir uma configuração do provedor OIDC

O exemplo a seguir demonstra como excluir uma configuração de provedor 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')

Java

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

Como listar as configurações do provedor OIDC

O exemplo a seguir mostra como listar configurações de provedor OIDC atuais:

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)

Java

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

Cada lote de resultados contém uma lista de configurações do provedor e um token de próxima página usado para buscar o próximo lote. Quando todos os provedores foram listados, nenhum token é retornado.

Por padrão, 100 provedores são retornados com cada lote. Esse também é o número máximo de provedores por lote.

A seguir