Tipo di concessione scambio token: scambio di un token Kerberos per un UPST

Utilizzare lo scambio di token Kerberos in cui Kerberos è il provider di autenticazione ed è necessario scambiare i token Kerberos per i token o le principal IAM per accedere ai servizi OCI. Si scambiano i token Kerberos per i token di sessione del principal utente OCI (UPST) in IAM.

Termini del token Kerberos
Durata Descrizione
Kerberos

Autenticazione multipiattaforma e sistema Single Sign-On. Il protocollo Kerberos fornisce l'autenticazione reciproca tra due entità che si basano su un segreto condiviso (chiavi simmetriche). L'autenticazione Kerberos richiede che un client, un server e una parte attendibile mediino tra loro chiamato KDC (Key Distribution Center).

È inoltre necessario quanto segue:

  • Principal: identità per un utente (a un utente viene assegnato un principal) o identità per un'applicazione che offre servizi Kerberos.

  • Un realm: un ambiente server Kerberos, che può essere un nome di dominio quale example.com. Ogni realm Kerberos dispone di almeno un KDC Sicurezza servizi Web.

Il profilo Token Kerberos di WS-Security consente ai partner commerciali di utilizzare i token Kerberos nelle architetture SOA (Service-Oriented Architecture).

Centro di distribuzione delle chiavi Kerberos (KDC) Server di autenticazione di terze parti.
Active Directory (AD) Repository per il server KDC.
Keytab

File in cui è memorizzata la chiave di cifratura effettiva che può essere utilizzata al posto della richiesta di verifica password per un principal specifico. I file keytab sono utili per i casi d'uso non interattivi.

Suggerimento: è possibile utilizzare lo strumento di amministrazione KDC per creare un file keytab. Durante la creazione della tabella chiavi, è possibile specificare il tipo di cifratura. Usare il seguente tipo di cifratura: aes256-cts-hmac-sha1-96.

Meccanismo di negoziazione GSSAPI semplice e protetto (SPNEGO)

Simple and Protected GSSAPI Negotiation Mechanism (SPNEGO) è un "pseudo meccanismo" GSSAPI utilizzato dal software client/server per negoziare la scelta della tecnologia di sicurezza.

I ticket Kerberos vengono sottoposti a wrapping come parte del token SPNEGO in modo che il token funzioni con il livello di applicazione basato su HTTP.

Formato e dettagli token SPNEGO

Il formato del token SPNEGO è definito in RFC 4178. Il token è una struttura di dati serializzata che contiene i seguenti campi:

  • mechTypes: sequenza di identificatori di oggetti (OID) che elenca i meccanismi di autenticazione supportati.
  • mechToken: un token di meccanismo ottimistico. Questo è un token utilizzato per negoziare il meccanismo di autenticazione effettivo che verrà utilizzato.
  • krb5Creds: un blob Kerberos. Si tratta di un blob binario contenente le informazioni di autenticazione Kerberos.

Il token SPNEGO è codificato in ASN.1. Di seguito è riportato un esempio di token SPNEGO.

NegTokenInit ::= SEQUENCE
{
mechTypes SEQUENCE OF Oid,
mechToken OCTET STRING,
krb5Creds [0] KerberosCreds OPTIONAL
}
GSSAPI Interfaccia programma applicazione servizi di sicurezza generici
API servizio scambio token IAM Servizio OAuth del dominio di Identity IAM: /oauth2/v1/token. L'API accetta sia intestazioni/payload di autenticazione basati su OAuth standard che firme OCI. Per informazioni su come utilizzare un client OAuth con un dominio di Identity per accedere alle API REST, vedere Uso di OAuth 2 per accedere all'API REST.
Configurazione sicura propagazione identità Utilizzare le configurazioni Trust di propagazione delle identità per stabilire l'affidabilità tra OCI Identity e un provider di identità esterno e convalidare il token del provider di identità esterno e il mapping dell'identità utente del provider di identità esterno con l'identità utente in IAM. Identity Propagation Trust facilita anche la propagazione delle identità da un provider di identità esterno a OCI. La progettazione dell'endpoint /IdentityPropagationTrust è generica e funziona con qualsiasi provider cloud. Per creare una configurazione attendibile di propagazione delle identità, vedere Passo 6: creazione di una configurazione attendibile di propagazione delle identità.
Utente servizio Utente senza privilegi di login interattivi. Questi utenti del servizio possono essere concessi a gruppi e ruoli di servizio. Le applicazioni possono utilizzare questi utenti del servizio o l'utente collegato può impersonarli per ottenere un UPST temporaneo. L'utilizzo di un utente del servizio è facoltativo. Per ulteriori informazioni sull'uso degli utenti del servizio, vedere Passo 5: uso di un utente del servizio (facoltativo).
Token sessione principal utente (UPST) Token generato da IAM. Conosciuto anche come token di sicurezza. Rappresenta l'utente del servizio autenticato.

