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

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

Termos do Token do Kerberos
Termo Descrição
Kerberos

Um sistema de autenticação multiplataforma e 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 um cliente, um servidor e uma parte confiável para fazer a mediação entre eles chamada KDC (Key Distribution Center).

O seguinte também é necessário:

  • Um Principal: Uma identidade para um usuário (um usuário recebe um principal) ou uma identidade para 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 Kerberos da Segurança WS permite que os parceiros de negócios usem tokens Kerberos em arquiteturas orientadas a serviço (SOAs).

KDC (Centro de Distribuição de Chaves) do Kerberos 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 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 de 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 que é usado para negociar o mecanismo de autenticação real que será usado.
  • krb5Creds: Um blob Kerberos. Este é um blob binário que contém as informações de autenticação do Kerberos.

O token SPNEGO está codificado na 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 Genérica do Programa Aplicativo Serviços Segurança
API do Serviço IAM Token Exchange Serviço OAuth do domínio de identidades do IAM: /oauth2/v1/token. A API aceita cabeçalhos/payload de autenticação baseados no padrão OAuth e assinaturas do OCI. Para saber como usar um cliente OAuth com um domínio de identidades para acessar as APIs REST, consulte Usando o OAuth 2 para Acessar a API REST.
Configuração de Confiança da Propagação de Identidades 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 IAM. A Identity Propagation Trust também facilita a propagação de identidade de um provedor de identidades externo para a OCI. O design do ponto final /IdentityPropagationTrust é genérico e funciona com qualquer provedor de nuvem. Para criar uma configuração de Confiança de Propagação de Identidade, consulte a Etapa 6: Criar uma Configuração de Confiança 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 do Serviço ou o usuário conectado pode personificá-los para obter um UPST temporário. O uso de 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 IAM. Também conhecido como token de segurança. Representa o Usuário do Serviço autenticado.

Etapas do Kerberos Token Exchange

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 Keytab
  2. Etapa 2: Criar a Política de IAM Obrigatória
  3. Etapa 3: Criar um Aplicativo de Domínio de Identidades
  4. Etapa 4: Gerar um Token SPNEGO para um Principal de Usuário 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 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.

Utilize as seguintes etapas como guia:

  1. Criar um Vault. Consulte Criando um Vault.
  2. Leia o conteúdo do 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 de 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 Vault. Use o seguinte exemplo como guia:

allow resource 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 Principal de Usuário 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 identidade 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 do Serviço e seus atributos.

Para usar um Usuário de Serviço, crie um sem privilégios de log-in interativo. 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 atribuiçõ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 as políticas de senha não se aplicam.

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

O exemplo a seguir mostra 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

O exemplo a seguir mostra 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 de 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 de Confiança 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:

  • spnego
  • 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ços, IAMSp, IAMSp será o valor do emissor.

Exemplo: IAMTokenExchangeServicePrincipal

ativo Sim

Se ativado, true.

Se estiver 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) Não

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

impersonatingServiceUser

Sim, se allowImpersonation estiver definido como true.

Especifica qual principal resultante será representado com base no nome da reivindicação de token e nas condições de valor. Você pode:

  • Permita um principal de personificação específico para todos os usuários autenticados do provedor de identidades (IdP).
  • Defina regras para definir condições de personificação:
    • Com base no nome da reivindicação de Token
    • Condição: contém (co) ou é igual a (eq)
    • Valor:
      • Pode ser uma string.
      • Não há suporte para uma matriz de valores e valores complexos/compostos.
      • Com condição igual: cartão curinga (*) é permitido.
      • Com a condição contains: o curinga (*) não é suportado.
    • Representação principal.

Exemplo:

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

Se a personificação for permitida, o token de segurança do OCI (UPST) resultante terá a reivindicação original relacionada ao usuário autenticado (source_authn_prin), bem como para indicar em cujo nome a personificaçã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, ele assumirá como padrão 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 Vault.

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

  • Se o keytab for girado no servidor KDC, você deverá atualizar as informações secretas na configuração da Confiança de Propagação de Identidade.

  • Se o keytab for girado no Vault, atualize as informações secretas na configuração do Identity Propagation Trust.

Exemplo de Solicitação: Criar uma Configuração de Confiança de Propagação de Identidade

O exemplo a seguir mostra 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 de Confiança de Propagação de Identidade

O exemplo a seguir mostra 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\"",
        "value": "<user_id>"
      },
      {
        "rule": "groups co \"tenancy-admin\"",
        "value": "<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 OCI UPST

Descrição Detalhada do Payload de Solicitação de Token UPST
Parâmetro da 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 chave pública:

  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 juntamente com o UPST.
  4. A autenticação de 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'

  • spnego
  • 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 no estado em que se encontra.
  • aws-credential: O valor codificado 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 da 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>"
}