Tipo de Concessão de Troca de Token: Trocando um Token Kerberos para um UPST

Use o intercâmbio de tokens do Kerberos em que o Kerberos é o provedor de autenticação e você precisa trocar tokens do Kerberos por tokens ou principais do serviço IAM para acessar serviços do OCI. Você troca tokens do Kerberos por tokens de sessão do controlador de usuários (UPST) do OCI no serviço IAM.

Termos do Token do Kerberos
Termo Descrição
Kerberos

Uma autenticação multiplataforma e um sistema de sign-on único. O protocolo Kerberos fornece autenticação mútua entre duas entidades que dependem de um segredo compartilhado (chaves simétricas). A autenticação do Kerberos requer que um cliente, um servidor e uma parte confiável façam a mediação entre eles chamada KDC (Key Distribution Center).

O seguinte também é necessário:

  • Um Principal: Uma identidade de um usuário (um usuário recebe um principal) ou uma identidade de um aplicativo que oferece serviços Kerberos.

  • Um Realm: Um ambiente de servidor Kerberos, que pode ser um nome de domínio, como example.com. Cada realm do Kerberos tem pelo menos um KDC de Segurança de Web Services.

O perfil de Token do Kerberos do WS-Security permite que parceiros de negócios usem tokens do Kerberos em arquiteturas orientadas a serviços (SOAs).

KDC (Kerberos Key Distribution Center) Um servidor de autenticação de terceiros.
Active Directory (AD) Um repositório para o servidor KDC.
Keytab

Um arquivo que armazena a chave de criptografia real que pode ser usada em vez de um desafio de senha para um principal específico. Os arquivos de keytab são úteis para casos de uso não interativos.

Dica: A ferramenta de administração do KDC pode ser usada para criar um arquivo keytab. Durante a criação do keytab, o tipo de criptografia pode ser especificado. Use o seguinte tipo de criptografia: aes256-cts-hmac-sha1-96.

Mecanismo de Negociação GSSAPI Simples e Protegido (SPNEGO)

O Mecanismo de Negociação GSSAPI Simples e Protegido (SPNEGO) é um "mecanismo pseudo" GSSAPI usado pelo software cliente/servidor para negociar a escolha da tecnologia de segurança.

Os tickets do Kerberos são encapsulados como parte do token SPNEGO para que o token funcione com a camada de aplicativo baseada em HTTP.

Formato e Detalhes do Token SPNEGO

O formato do token SPNEGO é definido na RFC 4178. O token é uma estrutura de dados serializada que contém os seguintes campos:

  • mechTypes: Uma sequência de identificadores de objeto (OID) que lista os mecanismos de autenticação suportados.
  • mechToken: Um token de mecanismo otimista. Este é um token usado para negociar o mecanismo de autenticação real que será usado.
  • krb5Creds: Um blob do Kerberos. Este é um blob binário que contém as informações de autenticação do Kerberos.

O token SPNEGO é codificado no ASN.1. Veja a seguir um exemplo de token SPNEGO:

NegTokenInit ::= SEQUENCE
{
mechTypes SEQUENCE OF Oid,
mechToken OCTET STRING,
krb5Creds [0] KerberosCreds OPTIONAL
}
GSSAPI Interface do Programa de Aplicativo Genérico dos Serviços de Segurança
API do Serviço Token Exchange do IAM Serviço OAuth do domínio de identidades do serviço IAM: /oauth2/v1/token. A API aceita cabeçalhos/payload de autenticação baseados em OAuth padrão e Assinaturas do OCI. Para saber como usar um cliente OAuth com um domínio de identidades para acessar as APIs REST, consulte Usando OAuth 2 para Acessar a API REST.
Configuração de Confiança de Propagação de Identidade Use as configurações de Confiança de Propagação de Identidade para estabelecer a confiança entre a Identidade do OCI e um provedor de identidades externo e validar o token do provedor de identidades externo e o mapeamento da identidade do usuário do provedor de identidades externo com a identidade do usuário no serviço IAM. O Identity Propagation Trust também facilita a propagação de identidade de um provedor de identidades externo para o OCI. O design de ponto final /IdentityPropagationTrust é genérico e funciona com qualquer provedor de nuvem. Para criar uma configuração Confiável de Propagação de Identidade, consulte Etapa 6: Criar uma Configuração Confiável de Propagação de Identidade.
Usuário do Serviço Um usuário sem privilégios de log-in interativo. Esses Usuários de Serviço podem ser concedidos a grupos e atribuições de serviço. Os aplicativos podem usar esses Usuários de Serviço ou o usuário conectado pode personificá-los para obter um UPST temporário. Usar um Usuário de Serviço é opcional. Para obter mais informações sobre como usar Usuários de Serviço, consulte a Etapa 5: Usar um Usuário de Serviço (Opcional).
Token da Sessão Principal do Usuário (UPST) Um token gerado pelo serviço IAM. Também conhecido como token de segurança. Ele representa o Usuário de Serviço autenticado.

