Token Exchange Grant Type : Échange d'un jeton Kerberos pour une UPST
Utilisez l'échange de jetons Kerberos où Kerberos est le fournisseur d'authentification et vous devez échanger des jetons Kerberos contre des jetons ou des principaux IAM pour accéder aux services OCI. Vous échangez des jetons Kerberos contre des jetons de session d'utilisateur principal OCI (UPST) dans IAM.
Terme | Description |
---|---|
Kerberos |
Un système d'authentification et d'authentification unique multiplateforme. Le protocole Kerberos fournit une authentification mutuelle entre deux entités reposant sur une clé secrète partagée (clés symétriques). L'authentification Kerberos nécessite un client, un serveur et une partie de confiance pour assurer la médiation entre eux, appelé Key Distribution Center (KDC). Les conditions suivantes sont également requises :
Le profil de jeton Kerberos de WS-Security permet aux partenaires commerciaux d'utiliser des jetons Kerberos dans des architectures orientées service (SOA). |
Centre de distribution de clés Kerberos (CDC) | Serveur d'authentification de tierce partie. |
Active Directory (AD) | Référentiel pour le serveur KDC. |
Keytab |
Fichier qui stocke la clé de chiffrement réelle qui peut être utilisée au lieu d'une identification par mot de passe pour un principal spécifique. Les fichiers Keytab sont utiles pour les cas d'utilisation non interactifs. Conseil : L'outil d'administration KDC peut être utilisé pour créer un fichier keytab. Lors de la création du fichier keytab, le type de chiffrement peut être spécifié. Utilisez le type de chiffrement suivant : |
Mécanisme de négociation GSSAPI simple et protégé (SPNEGO) |
Le mécanisme de négociation GSSAPI simple et protégé (SPNEGO) est un " pseudo mécanisme " GSSAPI utilisé par le logiciel client/serveur pour négocier le choix de la technologie de sécurité. Les tickets Kerberos sont encapsulés dans le jeton SPNEGO afin que le jeton fonctionne avec la couche d'application HTTP. Format et détails du jeton SPNEGO Le format de jeton SPNEGO est défini dans la RFC 4178. Le jeton est une structure de données sérialisée qui contient les champs suivants :
Le jeton SPNEGO est encodé dans ASN.1. Voici un exemple de jeton SPNEGO :
|
GSSAPI | Interface de programme d'application générique de services de sécurité |
API du service IAM Token Exchange | Service de domaine d'identité IAM OAuth : /oauth2/v1/token . L'API accepte les en-têtes/données utiles d'authentification standard basés sur OAuth et les signatures OCI. Pour savoir comment utiliser un client OAuth avec un domaine d'identité pour accéder aux API REST, voir Utilisation de OAuth 2 pour accéder à l'API REST. |
Configuration de l'approbation de propagation des identités | Utilisez les configurations d'approbation de propagation d'identité pour établir l'approbation entre l'identité OCI et un fournisseur d'identités externe et valider le jeton du fournisseur d'identités externe et le mappage de l'identité d'utilisateur du fournisseur d'identités externe avec l'identité d'utilisateur dans IAM. L'approbation de propagation des identités facilite également la propagation des identités d'un fournisseur d'identités externe vers OCI. La conception de point d'extrémité /IdentityPropagationTrust est générique et fonctionne avec n'importe quel fournisseur de nuage. Pour créer une configuration d'approbation de propagation d'identité, voir Étape 6 : Créer une configuration d'approbation de propagation d'identité. |
Utilisateur du service | Utilisateur sans privilèges de connexion interactifs. Ces utilisateurs de service peuvent être accordés à des groupes et à des rôles de service. Les applications peuvent utiliser ces utilisateurs de service ou l'utilisateur connecté peut se faire passer pour eux pour obtenir une UPST temporaire. L'utilisation d'un utilisateur de service est facultative. Pour plus d'informations sur l'utilisation des utilisateurs du service, voir Étape 5 : Utiliser un utilisateur du service (facultatif). |
Jeton de session du principal d'utilisateur (UPST) | Un jeton généré par IAM. Également appelé jeton de sécurité. Il représente l'utilisateur du service authentifié. |
Étapes d'échange de jetons Kerberos
Utilisez les étapes suivantes pour échanger un jeton Kerberos contre un UPST :
- Étape 1 : Créer une chambre forte et ajouter le contenu du fichier Keytab
- Étape 2 : Créer la politique IAM requise
- Étape 3 : Créer une application de domaine d'identité
- Étape 4 : Générer un jeton SPNEGO pour un principal d'utilisateur spécifique
- Étape 5 : Utiliser un utilisateur du service (facultatif)
- Étape 6 : Créer une configuration d'approbation de propagation d'identité
- Étape 7 : Obtenir l'OCI UPST
Étape 1 : Créer une chambre forte et ajouter le contenu du fichier Keytab
Créez une chambre forte et ajoutez le contenu du fichier keytab en tant que chaîne encodée par base64. Note : Le service IAM ne stocke pas le fichier keytab dans son système de fichiers.
Reportez-vous aux étapes suivantes :
- Créer une chambre forte. Voir Création d'une chambre forte.
- Lisez le contenu du fichier keytab au format Base64.
- Allez à la chambre forte et stockez-la telle quelle, en veillant à vérifier Base64 en tant que modèle de type de clé secrète lors de la création de la clé secrète. Voir Création d'une clé secrète dans une chambre forte.
Étape 2 : Créer la politique IAM requise
Créez une politique IAM dans la location pour permettre à une ressource de domaine d'identité d'accéder à la chambre forte. Cela permet à IAM d'extraire la configuration du fichier keytab de la chambre forte. Reportez-vous à l'exemple suivant :
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>}
Étape 3 : Créer une application de domaine d'identité
Créer une application confidentielle de domaine d'identité. Après avoir créé l'application, enregistrez l'ID client et la clé secrète client dans un emplacement sécurisé. Voir Ajouter une application confidentielle.
Étape 4 : Générer un jeton SPNEGO pour un principal d'utilisateur spécifique
- Utilisez du code Java pour vous connecter au serveur KDC et générer le jeton SPNEGO.
- Copiez ce jeton SPNEGO pour former la demande de jeton.
Reportez-vous à l'exemple de code Java suivant :
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;
}
}
Étape 5 : Utiliser un utilisateur du service (facultatif)
Un utilisateur de service est un utilisateur de domaines d'identité dont l'attribut serviceUser
est réglé à true
.
L'utilisation d'un utilisateur du service est facultative. Si l'emprunt d'identité d'utilisateur est utilisé dans le cadre de la configuration de l'approbation, les utilisateurs du service sont nécessaires. Sinon, tout autre utilisateur du domaine d'identité est utilisé. Seuls les administrateurs de domaine d'identité peuvent créer, remplacer, mettre à jour ou supprimer un utilisateur du service. D'autres administrateurs peuvent lire les utilisateurs du service et leurs attributs.
Pour utiliser un utilisateur de service, créez-en un sans privilèges de connexion interactifs. Ces utilisateurs de service peuvent être accordés à des groupes et à des rôles de service. Vos applications peuvent utiliser ces utilisateurs de service ou l'utilisateur connecté peut se faire passer pour eux afin d'obtenir un jeton UPST temporaire.
Les utilisateurs du service ont les caractéristiques suivantes :
- Doit avoir une valeur userName. Le prénom et le nom ne sont pas requis.
- Peut avoir une adresse de courriel (facultatif).
- Peut être membre de groupes et de rôles d'application.
- Impossible d'avoir des clés d'API.
- Impossible d'utiliser des points d'extrémité en libre-service.
- Impossible d'avoir des mots de passe et les politiques de mot de passe ne s'appliquent pas.
Exemple de demande : Créer un utilisateur du service
Voici un exemple de demande avec les attributs minimum requis pour créer un utilisateur de service.
## 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"
}
Exemple de réponse : Créer un utilisateur de service
Voici un exemple de réponse lors de la création d'un utilisateur de service.
{
"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"
]
}
Étape 6 : Créer une configuration d'approbation de propagation d'identité
La configuration de l'approbation de propagation d'identité est utilisée pour établir l'approbation entre l'identité OCI et les fournisseurs de services en nuage externes, la validation du jeton de fournisseur en nuage et le mappage de l'identité d'utilisateur du fournisseur en nuage avec l'identité d'utilisateur des domaines d'identité service
.
Attribut | Obligatoire? | Descriptions et exemples |
---|---|---|
nom | Oui |
Nom de la fiducie. |
type | Oui |
Type de jeton :
|
émetteur | Oui |
Utilisez l'émetteur pour trouver l'identification de la fiducie. Par exemple, si le jeton SPNEGO est généré à l'aide du principal de service, Exemple : |
active | Oui |
Si cette option est activée, Si cette option est désactivée, |
oauthClients | Oui |
Liste des clients OAuth autorisés à obtenir des jetons pour un partenaire de confiance spécifique. Exemple :
|
allowImpersonation (utilisez serviceUser) | Non |
Valeur booléenne. Indique si l'UPST résultant doit contenir l'utilisateur authentifié comme sujet ou s'il doit emprunter l'identité d'un utilisateur de service dans IAM. |
impersonatingServiceUser |
Oui, si |
Indique quel principal résultant empruntera l'identité en fonction du nom de la revendication de jeton et des conditions de valeur. Vous pouvez :
Exemple :
Si l'emprunt d'identité est autorisé, le jeton de sécurité OCI (UPST) résultant aura la revendication initiale liée à l'utilisateur authentifié (
|
keytab |
Oui, si le type de jeton est |
Extrait la configuration du fichier keytab de la chambre forte. Important :
|
Exemple de demande : Créer une configuration d'approbation de propagation d'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"
]
}
Exemple de réponse : Créer une configuration d'approbation de propagation d'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>"
}
}
Étape 7 : Obtenir l'OCI UPST
Paramètre de demande | Valeur valide |
---|---|
|
|
|
|
|
Le flux de travail de la clé publique :
|
|
|
|
Si le type de jeton est :
|
|
Obligatoire si le type de jeton est Exemple :
|
Exemple de demande de jeton UPST : OCI basée sur une signature
Voici un exemple de demande cURL basée sur une signature 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>"
}
Exemple de demande de jeton UPST : Basé sur une application de domaine d'identité
Voici un exemple de demande cURL basée sur une application de domaine d'identité 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>"
}