Passi di scambio token Kerberos

Per scambiare un token Kerberos con un UPST, effettuare le operazioni riportate di seguito.

  1. Passo 1: Creare un vault e aggiungere il contenuto del file keytab
  2. Passo 2: creare il criterio IAM richiesto
  3. Passo 3: creare un'applicazione del dominio di Identity
  4. Passo 4: generare un token SPNEGO per un principal utente specifico
  5. Passo 5: Uso di un utente del servizio (facoltativo)
  6. Passo 6: creare una configurazione sicura per la propagazione delle identità
  7. Passo 7: ottieni OCI UPST

Passo 1: Creare un vault e aggiungere il contenuto del file keytab

Creare un vault e aggiungere il contenuto del file keytab come stringa con codifica base64. Nota: IAM non memorizza il file keytab nel file system.

Utilizzare i passi riportati di seguito come guida.

  1. Creare un vault Vedere Creazione di un v Vault.
  2. Leggere il contenuto della tabella chiavi in formato Base64.
  3. Andare al vault e memorizzarlo così com'è, assicurarsi di controllare Base64 come Modello tipo di segreto durante la creazione del segreto. Vedere Creazione di un segreto in un vault.

Passo 2: creare il criterio IAM richiesto

Creare un criterio IAM nella tenancy per consentire a una risorsa del dominio di Identity di accedere al vault. Ciò consente a IAM di recuperare la configurazione keytab dal vault. Utilizzare l'esempio seguente come guida.

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

Passo 3: creare un'applicazione del dominio di Identity

Creare un'applicazione riservata del dominio di Identity. Dopo aver creato l'applicazione, salvare i valori di ID client e segreto client in una posizione sicura. Vedere Aggiunta di un'applicazione riservata.

Passo 4: generare un token SPNEGO per un principal utente specifico

  1. Utilizzare il codice Java per connettersi al server KDC e generare il token SPNEGO.
  2. Copiare il token SPNEGO per formare la richiesta del token.

Utilizzare il seguente esempio di codice Java come guida:

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;

    }
}

Passo 5: Uso di un utente del servizio (facoltativo)

Un utente del servizio è un utente dei domini di Identity con l'attributo serviceUser impostato su true.

Nota

L'uso di un utente del servizio è facoltativo. Se la rappresentazione utente viene utilizzata come parte della configurazione Trust, sono necessari gli utenti del servizio. In caso contrario, viene utilizzato qualsiasi altro utente del dominio di Identity. Solo gli amministratori del dominio di Identity possono creare, sostituire, aggiornare o eliminare un utente del servizio. Altri amministratori possono leggere gli utenti del servizio e i relativi attributi.

Per utilizzare un utente del servizio, crearne uno senza privilegi di login interattivi. Questi utenti del servizio possono essere concessi a gruppi e ruoli di servizio. Le applicazioni possono utilizzare questi utenti del servizio o l'utente che ha eseguito il login può rappresentarli per ottenere un token UPST temporaneo.

Gli utenti del servizio hanno le seguenti caratteristiche:

  • Deve avere un indirizzo userName. Nome e cognome non sono obbligatori.
  • Può avere un indirizzo di posta elettronica (facoltativo).
  • Può essere un membro di gruppi e ruoli applicazione.
  • Non può avere API key.
  • Impossibile utilizzare gli endpoint self-service.
  • Non è possibile applicare le password e i criteri password.

Esempio di richiesta: creazione di un utente servizio

Di seguito è riportato un esempio di richiesta con gli attributi minimi necessari per creare un utente del servizio.

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

Esempio di risposta: creazione di un utente servizio

Di seguito è riportato un esempio di risposta durante la creazione di un utente del servizio.

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

Passo 6: creare una configurazione sicura per la propagazione delle identità

La configurazione Trust di propagazione delle identità viene utilizzata per stabilire l'affidabilità tra OCI Identity e i provider cloud esterni, la convalida del token del provider cloud e il mapping dell'identità utente del provider cloud con l'identità utente dei domini di identità service.

Descrizione dettagliata di una configurazione sicura di propagazione delle identità
Attribute Obbligatorio? Descrizioni ed esempi
nome

Il nome del trust.

tipo

Tipo di token:

  • spnego
  • jwt
  • saml
  • aws-credenziale
emittente

Usa l'emittente per trovare l'identificazione del trust. Ad esempio, se il token SPNEGO viene generato utilizzando il principal del servizio, IAMSp, IAMSp è il valore dell'emittente.

Esempio: IAMTokenExchangeServicePrincipal

attivo

Se abilitato, true.

Se disabilitata, false.

oauthClients

