Type d'octroi 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 vous devez échanger des jetons Kerberos contre des jetons ou des principaux IAM pour accéder aux services OCI. Vous échangez des jetons Kerberos pour les jetons de session de principal utilisateur OCI (UPST) dans IAM.
| Terme | Description |
|---|---|
| Kerberos |
Authentification interplateforme et système d'accès avec connexion unique. 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 qu'un client, un serveur et une partie de confiance interviennent entre eux, appelés KDC (Key Distribution Center). Les éléments suivants sont également requis :
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 (KDC) | Serveur d'authentification tiers. |
| Active Directory (AD) | Un référentiel pour le serveur KDC. |
| Fichier keytab |
Fichier qui stocke la clé de chiffrement réelle qui peut être utilisée à la place d'une question de vérification de mot de passe pour un principal spécifique. Les fichiers keytab sont utiles pour les cas d'utilisation non interactifs. A savoir : 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 cryptage peut être spécifié. Utilisez le type de cryptage suivant : |
| Mécanisme de négociation simple et protégé du GSSAPI (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 cadre du jeton SPNEGO afin que le jeton fonctionne avec la couche d'application basée sur HTTP. Format et détails du jeton SPNEGO Le format de jeton SPNEGO est défini dans la norme RFC 4178. Le jeton est une structure de données sérialisée qui contient les champs suivants :
Le jeton SPNEGO est encodé en ASN.1. Voici un exemple de jeton SPNEGO :
|
| GSSAPI | Interface de programme de l'application Generic Security Services |
| API du service IAM Token Exchange | Service OAuth de domaine d'identité IAM : /oauth2/v1/token. L'API accepte à la fois les en-têtes/la charge utile d'authentification standard basés sur OAuth et les signatures OCI. Pour savoir comment utiliser un client OAuth avec un domaine d'identité afin d'accéder aux API REST, reportez-vous à Utilisation de OAuth 2 pour accéder à l'API REST. |
| Configuration de sécurisation de propagation d'identité | Utilisez les configurations de sécurisation de propagation d'identité pour établir la sécurisation entre OCI Identity et un fournisseur d'identités externe, et valider le jeton de fournisseur d'identités externe et la mise en correspondance de l'identité utilisateur du fournisseur d'identités externe avec l'identité utilisateur dans IAM. La sécurisation de la propagation des identités facilite également la propagation des identités d'un fournisseur d'identités externe vers OCI. La conception d'adresse /IdentityPropagationTrust est générique et fonctionne avec n'importe quel fournisseur cloud. Pour créer une configuration sécurisée de propagation d'identité, reportez-vous à Etape 6 : création d'une configuration sécurisée de propagation d'identité. |
| Utilisateur de 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 un UPST temporaire. L'utilisation d'un utilisateur de service est facultative. Pour plus d'informations sur l'utilisation des utilisateurs de service, reportez-vous à Etape 5 : utilisation d'un utilisateur de service (facultatif). |
| Jeton de session utilisateur principal (UPST) | Jeton généré par IAM. Egalement appelé jeton de sécurité. Il représente l'utilisateur de service authentifié. |
Etapes d'échange de jetons Kerberos
Pour échanger un jeton Kerberos contre un UPST, procédez comme suit :
- Etape 1 : création d'un coffre et ajout du contenu du fichier keytab
- Etape 2 : création de la stratégie de service IAM requise
- Etape 3 : création d'une application de domaine d'identité
- Etape 4 : génération d'un jeton SPNEGO pour un principal utilisateur spécifique
- Etape 5 : Utilisation d'un utilisateur de service (facultatif)
- Etape 6 : création d'une configuration sécurisée de propagation d'identité
- Etape 7 : Obtention de l'UPST OCI
Etape 1 : création d'un coffre et ajout du contenu du fichier keytab
Créez un coffre et ajoutez le contenu du fichier keytab en tant que chaîne codée en base64. Remarque : IAM ne stocke pas le fichier keytab dans son système de fichiers.
Pour vous guider, procédez comme suit :
- Créer un coffre Reportez-vous à Création d'un coffre.
- Lisez le contenu du fichier keytab au format Base64.
- Accédez au coffre et stockez-le tel quel. Veillez à vérifier Base64 en tant que modèle de type de clé secrète lors de la création de la clé secrète. Reportez-vous à Création d'une clé secrète dans une chambre forte.
Etape 2 : création de la stratégie de service IAM requise
Créez une stratégie IAM dans la location pour autoriser une ressource de domaine d'identité à accéder à Vault. Cela permet à IAM d'extraire la configuration de fichier keytab à partir du coffre. Utilisez l'exemple suivant comme guide :
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>}
Etape 3 : création d'une application de domaine d'identité
Créez une application confidentielle de domaine d'identité. Une fois l'application créée, enregistrez l'ID client et la clé secrète client dans un emplacement sécurisé. Reportez-vous à Ajout d'une application confidentielle.
Etape 4 : génération d'un jeton SPNEGO pour un principal utilisateur spécifique
- Utilisez le 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;
}
}
Etape 5 : Utilisation d'un utilisateur de service (facultatif)
Un utilisateur de service est un utilisateur de domaines d'identité dont l'attribut serviceUser est défini sur true.
L'utilisation d'un utilisateur de service est facultative. Si l'emprunt d'identité des utilisateurs est utilisé dans le cadre de la configuration sécurisée, les utilisateurs de service sont nécessaires. Sinon, tout autre utilisateur de 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 de 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 les usurper d'identité pour obtenir un jeton UPST temporaire.
Les utilisateurs du service présentent les caractéristiques suivantes :
- Doit avoir un élément userName. Le prénom et le nom ne sont pas obligatoires.
- Peut avoir une adresse e-mail (facultatif).
- Peut être membre de groupes et de rôles d'application.
- Impossible d'avoir des clés d'API.
- Impossible d'utiliser des adresses en libre-service.
- Les mots de passe et les stratégies de mot de passe ne s'appliquent pas.
Exemple de demande : création d'un utilisateur de service
L'exemple suivant illustre une 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éation d'un utilisateur de service
L'exemple suivant illustre une 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"
]
}
Etape 6 : création d'une configuration sécurisée de propagation d'identité
La configuration de sécurisation de propagation des identités est utilisée pour établir la sécurisation entre OCI Identity et les fournisseurs cloud externes, la validation du jeton de fournisseur cloud et la mise en correspondance de l'identité utilisateur du fournisseur cloud avec l'identité utilisateur service des domaines d'identité.
| Attribut | Obligatoire ? | Descriptions et exemples |
|---|---|---|
| nom | Oui |
Nom de l'approbation. |
| 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 : |
| actif | Oui |
Si cette option est activée, Si elle est désactivée, |
| oauthClients | Oui |
Liste des clients OAuth autorisés à obtenir des jetons pour un partenaire de confiance spécifique. Exemple :
|
| allowImpersonation (utiliser serviceUser) | Non |
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 qui va imiter en fonction du nom de la demande de jeton et des conditions de valeur. Vous pouvez effectuer les opérations suivantes :
Exemple :
Si l'emprunt d'identité est autorisé, le jeton de sécurité OCI (UPST) obtenu aura la réclamation liée à l'utilisateur authentifié d'origine (
|
| keytab |
Oui, si le type de jeton est |
Extrait la configuration keytab du coffre. Important :
|
Exemple de demande : création d'une configuration sécurisée 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éation d'une configuration sécurisée 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>"
}
}Etape 7 : Obtention de l'UPST OCI
| Paramètre de demande | Valeur valide |
|---|---|
|
|
|
|
|
|
|
|
Le workflow de clé publique :
|
|
|
|
|
|
Si le type de jeton est :
|
|
|
Obligatoire si le type de jeton est Exemple :
|
Exemple de demande de jeton UPST : OCI Signature-based
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>"
}