Tipo de otorgamiento de intercambio de token: intercambio de un token de Kerberos para una UPST

Utilice el intercambio de tokens de Kerberos donde Kerberos es el proveedor de autenticación y debe intercambiar tokens de Kerberos por tokens o principales de IAM para acceder a los servicios de OCI. Los tokens de Kerberos se intercambian por tokens de sesión de principal de usuario (UPST) de OCI en IAM.

Términos de token de Kerberos
Término Descripción
Kerberos

Un sistema de autenticación multiplataforma y conexión única. El protocolo Kerberos proporciona autenticación mutua entre dos entidades que dependen de un secreto compartido (claves simétricas). La autenticación de Kerberos requiere un cliente, un servidor y una parte de confianza para mediar entre ellos denominado Centro de distribución de claves (KDC).

También es necesario lo siguiente:

  • Un principal: una identidad para un usuario (a un usuario se le asigna un principal) o una identidad para una aplicación que ofrece servicios Kerberos.

  • Un dominio: un entorno de servidor Kerberos, que puede ser un nombre de dominio como example.com. Cada dominio Kerberos tiene al menos un KDC de seguridad de servicios web.

El perfil de token de Kerberos de WS-Security permite a los socios comerciales utilizar tokens de Kerberos en arquitecturas orientadas a servicios (SOA).

Centro de distribución de claves (KDC) de Kerberos Un servidor de autenticación de terceros.
Active Directory (AD) Un repositorio para el servidor KDC.
Tabla de claves

Un archivo que almacena la clave de cifrado real que se puede utilizar en lugar de una comprobación de contraseña para un principal específico. Los archivos keytab son útiles para casos de uso no interactivos.

Consejo: la herramienta de administración de KDC se puede utilizar para crear un archivo keytab. Durante la creación de la tabla de claves, se puede especificar el tipo de cifrado. Utilice el siguiente tipo de cifrado: aes256-cts-hmac-sha1-96.

Mecanismo de negociación GSSAPI simple y protegido (SPNEGO)

El Mecanismo de Negociación GSSAPI simple y protegido (SPNEGO) es un "pseudomecanismo" GSSAPI utilizado por el software cliente/servidor para negociar la elección de la tecnología de seguridad.

Los tickets de Kerberos se ajustan como parte del token SPNEGO para que el token funcione con la capa de aplicación basada en HTTP.

Detalles y formato de token de SPNEGO

El formato de token SPNEGO se define en RFC 4178. El token es una estructura de datos serializada que contiene los siguientes campos:

  • mechTypes: secuencia de identificadores de objeto (OID) que muestra los mecanismos de autenticación soportados.
  • mechToken: token de mecanismo optimista. Este es un token que se utiliza para negociar el mecanismo de autenticación real que se utilizará.
  • krb5Creds: blob de Kerberos. Este es un blob binario que contiene la información de autenticación de Kerberos.

El token SPNEGO está codificado en ASN.1. A continuación se muestra un ejemplo de un token SPNEGO:

NegTokenInit ::= SEQUENCE
{
mechTypes SEQUENCE OF Oid,
mechToken OCTET STRING,
krb5Creds [0] KerberosCreds OPTIONAL
}
GSSAPI Interfaz de programa de aplicación de servicios de seguridad genéricos
API del servicio IAM Token Exchange Servicio OAuth del dominio de identidad de IAM: /oauth2/v1/token. La API acepta cabeceras/carga útil de autenticación basadas en OAuth estándar y firmas de OCI. Para obtener más información sobre cómo utilizar un cliente OAuth con un dominio de identidad para acceder a las API de REST, consulte Uso de OAuth 2 para acceder a la API de REST.
Configuración de confianza de propagación de identidad Utilice las configuraciones de confianza de propagación de identidad para establecer la confianza entre OCI Identity y un proveedor de identidad externo y validar el token del proveedor de identidad externo y la asignación de la identidad de usuario del proveedor de identidad externo con la identidad de usuario en IAM. La confianza de propagación de identidad también facilita la propagación de identidad de un proveedor de identidad externo a OCI. El diseño de punto final /IdentityPropagationTrust es genérico y funciona con cualquier proveedor de nube. Para crear una configuración de protección de propagación de identidad, consulte el Step 6: Create an Identity Propagation Trust Configuration.
Usuario de Servicio Usuario sin privilegios de inicio de sesión interactivo. Estos usuarios de servicio se pueden otorgar a grupos y roles de servicio. Las aplicaciones pueden utilizar estos usuarios del servicio o el usuario conectado puede suplantarlos para obtener una UPST temporal. El uso de un usuario de servicio es opcional. Para obtener más información sobre el uso de usuarios de servicio, consulte el Paso 5: Uso de un usuario de servicio (opcional).
Token de sesión de principal de usuario (UPST) Token generado por IAM. También se conoce como token de seguridad. Representa el usuario de servicio autenticado.