Lista di client OAuth autorizzati a ottenere token per un partner sicuro specifico.

Esempio:
"oauthClients": [
 "oauthclient-id"
 ],
allowImpersonation (utilizzare serviceUser) N

Valore booleano. Specifica se l'UPST risultante deve contenere l'utente autenticato come oggetto o se deve rappresentare un utente del servizio in IAM.

impersonatingServiceUser

Sì, se allowImpersonation è impostato su true.

Specifica quale principal risultante rappresenterà in base al nome della richiesta di token e alle condizioni del valore. È possibile effettuare le operazioni riportate di seguito.

  • Consentire un principal rappresentante specifico per tutti gli utenti autenticati del provider di identità (IdP).
  • Impostare le regole per definire le condizioni di rappresentazione:
    • In base al nome richiesta token
    • Condizione: contiene (co) o è uguale a (eq)
    • Valore:
      • Può essere una stringa.
      • Array di valori e valori complessi/compositi non supportato.
      • Con la condizione uguale a: è consentito il carattere jolly (*).
      • Con la condizione contiene: il carattere jolly (*) non è supportato.
    • Rappresentazione principale.

Esempio:

  • Regola: "username" eq kafka*
  • Utente servizio mappato: kafka
  • Risultato: tutti gli utenti autenticati che iniziano con il prefisso kafka vengono rappresentati con l'utente del servizio IAM kafka. L'UPST risultante contiene kafka come principal utente autenticato.

Se è consentita la rappresentazione, il token di sicurezza OCI (UPST) risultante avrà anche la richiesta correlata all'utente autenticato originale (source_authn_prin) per indicare per conto di chi è stata eseguita la rappresentazione.

  • Se il nome della richiesta oggetto è configurato, verrà utilizzato per estrarre il valore della richiesta.
  • Se il nome della richiesta di rimborso oggetto non è configurato, per impostazione predefinita viene utilizzato sub nel token in entrata. Se la richiesta sub non è presente, viene ignorata.
La valutazione si interrompe con la prima regola corrispondente e il principal risultante corrispondente viene restituito utilizzando l'attributo nome visualizzato. Se non viene trovata una corrispondenza con alcuna regola, la richiesta del token non riesce con errori.
tabella chiavi

Sì, se il tipo di token è SPNEGO.

Recupera la configurazione keytab dal vault.

Importante:
  • Il servizio di scambio di token recupera le informazioni sul segreto in base all'OCID del segreto e alla versione del segreto.

  • Se la tabella chiavi viene ruotata nel server KDC, è necessario aggiornare le informazioni segrete nella configurazione Trust di propagazione delle identità.

  • Se il keytab viene ruotato nel vault, è necessario aggiornare le informazioni del segreto nella configurazione Trust di propagazione delle identità.

Esempio di richiesta: creazione di una configurazione sicura di propagazione delle identità

Di seguito è riportato un esempio di richiesta di creazione di una configurazione Trust di propagazione delle identità.
## 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"
 ]
}

Esempio di risposta: creazione di una configurazione sicura di propagazione delle identità

Di seguito è riportato un esempio di risposta durante la creazione di una configurazione Trust di propagazione delle identità.
  "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>"
    }
  }

Passo 7: ottieni OCI UPST

Descrizione dettagliata del payload della richiesta token UPST
Parametro richiesta Valore valido

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

Workflow della chiave pubblica:

  1. Il carico di lavoro genera un paio di chiavi.
  2. La chiave pubblica viene inviata come parte della richiesta di scambio di token, che viene aggiunta come richiesta, jwk, nell'UPST risultante.
  3. La chiave privata viene utilizzata per generare le firme OCI per il richiamo dell'API dei servizi nativi OCI insieme all'UPST.
  4. L'autenticazione dei servizi OCI convalida l'UPST, estrae la richiesta di rimborso jwk dall'UPST e la utilizza per convalidare la firma OCI.

subject_token_type

'subject_token_type=spnego'

  • spnego
  • jwt
  • saml
  • aws-credenziale

subject_token

'subject_token=<subject-token>'

Se il tipo di token è:

  • spnego: token cifrato opaco.
  • jwt o saml: il valore di asserzione jwt o saml così com'è.
  • aws-credential: il valore codificato base64 delle credenziali AWS che vengono visualizzate in formato XML.

issuer

Obbligatorio se il tipo di token è spnego.

Esempio:

IAMTokenExchangeServicePrincipal

Esempio di richiesta token UPST: basato sulla firma OCI

Di seguito è riportato un esempio di richiesta cURL basata sulla firma 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>"
}

Esempio di richiesta token UPST: basato sull'applicazione del dominio di Identity

Di seguito è riportato un esempio di richiesta cURL basata su applicazione del dominio di Identity 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>"
}