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 IAM o i principal per accedere ai servizi OCI. Puoi scambiare i token Kerberos per i token di sessione del principal utente OCI (UPST) in IAM.

Termini token Kerberos
Periodo descrizione;
Kerberos

Un sistema di autenticazione multipiattaforma e 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 fungano da mediatore tra di loro, denominato KDC (Key Distribution Center).

È inoltre necessario:

  • Un principal: un'identità per un utente (a un utente viene assegnato un principal) o un'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 di sicurezza Web Services.

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

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 della 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 di tabella chiavi. Durante la creazione della tabella di chiavi, è possibile specificare il tipo di cifratura. Usare il seguente tipo di cifratura: aes256-cts-hmac-sha1-96.

Meccanismo di negoziazione GSSAPI semplice e protetta (SPNEGO)

Il meccanismo di negoziazione GSSAPI semplice e protetta (SPNEGO) è uno "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 layer 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 campi riportati di seguito.

  • mechTypes: sequenza di OID (Object Identifiers) 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 che contiene 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 IAM Token Exchange Service Servizio OAuth del dominio di Identity IAM: /oauth2/v1/token. L'API accetta sia intestazioni/carico di pagamento 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 interfacce API REST, vedere Utilizzo di OAuth 2 per accedere all'interfaccia API REST.
Configurazione sicura di Identity Propagation Utilizzare le configurazioni Trust di propagazione delle identità per stabilire la fiducia 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 degli endpoint /IdentityPropagationTrust è generica e funziona con qualsiasi provider cloud. Per creare una configurazione sicura di Identity Propagation, vedere Passo 6: Creare una configurazione sicura di Identity Propagation.
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ò rappresentarli per ottenere un UPST temporaneo. L'utilizzo di un utente del servizio è facoltativo. Per ulteriori informazioni sull'uso degli utenti del servizio, vedere il Passo 5: utilizzo di un utente del servizio (facoltativo).
Token sessione principal utente (UPST) Token generato da IAM. Noto anche come token di sicurezza. Rappresenta l'utente del servizio autenticato.

Passi di scambio token Kerberos

Per scambiare un token Kerberos con un UPST, attenersi alla procedura riportata 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: utilizzare un utente del servizio (facoltativo)
  6. Passo 6: creare una configurazione sicura per la propagazione delle identità
  7. Passo 7: ottieni l'UPST OCI

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 della tabella chiavi nel relativo file system.

Eseguire le operazioni descritte di seguito.

  1. Creare un vault. Vedere Creazione di un vault.
  2. Leggere il contenuto della tabella chiavi in formato Base64.
  3. Andare al vault e memorizzarlo così com'è, assicurarsi di selezionare Base64 come Modello di tipo 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 a Vault. Ciò consente a IAM di recuperare la configurazione della tabella di chiavi dal vault. Utilizzare l'esempio riportato di seguito come riferimento.

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 l'ID client e il 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 formarne la richiesta.

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: utilizzare un utente del servizio (facoltativo)

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

Nota

L'utilizzo di un utente del servizio è facoltativo. Se la rappresentazione utente verrà 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 di 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 collegato può rappresentarli per ottenere un token UPST temporaneo.

Gli utenti del servizio hanno le seguenti caratteristiche:

  • Deve avere un userName. Non sono richiesti nome e cognome.
  • Può avere un indirizzo di posta elettronica (facoltativo).
  • Può essere membro di gruppi e ruoli dell'applicazione.
  • Impossibile avere chiavi API.
  • Impossibile utilizzare gli endpoint self-service.
  • Non è possibile avere password e criteri password non validi.

Esempio di richiesta: creazione di un utente di servizio

Di seguito viene illustrato un esempio di richiesta con il numero minimo di attributi 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: Creare un utente del 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 la sicurezza 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 Identity service.

Descrizione dettagliata di una configurazione sicura di propagazione delle identità
Attributo obbligatorio? Descrizioni ed esempi
nome

Il nome del trust.

Tipo

Tipo di token:

  • spnegozio
  • jwt
  • saml
  • credenziale aws
emittente

Utilizzare Emittente per individuare l'identificazione del trust. Ad esempio, se il token SPNEGO viene generato utilizzando il nome principale del servizio, IAMSp, IAMSp è il valore dell'emittente.

Esempio: IAMTokenExchangeServicePrincipal

attive

Se abilitata, true.

Se disabilitato, false.

oauthClients

Un elenco di OAuth clienti a cui è consentito ottenere token per un partner di fiducia specifico.

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

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 il principal risultante che verrà sostituito in base al nome della richiesta token e alle condizioni del valore. È possibile effettuare le seguenti operazioni.

  • Consente 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 della 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: carattere jolly (*) non supportato.
    • Rappresentante 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à la richiesta originale autenticata relativa all'utente (source_authn_prin) e indicherà per conto del quale viene eseguita la rappresentazione.

  • Se il nome della richiesta oggetto è configurato, verrà utilizzato per estrarre il valore della richiesta.
  • Se il nome della richiesta oggetto non è configurato, nel token in entrata viene utilizzato per impostazione predefinita sub. 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 alcuna corrispondenza con le regole, la richiesta del token non riesce con errori.
keytab

Sì, se il tipo di token è SPNEGO.

Recupera la configurazione della tabella di chiavi dal vault.

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

  • Se la tabella chiavi viene ruotata nel server KDC, è necessario aggiornare le informazioni segrete nella configurazione Trust di Identity Propagation.

  • Se la tabella chiavi viene ruotata nel vault, è necessario aggiornare le informazioni segrete nella configurazione del 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: creare una configurazione sicura di Identity Propagation

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 l'UPST OCI

Descrizione dettagliata del payload di 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>'

Il flusso di lavoro della chiave pubblica:

  1. Il carico di lavoro genera una coppia 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 jwk dall'UPST, quindi la utilizza per convalidare la firma OCI.

subject_token_type

'subject_token_type=spnego'

  • spnegozio
  • jwt
  • saml
  • credenziale aws

subject_token

'subject_token=<subject-token>'

Se il tipo di token è:

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

issuer

Obbligatorio se il tipo di token è spnego.

Esempio:

IAMTokenExchangeServicePrincipal

Esempio di richiesta token UPST: OCI Signature-based

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 su applicazione dominio di Identity

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