Pasos de intercambio de token de Kerberos

Utilice los siguientes pasos para intercambiar un token de Kerberos para una UPST:

  1. Paso 1: Crear un almacén y agregar el contenido del archivo de tabla de claves
  2. Paso 2: Creación de la política de IAM necesaria
  3. Paso 3: Creación de una aplicación de dominio de identidad
  4. Paso 4: Generar un token SPNEGO para un principal de usuario específico
  5. Paso 5: Uso de un usuario de servicio (opcional)
  6. Paso 6: Creación de una configuración de confianza de propagación de identidad
  7. Paso 7: Obtener OCI UPST

Paso 1: Crear un almacén y agregar el contenido del archivo keytab

Cree un almacén y agregue el contenido del archivo keytab como una cadena codificada en base64. Nota: IAM no almacena el archivo keytab en su sistema de archivos.

Utilice los siguientes pasos como guía:

  1. Creación de un almacén. Consulte Creación de un almacén.
  2. Lea el contenido de la tabla de claves en formato Base64.
  3. Vaya al almacén y almacénelo tal cual, asegurándose de marcar Base64 como la plantilla de tipo secreto al crear el secreto. Consulte Creación de un secreto en un almacén.

Paso 2: Crear la política de IAM necesaria

Cree una política de IAM en el arrendamiento para permitir que un recurso de dominio de identidad acceda a Vault. Esto permite a IAM recuperar la configuración de keytab de Vault. Utilice el siguiente ejemplo como guía:

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>}

Paso 3: Creación de una aplicación de dominio de identidad

Cree una aplicación confidencial de dominio de identidad. Después de crear la aplicación, guarde el id de cliente y el secreto de cliente en una ubicación segura. Consulte Adición de una aplicación confidencial.

Paso 4: Generar un token SPNEGO para un principal de usuario específico

  1. Utilice código Java para conectarse al servidor KDC y generar el token SPNEGO.
  2. Copie ese token SPNEGO para formar la solicitud de token.

Utilice el siguiente ejemplo de código Java como guía:

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;

    }
}

Paso 5: Uso de un usuario de servicio (opcional)

Un usuario de servicio es un usuario de dominios de identidad con el atributo serviceUser definido en true.

Nota

El uso de un usuario de servicio es opcional. Si la suplantación de usuario se utilizará como parte de la configuración de confianza, se necesitan usuarios de servicio. De lo contrario, se utiliza cualquier otro usuario del dominio de identidad. Solo los administradores del dominio de identidad pueden crear, sustituir, actualizar o suprimir un usuario de servicio. Otros administradores pueden leer los usuarios del servicio y sus atributos.

Para utilizar un usuario de servicio, cree uno sin privilegios de conexión interactivos. Estos usuarios de servicio se pueden otorgar a grupos y roles de servicio. Sus aplicaciones pueden utilizar estos usuarios de servicio o el usuario conectado puede suplantarlos para obtener un token de UPST temporal.

Los usuarios de servicio tienen las siguientes características:

  • Debe tener un userName. El nombre y el apellido no son necesarios.
  • Puede tener una dirección de correo electrónico (Opcional).
  • Puede ser miembro de grupos y roles de aplicación.
  • No puede haber claves API.
  • No se pueden utilizar puntos finales de autoservicio.
  • No se pueden aplicar contraseñas y políticas de contraseñas.

Ejemplo de Solicitud: Creación de un Usuario de Servicio

A continuación, se muestra un ejemplo de una solicitud con los atributos mínimos necesarios para crear un usuario de servicio.

## 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"
}

Ejemplo de respuesta: creación de un usuario de servicio

A continuación, se muestra un ejemplo de una respuesta al crear un usuario de servicio.

{
    "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"
    ]
}

Paso 6: Creación de una configuración de confianza de propagación de identidad

La configuración de confianza de propagación de identidad se utiliza para establecer la confianza entre OCI Identity y los proveedores de nube externos, la validación del token de proveedor de nube y la asignación de la identidad de usuario del proveedor de nube con la identidad de usuario de los dominios de identidad service.

Descripción detallada de una configuración de confianza de propagación de identidad
Atributo obligatorio? Descripciones y ejemplos
nombre

El nombre del fideicomisario.

tipo

Tipo de token:

  • Italiano
  • jwt
  • saml
  • aws-credential
emisor

Use Emisor para encontrar la identificación del fideicomiso. Por ejemplo, si el token SPNEGO se genera mediante el principal de servicio, IAMSp, IAMSp es el valor del emisor.