Etapas de Troca de Token do Kerberos

Use as seguintes etapas para trocar um token do Kerberos por um UPST:

  1. Etapa 1: Criar um Vault e Adicionar o Conteúdo do Arquivo do Keytab
  2. Etapa 2: Criar a Política do Serviço IAM Obrigatória
  3. Etapa 3: Criar um Aplicativo de Domínio de Identidades
  4. Etapa 4: Gerar um Token SPNEGO para um Usuário Principal Específico
  5. Etapa 5: Usar um Usuário de Serviço (Opcional)
  6. Etapa 6: Criar uma Configuração de Confiança de Propagação de Identidade
  7. Etapa 7: Obtenha o OCI UPST

Etapa 1: Criar um Vault e Adicionar o Conteúdo do Arquivo do Keytab

Crie um Vault e adicione o conteúdo do arquivo keytab como uma string codificada em base64. Observação: O serviço IAM não armazena o arquivo keytab em seu sistema de arquivos.

Siga estas etapas como guia:

  1. Criar um Vault. Consulte Criando um Vault.
  2. Leia o conteúdo da keytab no formato Base64.
  3. Vá para o Vault e armazene-o como está, certificando-se de verificar Base64 como o Modelo de Tipo de Segredo ao criar o segredo. Consulte Criando um Segredo em um Vault.

Etapa 2: Criar a Política do Serviço IAM Obrigatória

Crie uma política do serviço IAM na tenancy para permitir que um recurso de domínio de identidades acesse o serviço Vault. Isso permite que o serviço IAM recupere a configuração do keytab do serviço Vault. Use o seguinte exemplo como guia:

allow resource iam-domain <domain_displayName> to read secrets from vault in compartment <compartment_ocid> where all {target.secret.id = <secret_ocid_where_the_keytab_is_present>}

Etapa 3: Criar um Aplicativo de Domínio de Identidades

Crie um aplicativo Confidencial do domínio de identidades. Depois de criar o aplicativo, salve o id do cliente e o segredo do cliente em um local seguro. Consulte Adicionando um Aplicativo Confidencial.

Etapa 4: Gerar um Token SPNEGO para um Usuário Principal Específico

  1. Use o código Java para estabelecer conexão com o Servidor KDC e gerar o token SPNEGO.
  2. Copie esse token SPNEGO para formar a solicitação de token.

Use o seguinte exemplo de código Java como guia:

package com.oracle;

import com.sun.security.auth.module.Krb5LoginModule;
import org.ietf.jgss.GSSContext;
import org.ietf.jgss.GSSException;
import org.ietf.jgss.GSSManager;
import org.ietf.jgss.GSSName;
import org.ietf.jgss.Oid;

import javax.security.auth.Subject;
import java.io.IOException;
import java.security.Principal;
import java.security.PrivilegedAction;
import java.util.Base64;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

