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 IAM ou des principaux pour accéder aux services OCI. Vous échangez des jetons Kerberos contre des jetons de session de principal d'utilisateur OCI (UPST) dans IAM.
Terme | Description |
---|---|
Kerberos |
Authentification multiplateforme et système d'accès avec connexion unique. Le protocole Kerberos assure l'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 servir de médiateur entre eux, appelé 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 (KDC) Kerberos | Serveur d'authentification tiers. |
Active Directory (AD) | Référentiel du serveur KDC. |
Keytab |
Fichier stockant la clé de cryptage 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. Conseil : l'outil d'administration du 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 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 en tant que partie du jeton SPNEGO de sorte 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 document 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 IAM Token Exchange Service | Service OAuth du domaine d'identité IAM : /oauth2/v1/token . L'API accepte à la fois les en-têtes d'authentification/la charge utile basés sur OAuth standard et les signatures OCI. Pour découvrir 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 sécurisée 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 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 de sécurisation de propagation d'identité, reportez-vous à l'Step 6 : Create an Identity Propagation Trust Configuration. |
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 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 à l'Step 5 : Use a Service User (Optional). |
Jeton de session d'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 jeton Kerberos
Procédez comme suit pour échanger un jeton Kerberos contre un UPST :
- Etape 1 : Créer un coffre et ajouter le contenu du fichier keytab
- Etape 2 : création de la stratégie 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 d'OCI UPST
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éez 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, en vérifiant que Base64 est le 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 un coffre.
Etape 2 : création de la stratégie 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 keytab de Vault. Aidez-vous de l'exemple suivant :
allow resource iam-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é avec l'attribut serviceUser
défini sur true
.
L'utilisation d'un utilisateur de service est facultative. Si l'usurpation d'identité est utilisée dans le cadre de la configuration Trust, les utilisateurs du 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 se faire passer pour obtenir un jeton UPST temporaire.
Les utilisateurs du service présentent les caractéristiques suivantes :
- Doit avoir un userName. Le prénom et le nom ne sont pas obligatoires.
- Peut avoir une adresse électronique (facultatif).
- Il 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 stratégies de mots de passe et de mots de passe ne peuvent pas s'appliquer.
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 d'identité permet d'établir l'approbation entre l'identité OCI 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 la fiducie. |
type | Oui |
Type de jeton :
|
émetteur | Oui |
Utilisez l'émetteur pour rechercher 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, S'il est désactivé, |
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 obtenu doit contenir l'utilisateur authentifié en tant que sujet ou s'il doit usurper l'identité d'un utilisateur de service dans IAM. |
impersonatingServiceUser |
Oui, si |
Spécifie le principal résultant qui va emprunter l'identité en fonction du nom de la demande 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 demande d'origine liée à l'utilisateur authentifié (
|
keytab |
Oui, si le type de jeton est |
Récupère la configuration du fichier keytab de Vault. 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\"",
"userId": "<user_id>"
},
{
"rule": "groups co \"tenancy-admin\"",
"userId": "<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 |
---|---|
|
|
|
|
|
Workflow 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é sur une signature
L'exemple suivant présente une 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 : domaine d'identité basé sur une application
L'exemple suivant présente une 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>"
}