Ejemplo: IAMTokenExchangeServicePrincipal

activas

Si está activado, true.

Si está desactivado, false.

oauthClients

Lista de clientes OAuth que pueden obtener tokens para un partner de confianza específico.

Ejemplo:
"oauthClients": [
 "oauthclient-id"
 ],
allowImpersonation (utilizar serviceUser) No

Valor booleano. Especifica si el UPST resultante debe contener el usuario autenticado como asunto o si debe suplantar a un usuario de servicio en IAM.

impersonatingServiceUser

Sí, si allowImpersonation está definido en true.

Especifica qué principal resultante se va a suplantar según el nombre de reclamación de token y las condiciones de valor. Puede:

  • Permitir un principal de suplantación específico para todos los usuarios autenticados del proveedor de identidad (IdP).
  • Defina reglas para definir condiciones de suplantación:
    • Según el nombre de la reclamación de token
    • Condición: contiene (co) o es igual a (eq)
    • Valor:
      • Puede ser una cadena.
      • La matriz de valores y los valores complejos/compuestos no están soportados.
      • Con la condición equals: wild card (*) is allowed (Se permite comodín (*).
      • Con la condición contains: wild card (*) not supported (No se admite comodín (*).
    • Suplantación de principal.

Ejemplo:

  • Regla: "username" eq kafka*
  • Usuario de servicio asignado: kafka
  • Resultado: todos los usuarios autenticados que comienzan con el prefijo kafka se suplantan con el usuario de IAM Service kafka. El UPST resultante contiene kafka como principal de usuario autenticado.

Si se permite la suplantación, el token de seguridad de OCI (UPST) resultante tendrá la reclamación relacionada con el usuario autenticado original (source_authn_prin), así como para indicar en cuyo nombre se realiza la suplantación.

  • Si se configura el nombre de reclamación de asunto, se utilizará para extraer ese valor de reclamación.
  • Si el nombre de reclamación de asunto no está configurado, el valor por defecto es sub en el token entrante. Si la reclamación sub no está presente, se ignora.
La evaluación se para con la primera regla coincidente y el principal resultante correspondiente se devuelve mediante el atributo display name. Si no hay reglas coincidentes, la solicitud de token falla con errores.
tabla de claves

Sí, si el tipo de token es SPNEGO.

Recupera la configuración de tabla de claves del almacén.

Importante:
  • El servicio de intercambio de tokens recupera la información del secreto según el OCID del secreto y la versión del secreto.

  • Si la tabla de claves se rota en el servidor KDC, debe actualizar la información del secreto en la configuración de protección de propagación de identidad.

  • Si se rota keytab en Vault, debe actualizar la información secreta en la configuración de protección de propagación de identidad.

Ejemplo de solicitud: creación de una configuración de confianza de propagación de identidad

A continuación, se muestra un ejemplo de una solicitud para crear una configuración de confianza de propagación de identidad.
## 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"
 ]
}

Ejemplo de respuesta: creación de una configuración de confianza de propagación de identidad

A continuación, se muestra un ejemplo de una respuesta al crear una configuración de confianza de propagación de identidad.
  "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>"
    }
  }

Paso 7: Obtener OCI UPST

Descripción detallada de la carga útil de solicitud de token de UPST
Parámetro de solicitud 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>'

Flujo de trabajo de clave pública:

  1. La carga de trabajo genera un par de claves.
  2. La clave pública se envía como parte de la solicitud de intercambio de token, que se agrega como reclamación, jwk, a la UPST resultante.
  3. La clave privada se utiliza para generar las firmas de OCI para la llamada de API de servicios nativos de OCI junto con UPST.
  4. La autenticación de servicios de OCI valida el UPST, extrae la reclamación jwk del UPST y, a continuación, lo utiliza para validar la firma de OCI.

subject_token_type

'subject_token_type=spnego'

  • Italiano
  • jwt
  • saml
  • aws-credential

subject_token

'subject_token=<subject-token>'

Si el tipo de token es:

  • spnego: token cifrado opaco.
  • jwt o saml: valor de afirmación jwt o saml tal cual.
  • aws-credential: valor codificado base64 de las credenciales de AWS que aparecen en formato XML.

issuer

Obligatorio si el tipo de token es spnego.

Ejemplo:

IAMTokenExchangeServicePrincipal

Ejemplo de solicitud de token UPST: basado en firma de OCI

A continuación se muestra un ejemplo de solicitud de cURL basada en firmas de 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>"
}

Ejemplo de solicitud de token de UPST: basado en aplicación de dominio de identidad

A continuación se muestra un ejemplo de solicitud de cURL basada en la aplicación del dominio de identidad de 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>"
}