public class GenerateSpnegoToken {
    static String servicePrincipal = "HTTP/iamtesp@WINDOWSKDCSERVER.COM";
    static String userPrincipal = "HTTP/<sample-job>@WINDOWSKDCSERVER.COM";
    static String userPrincipalKeyTab = "keytabs/ms/<sample-job>.keytab";
    public static void main(String[] args) throws IOException {
        System.setProperty("sun.security.krb5.debug", "true");
        System.setProperty("sun.security.spnego.debug", "true");
        System.setProperty("java.security.krb5.conf", "ms_krb5.conf");

        String spnegoToken = generateSpnegoToken();
    }
    private static String generateSpnegoToken() {
        Subject subject = getAuthenticateSubject();
        return Subject.doAs(
                subject,
                (PrivilegedAction<String>)
                        () -> {
                            String SPNEGO_OID = "1.3.6.1.5.5.2";
                            String KRB5_MECHANISM_OID = "1.2.840.113554.1.2.2";
                            String KRB5_PRINCIPAL_NAME_OID = "1.2.840.113554.1.2.2.1";

                            try {
                                // Create GSS context for the service principal and the logged-in user
                                Oid krb5Mechanism = new Oid(KRB5_MECHANISM_OID);
                                Oid krb5PrincipalNameType = new Oid(KRB5_PRINCIPAL_NAME_OID);
                                Oid spnegoOid = new Oid(SPNEGO_OID);
                                GSSManager manager = GSSManager.getInstance();
                                GSSName gssServerName =
                                        manager.createName(servicePrincipal, krb5PrincipalNameType, krb5Mechanism);
                                GSSContext gssContext =
                                        manager.createContext(
                                                gssServerName, spnegoOid, null, 240000);
                                gssContext.requestMutualAuth(true);
                                gssContext.requestCredDeleg(true);
                                gssContext.requestLifetime(10);

                                // Generate the SPNEGO token
                                byte[] token = new byte[0];
                                token = gssContext.initSecContext(token, 0, token.length);
                                return Base64.getEncoder().encodeToString(token);
                            } catch (GSSException e) {
                                throw new RuntimeException(e);
                            }
                        });
    }

    private static Subject getAuthenticateSubject() {
        final Map<String, String> options = new HashMap<>();
        options.put("keyTab", userPrincipalKeyTab);
        options.put("principal", userPrincipal);
        options.put("doNotPrompt", "true");
        options.put("isInitiator", "true");
        options.put("refreshKrb5Config", "true");
        options.put("storeKey", "true");
        options.put("useKeyTab", "true");

        // Execute the login
        Subject subject = new Subject();
        Krb5LoginModule krb5LoginModule = new Krb5LoginModule();
        krb5LoginModule.initialize(subject, null, new HashMap<String, String>(), options);
        try {
            krb5LoginModule.login();
            krb5LoginModule.commit();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        Set<Principal> principals = (Set<Principal>) subject.getPrincipals();
        Iterator<Principal> iterator = principals.iterator();
        while (iterator.hasNext()) {
            System.out.println("\nprincipal : " + ((Principal) iterator.next()));
        }

        return subject;

    }
}

Etapa 5: Usar um Usuário de Serviço (Opcional)

Um Usuário de Serviço é um Usuário de domínios de identidades com o atributo serviceUser definido como true.

Observação

O uso de um Usuário de Serviço é opcional. Se a personificação do usuário for usada como parte da configuração de Confiança, os Usuários do Serviço serão necessários. Caso contrário, qualquer outro usuário do domínio de identidades será usado. Somente administradores de domínio de identidades podem criar, substituir, atualizar ou excluir um Usuário de Serviço. Outros administradores podem ler Usuários de Serviço e seus atributos.

Para usar um Usuário de Serviço, crie um sem privilégios de log-in interativos. Esses Usuários de Serviço podem ser concedidos a grupos e atribuições de serviço. Seus aplicativos podem usar esses Usuários de Serviço ou o usuário conectado pode personificá-los para obter um token UPST temporário.

Os Usuários do Serviço têm as seguintes características:

