Type d'autorisation d'échange de jetons : Échange d'un jeton Kerberos pour un UPST
Utilisez l'échange de jetons Kerberos, où Kerberos est le fournisseur d'authentification et où 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 du principal d'utilisateur OCI (UPST) dans IAM.
| Terme | Description |
|---|---|
| Kerberos |
Un système d'authentification multiplateforme et d'authentification unique. Le protocole Kerberos fournit une authentification mutuelle entre deux entités s'appuyant sur une clé secrète partagée (clés symétriques). L'authentification Kerberos nécessite qu'un client, un serveur et une partie de confiance interviennent entre eux, appelés Centre de distribution de clés (KDC). Les éléments suivants sont également requis :
Le profil Kerberos Token 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 à la place 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 du jeton SPNEGO est défini dans le 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 du programme générique Security Services Application |
| 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 d'identité | 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é de l'utilisateur du fournisseur d'identités externe avec l'identité de l'utilisateur dans IAM. L'approbation de propagation d'identité facilite également la propagation des identités d'un fournisseur d'identités externe vers OCI. La conception du point d'extrémité /IdentityPropagationTrust est générique et fonctionne avec n'importe quel fournisseur de services en 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 interactive. 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 les emprunter pour obtenir une UPST temporaire. L'utilisation d'un utilisateur de service est facultative. Pour plus d'informations sur l'utilisation des utilisateurs de service, voir Étape 5 : Utiliser un utilisateur de service (facultatif). |
| Jeton de session principal d'utilisateur (UPST) | Jeton généré par le service IAM. Également appelé jeton de sécurité. Il représente l'utilisateur de service authentifié. |
Étapes d'échange de jetons Kerberos
Pour échanger un jeton Kerberos contre un UPST, procédez comme suit :
- É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 de service (facultatif)
- Étape 6 : Créer une configuration d'approbation de propagation d'identité
- Étape 7 : Obtenir 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 en base64. Note : Le service IAM ne stocke pas le fichier keytab dans son système de fichiers.
Pour vous guider, procédez comme suit :
- 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 comme 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 au service de chambre forte. Le service IAM peut ainsi extraire la configuration du fichier keytab du service de chambre forte. Pour vous guider, 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 de 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 de service est facultative. Si l'emprunt d'identité de l'utilisateur est utilisé dans le cadre de la configuration Trust, 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 de 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 interactive. 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 leur emprunter l'identité pour obtenir un jeton UPST temporaire.
Les utilisateurs du service ont les caractéristiques suivantes :
- Vous devez avoir un userName. Le prénom et le nom de famille ne sont pas obligatoires.
- 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 de service
Voici un exemple de demande avec le minimum d'attributs 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é permet d'établir l'approbation entre l'identité OCI et les fournisseurs en nuage externes, la validation du jeton du fournisseur en nuage et le mappage de l'identité de l'utilisateur du fournisseur en nuage avec les domaines d'identité service de l'identité de l'utilisateur.
| Attribut | Obligatoire? | Descriptions et exemples |
|---|---|---|
| nom | Oui |
Nom de la fiducie. |
| type | Oui |
Type de jeton :
|
| émetteur | Oui |
Utilisez Émetteur pour trouver l'identification de 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 approuvé spécifique. Exemple :
|
| allowImpersonation (utiliser serviceUser) | Nombre |
Valeur booléenne. Indique si l'UPST résultant doit contenir l'utilisateur authentifié en tant que sujet ou s'il doit emprunter l'identité d'un utilisateur de service dans IAM. |
| impersonatingServiceUser |
Oui, si |
Indique le principal résultant qui va emprunter 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 réclamation liée à l'utilisateur authentifié d'origine (
|
| keytab |
Oui, si le type de jeton est |
Extrait la configuration du fichier keytab du service de 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 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 : basée sur une signature OCI
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>"
}