  • Deve ter um userName. O nome e o sobrenome não são obrigatórios.
  • Pode ter um endereço de e-mail (Opcional).
  • Pode ser membro de grupos e funções de aplicativo.
  • Não é possível ter chaves de API.
  • Não é possível usar pontos finais de autoatendimento.
  • Não é possível ter senhas e políticas de senha não se aplicam.

Exemplo de Solicitação: Criar um Usuário de Serviço

Veja a seguir um exemplo de solicitação com os atributos mínimos necessários para criar um Usuário de Serviço.

## POST on https://<domainURL>/admin/v1/Users
## Payload:
{
    "schemas": [
        "urn:ietf:params:scim:schemas:core:2.0:User"
    ],
    "urn:ietf:params:scim:schemas:oracle:idcs:extension:user:User": {
        "serviceUser": true
    },
    "userName": "myServiceUserName"
}

Exemplo de Resposta: Criar um Usuário de Serviço

Veja a seguir um exemplo de resposta ao criar um Usuário de Serviço.

{
    "idcsCreatedBy": {
        "type": "App",
        "display": "idcsadmin"
    },
    "id": "<user_id>",
    "urn:ietf:params:scim:schemas:oracle:idcs:extension:user:User": {
        "isFederatedUser": false,
        "isGroupMembershipSyncedToUsersGroups": true,
        "serviceUser": true
    },
    "meta": {
        "created": "2023-12-07T06:52:55.380Z",
        "lastModified": "2023-12-07T06:52:55.380Z",
        "version": "<version>",
        "resourceType": "User",
        "location": "https://<domainURL>/admin/v1/Users/<user_id>"
    },
    "active": true,
    "idcsLastModifiedBy": {
        "display": "idcsadmin",
        "type": "App"
    },
    "urn:ietf:params:scim:schemas:oracle:idcs:extension:userState:User": {
        "locked": {
            "on": false
        }
    },
    "ocid": "ocid1.user.region1...<ocid>",
    "userName": "myServiceUserName",
    "schemas": [
        "urn:ietf:params:scim:schemas:core:2.0:User",
        "urn:ietf:params:scim:schemas:oracle:idcs:extension:userState:User",
        "urn:ietf:params:scim:schemas:oracle:idcs:extension:capabilities:User",
        "urn:ietf:params:scim:schemas:oracle:idcs:extension:user:User"
    ]
}

Etapa 6: Criar uma Configuração de Confiança de Propagação de Identidade

A configuração Confiança de Propagação de Identidade é usada para estabelecer a confiança entre a Identidade do OCI e os provedores de Nuvem externos, a validação do token do provedor de Nuvem e o mapeamento da identidade do usuário do provedor de Nuvem com a identidade do usuário service dos domínios de identidade.

Descrição Detalhada de uma Configuração Confiável de Propagação de Identidade
Atributo Obrigatório? Descrições e Exemplos
nome Sim

O nome da confiança.

tipo Sim

O tipo de token:

  • espnego
  • jwt
  • saml
  • aws-credencial
emissor Sim

Use o Emissor para ajudar a encontrar a identificação de Confiança. Por exemplo, se o token SPNEGO for gerado usando o controlador de serviço, IAMSp, IAMSp será o valor do emissor.

Exemplo: IAMTokenExchangeServicePrincipal

ativo Sim

Se ativada, true.

Se desativado, false.

oauthClients Sim

Uma lista de Clientes OAuth que têm permissão para obter tokens para um parceiro confiável específico.

Exemplo:
"oauthClients": [
 "oauthclient-id"
 ],
allowImpersonation (fazer uso de serviceUser) No

Valor Booleano. Especifica se o UPST resultante deve conter o usuário autenticado como assunto ou se ele deve representar um Usuário de Serviço no serviço IAM.

impersonatingServiceUser

Sim, se allowImpersonation for definido como true.

Especifica qual principal resultante será representado com base no nome da reivindicação do token e nas condições de valor. É possível:

  • Permita que um principal personificador específico para todos os usuários autenticados do provedor de identidades (IdP).
  • Defina regras para definir condições de representação:
    • Com base no nome da reivindicação do Token
    • Condição: contém (co) ou é igual a (eq)
    • Valor:
      • Pode ser uma string.
      • Matriz de valores e valores complexos/compostos não são suportados.
      • Com condição igual a: curinga (*) é permitido.
      • Com a condição contains: wild card (*) não é suportado.
    • Representando o diretor.

Exemplo:

  • Regra: "username" eq kafka*
  • Usuário de Serviço Mapeado: kafka
  • Resultado: Todos os usuários autenticados que começam com o prefixo kafka são representados pelo Usuário do Serviço IAM kafka. O UPST resultante contém kafka como o principal do usuário autenticado.

Se a representação for permitida, o token de segurança (UPST) resultante do OCI terá a reivindicação original autenticada relacionada ao usuário (source_authn_prin) também para indicar em cujo nome a representação é feita.

  • Se o nome da reivindicação do assunto estiver configurado, ele será usado para extrair esse valor da reivindicação.
  • Se o nome da reivindicação do assunto não estiver configurado, o padrão será sub no token de entrada. Se a própria reivindicação sub não estiver presente, ela será ignorada.
A avaliação é interrompida com a primeira regra correspondente e o principal resultante correspondente é retornado usando o atributo de nome para exibição. Se nenhuma regra for correspondida, a solicitação de token falhará com erros.
keytab

Sim, se o tipo de token for SPNEGO.

Recupera a configuração do keytab do serviço Vault.

Importante:
  • O serviço de intercâmbio de tokens recupera as informações de segredo com base no OCID do segredo e na versão do segredo.

  • Se o keytab for rotacionado no servidor KDC, você deverá atualizar as informações secretas na configuração do Identity Propagation Trust.

  • Se o keytab for rotacionado no serviço Vault, atualize as informações secretas na configuração da Confiança de Propagação de Identidade.

Exemplo de Solicitação: Criar uma Configuração Confiável de Propagação de Identidade

Veja a seguir um exemplo de solicitação para criar uma configuração de Confiança de Propagação de Identidade.
## POST on https://<domainURL>/admin/v1/IdentityPropagationTrusts
## Payload:
{
 "active": true,
 "allowImpersonation": false,
 "issuer": "idcs_psr_itp",
 "name": "<identity_propagation_trust_name>",
 "oauthClients": [
 "<oauthclient-id>"
 ],
 "keytab": {
 "secretOcid": "<secret_ocid>"
 },
 "subjectMappingAttribute": "userName",
 "subjectType": "User",
 "type": "SPNEGO",
 "schemas": [
 "urn:ietf:params:scim:schemas:oracle:idcs:IdentityPropagationTrust"
 ]
}

Exemplo de Resposta: Criar uma Configuração Confiável de Propagação de Identidade

Veja a seguir um exemplo de resposta ao criar uma configuração de Confiança de Propagação de Identidade.
  "response": {
    "name": "<identity_propagation_trust_name>",
    "type": "<token_type>",
    "issuer": "idcs_psr_itp",
    "accountId": "<example_account_id>",
    "subjectClaimName": "cognito:username",
    "subjectMappingAttribute": "username",
    "subjectType": "User",
    "clientClaimName": "appId",
    "clientClaimValues": ["<client_claim_value>"],
    "active": true,
    "publicKeyEndpoint": "https://example.identityprovider.com/publickey/<publickey_value>",
    "publicCertificate": "<public_certificate_value>",
    "oauthClients": ["<oauthclient-id>"],

    "allowImpersonation": true,
    "impersonationServiceUsers": [
      {
        "rule": "groups co \"network-admin\"",
        "userId": "<user_id>"
      },
      {
        "rule": "groups co \"tenancy-admin\"",
        "userId": "<user_id>"
      }
    ],
    "keytab": {
      "secretOcid": "<secret_ocid>",
      "secretVersion": "<secret_version>"
    },
    "clockSkewSeconds": 60,
    "id": "<identity_propagation_trust_id>",
    "meta": {
      "created": "2023-11-09T23:26:53.224Z",
      "lastModified": "2023-11-09T23:26:53.224Z",
      "resourceType": "IdentityPropagationTrust",
      "location": "http://example.hostname.com:8990/admin/v1/IdentityPropagationTrusts/<identity_propagation_trust_id>"
    },
    "schemas": [
      "urn:ietf:params:scim:schemas:oracle:idcs:IdentityPropagationTrust"
    ],
    "idcsCreatedBy": {
      "value": "<app_id>",
      "display": "admin",
      "type":"App",
      "$ref": "http://example.hostname.com:8990/admin/v1/Apps/<app_id>"
    },
    "idcsLastModifiedBy": {
      "value": "<app_id>",
      "display": "admin",
      "type":"App",
      "$ref": "http://example.hostname.com:8990/admin/v1/Apps/<app_id>"
    }
  }

Etapa 7: Obtenha o UPST do OCI

Descrição Detalhada do Payload de Solicitação de Token UPST
Parâmetro de Solicitação Valor Válido

grant_type

'grant_type=urn:ietf:params:oauth:grant-type:token-exchange'

requested_token_type

'requested_token_type=urn:oci:token-type:oci-upst'

public_key

'public_key=<public-key-value>'

O workflow de chaves públicas:

  1. A carga de trabalho gera um par de chaves.
  2. A chave pública é enviada como parte da solicitação de troca de token, que é adicionada como uma reivindicação, jwk, no UPST resultante.
  3. A chave privada é usada para gerar as assinaturas do OCI para a chamada de API de serviços nativos do OCI junto com o UPST.
  4. A autenticação dos serviços do OCI valida o UPST, extrai a reivindicação jwk do UPST e a usa para validar a assinatura do OCI.

subject_token_type

'subject_token_type=spnego'

  • espnego
  • jwt
  • saml
  • aws-credencial

subject_token

'subject_token=<subject-token>'

Se o tipo de token for:

  • spnego: O token criptografado opaco.
  • jwt ou saml: O valor de asserção jwt ou saml como está.
  • aws-credential: O valor codificado em base64 das Credenciais da AWS que aparecem no formato XML.

issuer

Obrigatório se o tipo de token for spnego.

Exemplo:

IAMTokenExchangeServicePrincipal

Exemplo de Solicitação de Token UPST: Baseado em Assinatura do OCI

Veja a seguir um exemplo de solicitação cURL baseada em assinatura do OCI.

## OCI Signature Based Request
curl  -X POST -sS https://<domainURL>/oauth2/v1/token -i 
-H 'date: Wed, 06 Dec 2023 01:17:33 GMT' 
-H 'x-content-sha256: <key>' 
-H 'content-type: application/x-www-form-urlencoded;charset=utf-8' 
-H 'content-length: 197' 
-H 'Authorization: Signature version="1",keyId="<key_id>",algorithm="rsa-sha256",headers="(request-target) date host x-content-sha256 content-type content-length",signature="a+aH0b...TLtPA=="'  --data-urlencode 'grant_type=urn:ietf:params:oauth:grant-type:token-exchange' \
--data-urlencode 'requested_token_type=urn:oci:token-type:oci-upst' \
--data-urlencode 'public_key=<public_key>' \
--data-urlencode 'subject_token=<subject_token>' \
--data-urlencode 'subject_token_type=spnego' \
--data-urlencode 'issuer=<Issuer stored in the Identity Trust Propagation. For example, examplead@kdcserver.com>' -k
{
   "token": "<token_id>"
}

Exemplo de Solicitação de Token UPST: Baseado no Aplicativo do Domínio de Identidades

Veja a seguir um exemplo de solicitação cURL baseada em aplicativo do domínio de identidades do OCI.

## IAM Domain App Based Request. Note that client credentials can be sent as part of basic authn header or in the payload.  
curl --location ' https://<domainURL>/oauth2/v1/token' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--header 'Authorization: Basic <auth_code>' \
--data-urlencode 'grant_type=urn:ietf:params:oauth:grant-type:token-exchange' \
--data-urlencode 'requested_token_type=urn:oci:token-type:oci-upst' \
--data-urlencode 'public_key=<public_key>' \
--data-urlencode 'subject_token=<subject_token>' \
--data-urlencode 'subject_token_type=spnego' \
--data-urlencode 'issuer=<Issuer stored in the Identity Trust Propagation. For example, examplead@kdcserver.com>' -k
{
   "token": "<token_id>"
}