Référence REST générique

Un système orchestré REST générique est créé avec un modèle minimal, qui est mis à jour lors de l'exécution à l'aide du service des fonctions pour OCI afin de mettre à jour le système orchestré avec des classes d'objet, des types de consultation et des données de transformation sortantes.

Flux de travail de haut niveau de détection de schéma

La détection de schéma est le processus par lequel un système orchestré REST générique applique des modèles de fonction OCI pour permettre la détection du schéma, des classes d'objet, des attributs et des détails de connexion pour la source faisant autorité ou le système géré configuré.

La détection de schéma se produit lorsqu'un système orchestré est créé dans Oracle Access Governance. Les flux de travail simplifiés pour les scénarios Day0 et DayN sont détaillés dans les tableaux suivants.

Flux de travail Day0

Flux de travail Day0
Étape n° Tâche/opération Description
1 Créer un système orchestré

Créer un système orchestré à l'aide de la console Oracle Access Governance.

Le système orchestré est créé avec les détails de la fonction OCI que vous avez créée pour retourner les détails à partir de la source faisant autorité ou du système géré requis.

En fonction des détails entrés dans le système orchestré, l'opération suivante est créée.
  • Valider
2 Valider l'exécution de l'opération
L'opération Validate est exécutée et, en fonction du modèle de schéma configuré, extrait le schéma, y compris les classes d'objet suivantes :
  • Identité : Extrait uniquement les attributs de base. Les objets de base obligatoires doivent être détaillés ici
  • Non-identité : Extrait tous les attributs. Les attributs minimum doivent être détaillés ici

Le modèle de test de configuration est appelé pour valider la connectivité avec le système géré.

3 Opération post-validation
Une fois l'opération Validate exécutée avec succès, les opérations suivantes sont créées :
  • Chargement de données de consultation
  • Chargement de données complet

Flux de travail DayN

Flux de travail DayN
Étape n° Tâche/opération Description
1 Sélectionnez Extraire les attributs dans la page Attributs d'identité d'Oracle Access Governance. Voir Extraire les derniers attributs personnalisés pour plus de détails. Une opération de détection de schéma est créée dans le système orchestré
2 Exécution de l'opération de détection de schéma L'opération de détection de schéma est exécutée et, sur la base du modèle de schéma configuré, extrait le schéma, y compris les classes d'objet suivantes :
  • Identité : Extrait les attributs de base et personnalisés
  • Non-identité : Extrait tous les attributs
3 Actualiser la page Attributs d'identité La liste des attributs personnalisés commence à afficher les nouveaux attributs personnalisés pour la classe d'objet d'identité.
Si tout ce qui précède se termine avec succès, le système orchestré est disponible pour le programmateur afin de créer les opérations de chargement complet des données suivantes.

Attributs de schéma obligatoires de détection de schéma REST générique

Lors de la détection du schéma, certains attributs obligatoires doivent être retournés dans la sortie du schéma.

Classe d'objet d'identité

Les attributs obligatoires qui doivent être retournés dans la sortie de schéma pour la classe d'objet Identity sont les suivants :

  • uid
  • name
  • courriel
  • firstName
  • middleName
  • lastName
  • displayName
  • employeeType
  • titre
  • empNo
  • statut
  • jobCode
  • État
  • risque
  • emplacement
  • service
  • managerUid
  • managerLogin
  • organizationUid
  • organizationName
  • pays
  • Code postal
  • territoire
[
  {
    "name": "uid",
    "dataType": "TEXT",
    "nature": [
      "REQUIRED"
    ],
    "usage": [
      "READ"
    ]
  },
  {
    "name": "name",
    "dataType": "TEXT",
    "nature": [
      "REQUIRED"
    ],
    "usage": [
      "READ"
    ]
  },
  {
    "name": "email",
    "dataType": "TEXT",
    "nature": [
      "REQUIRED"
    ],
    "usage": [
      "READ"
    ]
  },
  {
    "name": "firstName",
    "dataType": "TEXT",
    "usage": [
      "READ"
    ]
  },
  {
    "name": "middleName",
    "dataType": "TEXT",
    "usage": [
      "READ"
    ]
  },
  {
    "name": "lastName",
    "dataType": "TEXT",
    "usage": [
      "READ"
    ]
  },
  {
    "name": "displayName",
    "dataType": "TEXT",
    "nature": [
      "REQUIRED"
    ],
    "usage": [
      "READ"
    ]
  },
  {
    "name": "employeeType",
    "dataType": "TEXT",
    "usage": [
      "READ"
    ]
  },
  {
    "name": "title",
    "dataType": "TEXT",
    "usage": [
      "READ"
    ]
  },
  {
    "name": "empNo",
    "dataType": "TEXT",
    "usage": [
      "READ"
    ]
  },
  {
    "name": "status",
    "dataType": "FLAG",
    "usage": [
      "READ"
    ]
  },
  {
    "name": "jobCode",
    "dataType": "TEXT",
    "usage": [
      "READ"
    ]
  },
  {
    "name": "state",
    "dataType": "TEXT",
    "usage": [
      "READ"
    ]
  },
  {
    "name": "risk",
    "dataType": "TEXT",
    "usage": [
      "READ"
    ]
  },
  {
    "name": "location",
    "dataType": "TEXT",
    "usage": [
      "READ"
    ]
  },
  {
    "name": "department",
    "dataType": "TEXT",
    "usage": [
      "READ"
    ]
  },
  {
    "name": "managerUid",
    "dataType": "TEXT",
    "usage": [
      "READ"
    ]
  },
  {
    "name": "managerLogin",
    "dataType": "TEXT",
    "usage": [
      "READ"
    ]
  },
  {
    "name": "organizationUid",
    "dataType": "TEXT",
    "usage": [
      "READ"
    ]
  },
  {
    "name": "organizationName",
    "dataType": "TEXT",
    "usage": [
      "READ"
    ]
  },
  {
    "name": "country",
    "dataType": "TEXT",
    "usage": [
      "READ"
    ]
  },
  {
    "name": "postalCode",
    "dataType": "TEXT",
    "usage": [
      "READ"
    ]
  },
  {
    "name": "territory",
    "dataType": "TEXT",
    "usage": [
      "READ"
    ]
  }
]

Classe d'objet de non-identité

Les attributs obligatoires qui doivent être retournés dans la sortie du schéma pour la classe d'objet Non-Identity sont les suivants :

  • uid
  • name
[
  {
    "name": "uid",
    "dataType": "TEXT",
    "nature": [
      "REQUIRED"
    ],
    "usage": [
      "READ"
    ]
  },
  {
    "name": "name",
    "dataType": "TEXT",
    "nature": [
      "REQUIRED"
    ],
    "usage": [
      "READ"
    ]
  }
]

Structure du modèle de schéma

Pour prendre en charge la détection de schéma, vous devez créer votre modèle de schéma à l'aide de l'outline prise en charge.

Structure du schéma

L'outline de schéma que vous devez suivre lors de la création de votre modèle de schéma est la suivante :
{
 "schemaTemplates":[
    {
        "type": "", // Type of entity i.e. either object class type i.e. "ACCOUNT", "ENTITLEMENT", "TARGETACCOUNT" or "LOOKUP"
        "name": "", // Name of entity i.e. name of either object class or lookup
        "displayName": "", // display name of entity
        "data": {
            // Key-value pairs representing lookup data if any, or else it will be missing from here.
        }
        "attributes": [
            {
                "name": "", // Name of attribute
                "dataType": "", // Either of TEXT, DATE, NUMBER, DECIMAL_NUMBER, FLAG
                "nature": [ // Adjectives i.e. One or more of "REQUIRED", "MULTIVALUED", "SENSITIVE". It can be missing from here if nothing applies.
                ],
                "usage": [ // Verbs i.e. One or more of "READ", "PROVISION". It can be missing from here if nothing applies.
                ],
                "relationship": { // Entity relationship details
                    "relatedTo": "", // Entity name in relationship with
                    "relatedBy": "", // Attribute to define the relation
                    "relationshipProperties": [ // Additional relationship properties
                        {
                            "name": "", // Name of additional attribute
                            "dataType": "", // Either of TEXT, DATE, NUMBER, DECIMAL_NUMBER, FLAG
                            "nature": [ // Only READ_ONLY is possible, or else it will be missing from here
                            ]
                        }
                    ]
                },
                "outboundTransformation": { // Outbound transformation script if applicable, or it will be missing from here
                    "script": "" // Script to execute for transformation
                },
                "uiProperties": { // ARMD if applicable, or it will be missing from here
                    "inputType": "" // Either of Auto, User, Admin
                    "widget": "", // Widget to use on UI i.e. Either of Text, Password, Number, Date, SelectOne, RepeatableFieldSet, CheckboxSet
                    "title": "", // Title to use on UI
                    "labelHint": "", // Labelhint to use on UI
                    "minLength": {SOME_POSITIVE_NUMBER},
                    "maxLength": {SOME_POSITIVE_NUMBER},
                    "defaultValues": [ // Default values if applicable, or it will be missing from here
                    ]
                }
            }
        ]
    }
  ]
}

Sortie du modèle de schéma

La sortie du modèle de schéma est retournée en tant que document JSON.

Sortie du modèle de schéma

La sortie de votre modèle de schéma ressemblera à celle fournie dans la mise en oeuvre de référence (<ReferenceBase>/functions/grc-schema-template/src/main/resources/schema/applications/<YourApplicationName>/TEMPLATE.json) :
{
  "schemaTemplates": [
    {
      "type": "ACCOUNT",
      "name": "UserAsIdentity",
      "displayName": "User As Identity",
      "attributes": [
        {
          "name": "uid",
          "dataType": "TEXT",
          "nature": [
            "REQUIRED"
          ],
          "usage": [
            "READ"
          ]
        },
        {
          "name": "name",
          "dataType": "TEXT",
          "nature": [
            "REQUIRED"
          ],
          "usage": [
            "READ"
          ]
        },
        {
          "name": "email",
          "dataType": "TEXT",
          "nature": [
            "REQUIRED"
          ],
          "usage": [
            "READ"
          ]
        },
        {
          "name": "firstName",
          "dataType": "TEXT",
          "usage": [
            "READ"
          ]
        },
        {
          "name": "middleName",
          "dataType": "TEXT",
          "usage": [
            "READ"
          ]
        },
        {
          "name": "lastName",
          "dataType": "TEXT",
          "usage": [
            "READ"
          ]
        },
        {
          "name": "displayName",
          "dataType": "TEXT",
          "nature": [
            "REQUIRED"
          ],
          "usage": [
            "READ"
          ]
        },
        {
          "name": "employeeType",
          "dataType": "TEXT",
          "usage": [
            "READ"
          ]
        },
        {
          "name": "title",
          "dataType": "TEXT",
          "usage": [
            "READ"
          ]
        },
        {
          "name": "empNo",
          "dataType": "TEXT",
          "usage": [
            "READ"
          ]
        },
        {
          "name": "jobCode",
          "dataType": "TEXT",
          "usage": [
            "READ"
          ]
        },
        {
          "name": "state",
          "dataType": "TEXT",
          "usage": [
            "READ"
          ]
        },
        {
          "name": "risk",
          "dataType": "TEXT",
          "usage": [
            "READ"
          ]
        },
        {
          "name": "location",
          "dataType": "TEXT",
          "usage": [
            "READ"
          ]
        },
        {
          "name": "department",
          "dataType": "TEXT",
          "usage": [
            "READ"
          ]
        },
        {
          "name": "managerUid",
          "dataType": "TEXT",
          "usage": [
            "READ"
          ]
        },
        {
          "name": "organizationUid",
          "dataType": "TEXT",
          "usage": [
            "READ"
          ]
        },
        {
          "name": "organizationName",
          "dataType": "TEXT",
          "usage": [
            "READ"
          ]
        },
        {
          "name": "postalCode",
          "dataType": "TEXT",
          "usage": [
            "READ"
          ]
        },
        {
          "name": "territory",
          "dataType": "TEXT",
          "usage": [
            "READ"
          ]
        },
        {
          "name": "usageLocation",
          "dataType": "TEXT",
          "usage": [
            "READ"
          ]
        },
        {
          "name": "country",
          "dataType": "TEXT",
          "usage": [
            "READ"
          ],
          "relationship": {
            "relatedTo": "countries",
            "relatedBy": "uid"
          }
        },
        {
          "name": "managerLogin",
          "dataType": "TEXT",
          "usage": [
            "READ"
          ]
        },
        {
          "name": "preferredLanguage",
          "dataType": "TEXT",
          "usage": [
            "READ"
          ],
          "relationship": {
            "relatedTo": "languages",
            "relatedBy": "uid"
          }
        },
        {
          "name": "status",
          "dataType": "FLAG",
          "usage": [
            "READ"
          ]
        }
      ]
    },
    {
      "type": "ENTITLEMENT",
      "name": "GroupAsEntitlement",
      "displayName": "Group As Entitlement",
      "attributes": [
        {
          "name": "uid",
          "dataType": "TEXT",
          "nature": [
            "REQUIRED"
          ],
          "usage": [
            "READ"
          ]
        },
        {
          "name": "name",
          "dataType": "TEXT",
          "nature": [
            "REQUIRED"
          ],
          "usage": [
            "READ"
          ]
        }
      ]
    },
    {
      "type": "TARGETACCOUNT",
      "name": "UserAsAccount",
      "displayName": "User As Account",
      "attributes": [
        {
          "name": "uid",
          "dataType": "TEXT",
          "nature": [
            "REQUIRED"
          ],
          "usage": [
            "READ",
            "PROVISION"
          ],
          "uiProperties": {
            "inputType": "Auto",
            "widget": "Text",
            "title": "User ID",
            "labelHint": "User ID",
            "minLength": 1,
            "maxLength": 256
          }
        },
        {
          "name": "name",
          "dataType": "TEXT",
          "nature": [
            "REQUIRED"
          ],
          "usage": [
            "READ",
            "PROVISION"
          ],
          "outboundTransformation": {
            "script": "user.getPrimaryEmail()"
          },
          "uiProperties": {
            "inputType": "Auto",
            "widget": "Text",
            "title": "User Name",
            "labelHint": "User Name",
            "minLength": 1,
            "maxLength": 256
          }
        },
        {
          "name": "email",
          "dataType": "TEXT",
          "nature": [
            "REQUIRED"
          ],
          "usage": [
            "READ",
            "PROVISION"
          ],
          "outboundTransformation": {
            "script": "user.getPrimaryEmail()"
          },
          "uiProperties": {
            "inputType": "Auto",
            "widget": "Text",
            "title": "Email",
            "labelHint": "Email",
            "minLength": 1,
            "maxLength": 256
          }
        },
        {
          "name": "firstName",
          "dataType": "TEXT",
          "usage": [
            "READ",
            "PROVISION"
          ],
          "outboundTransformation": {
            "script": "user.getName().getGivenName()"
          },
          "uiProperties": {
            "inputType": "Auto",
            "widget": "Text",
            "title": "First Name",
            "labelHint": "First Name",
            "minLength": 1,
            "maxLength": 256
          }
        },
        {
          "name": "lastName",
          "dataType": "TEXT",
          "usage": [
            "READ",
            "PROVISION"
          ],
          "outboundTransformation": {
            "script": "user.getName().getFamilyName()"
          },
          "uiProperties": {
            "inputType": "Auto",
            "widget": "Text",
            "title": "Last Name",
            "labelHint": "Last Name",
            "minLength": 1,
            "maxLength": 256
          }
        },
        {
          "name": "displayName",
          "dataType": "TEXT",
          "nature": [
            "REQUIRED"
          ],
          "usage": [
            "READ",
            "PROVISION"
          ],
          "outboundTransformation": {
            "script": "[user.getName().getGivenName(), user.getName().getFamilyName()].filter(element => { return element !== null && element.length > 0}).join(' ')"
          },
          "uiProperties": {
            "inputType": "Auto",
            "widget": "Text",
            "title": "Display Name",
            "labelHint": "Display Name",
            "minLength": 1,
            "maxLength": 256
          }
        },
        {
          "name": "mailNickname",
          "dataType": "TEXT",
          "nature": [
            "REQUIRED"
          ],
          "usage": [
            "READ",
            "PROVISION"
          ],
          "outboundTransformation": {
            "script": "[user.getName().getGivenName(), user.getName().getFamilyName()].filter(element => { return element !== null && element.length > 0}).join('')"
          },
          "uiProperties": {
            "inputType": "Auto",
            "widget": "Text",
            "title": "Nick Name",
            "labelHint": "Nick Name",
            "minLength": 1,
            "maxLength": 256
          }
        },
        {
          "name": "password",
          "dataType": "TEXT",
          "nature": [
            "REQUIRED",
            "SENSITIVE"
          ],
          "usage": [
            "READ",
            "PROVISION"
          ],
          "uiProperties": {
            "inputType": "User",
            "widget": "Password",
            "title": "Password",
            "labelHint": "Password",
            "minLength": 1,
            "maxLength": 256
          }
        },
        {
          "name": "usageLocation",
          "dataType": "TEXT",
          "usage": [
            "READ",
            "PROVISION"
          ],
          "relationship": {
            "relatedTo": "countries"
          },
          "outboundTransformation": {
            "script": "user.getLocation() != null ? transformationUtil.getLookupCode(agcs_tenant_id, agcs_target_id, 'countries', user.getLocation()) : null"
          },
          "uiProperties": {
            "inputType": "Auto",
            "widget": "SelectOne",
            "title": "Location",
            "labelHint": "Location",
            "minLength": 1,
            "maxLength": 256
          }
        },
        {
          "name": "city",
          "dataType": "TEXT",
          "usage": [
            "READ",
            "PROVISION"
          ],
          "uiProperties": {
            "inputType": "User",
            "widget": "Text",
            "title": "City",
            "labelHint": "City",
            "minLength": 1,
            "maxLength": 256
          }
        },
        {
          "name": "country",
          "dataType": "TEXT",
          "usage": [
            "READ",
            "PROVISION"
          ],
          "relationship": {
            "relatedTo": "countries",
            "relatedBy": "uid"
          },
          "outboundTransformation": {
            "script": "user.getAddresses() != null && user.getAddresses().size() > 0 ? transformationUtil.getLookupCode(agcs_tenant_id, agcs_target_id, 'countries', user.getAddresses().get(0).getCountry()) : null"
          },
          "uiProperties": {
            "inputType": "Auto",
            "widget": "SelectOne",
            "title": "Country",
            "labelHint": "Country",
            "minLength": 1,
            "maxLength": 256
          }
        },
        {
          "name": "managerLogin",
          "dataType": "TEXT",
          "usage": [
            "READ",
            "PROVISION"
          ],
          "uiProperties": {
            "inputType": "Admin",
            "widget": "Text",
            "title": "Manager Login",
            "labelHint": "Manager Login",
            "minLength": 1,
            "maxLength": 256
          }
        },
        {
          "name": "preferredLanguage",
          "dataType": "TEXT",
          "usage": [
            "READ",
            "PROVISION"
          ],
          "relationship": {
            "relatedTo": "languages",
            "relatedBy": "uid"
          },
          "uiProperties": {
            "inputType": "Admin",
            "widget": "SelectOne",
            "title": "Language",
            "labelHint": "Language",
            "minLength": 1,
            "maxLength": 256
          }
        },
        {
          "name": "userType",
          "dataType": "TEXT",
          "usage": [
            "READ"
          ]
        },
        {
          "name": "status",
          "dataType": "FLAG",
          "usage": [
            "READ",
            "PROVISION"
          ],
          "outboundTransformation": {
            "script": "true"
          },
          "uiProperties": {
            "inputType": "Auto",
            "widget": "Text",
            "title": "Status",
            "labelHint": "Status",
            "minLength": 1,
            "maxLength": 256
          }
        },
        {
          "name": "groups",
          "dataType": "TEXT",
          "nature": [
            "MULTIVALUED"
          ],
          "usage": [
            "READ",
            "PROVISION"
          ],
          "relationship": {
            "relatedTo": "GroupAsEntitlement",
            "relatedBy": "uid",
            "relationshipProperties": []
          },
          "uiProperties": {
            "inputType": "Admin",
            "widget": "RepeatableFieldSet",
            "title": "Groups",
            "labelHint": "Groups",
            "minLength": 1,
            "maxLength": 256
          }
        }
      ]
    },
    {
      "name": "countries",
      "type": "LOOKUP",
      "attributes": [
        {
          "name": "uid",
          "dataType": "TEXT",
          "nature": [
            "REQUIRED"
          ],
          "usage": [
            "READ"
          ]
        },
        {
          "name": "name",
          "dataType": "TEXT",
          "nature": [
            "REQUIRED"
          ],
          "usage": [
            "READ"
          ]
        }
      ]
    },
    {
      "name": "languages",
      "type": "LOOKUP",
      "attributes": [
        {
          "name": "uid",
          "dataType": "TEXT",
          "nature": [
            "REQUIRED"
          ],
          "usage": [
            "READ"
          ]
        },
        {
          "name": "name",
          "dataType": "TEXT",
          "nature": [
            "REQUIRED"
          ],
          "usage": [
            "READ"
          ]
        }
      ]
    }
  ]
}

Structure du modèle de demande

Pour prendre en charge les demandes à la source faisant autorité ou au système géré requis, vous devez créer votre modèle de demande à l'aide de la structure prise en charge.

Structure de la demande

La structure de demande que vous devez suivre lors de la création de votre modèle de demande est la suivante :
{
  "id": "", // request id
  "name": "", // request name
  "paginationType": "", // either of OFFSET,PAGE_INCREMENT,PAGE_TOKEN
  "method": "", // either of GET,HEAD,POST,PUT,PATCH,DELETE,OPTIONS,TRACE
  "uri": {
    "scheme": "", // request URI scheme either of http, https
    "host": "", // request URI host
    "path": "" // request URI path
  },
  "queryParameters": [
    {
      "name": "", // queryParameter name
      "value": "" // queryParameter value
    }
  ],
  "headers": [
    {
      "name": "", // request header name
      "value": "" // request header value
    }
  ],
  "body": {
        "type": "text",
        "textBody": {} // json request body
  },
  "subRequests": [ // subrequest if any
    {
      "id": "", // subrequest id
      "name": "", // subrequest name
      "paginationType": "", // either of OFFSET,PAGE_INCREMENT,PAGE_TOKEN
      "method": "", // either of GET,HEAD,POST,PUT,PATCH,DELETE,OPTIONS,TRACE
      "uri": {
        "scheme": "", // subrequest URI scheme either of http, https
        "host": "", // subrequest URI host
        "path": "" // subrequest URI path
      },
      "queryParameters": [
        {
          "name": "", // subrequestqueryParameter name
          "value": "" // subrequest queryParameter value
        }
      ],
      "headers": [
        {
          "name": "", // subrequest header name
          "value": "" // subrequest header value
        }
      ],
      "body": {
        "type": "text",
        "textBody": {} // json subrequest body
      }
    }
  ]
}

Prise en charge de la pagination

La structure de demande prend en charge un certain nombre de méthodes de pagination pour éviter que les résultats de recherche volumineux causent un trafic réseau excessif. Les méthodes de pagination suivantes sont prises en charge :
  • COMPENSATION
  • PAGE_INCREMENT
  • PAGE_TOKEN
Les paramètres de ces méthodes sont détaillés comme suit. Ils doivent être ajoutés à l'outline de la demande.
Prise en charge de la pagination
Type de pagination Conditions requises Configuration
COMPENSATION L'API REST que vous intégrez à Oracle Access Governance doit prendre en charge la pagination OFFSET lors du retour d'une réponse.

Si paginationType est réglé à OFFSET, vous devez ajouter les valeurs de paramètre suivantes à la structure :

"queryParameters": [
{"name": "startIndex", "value": "<EL>currentOffset</EL>"}
{"name": "count", "value": "<EL>limit</EL>"}
] 
PAGE_INCREMENT L'API REST que vous intégrez à Oracle Access Governance doit prendre en charge la pagination PAGE_INCREMENT lors du retour d'une réponse.

Si paginationType est réglé à PAGE_INCREMENT, vous devez ajouter les valeurs de paramètre suivantes à la structure :

"queryParameters": [
{"name": "currentPage", "value": "<EL>currentPage</EL>"}
{"name": "pageSize", "value": "<EL>pageSize</EL>"}
] 
PAGE_TOKEN L'API REST que vous intégrez à Oracle Access Governance doit prendre en charge la pagination PAGE_TOKEN lors du retour d'une réponse.

Si paginationType est réglé à PAGE_TOKEN, vous devez ajouter les valeurs de paramètre suivantes à la structure :

"queryParameters": [
{"name": "top", "value": "<EL>pageSize</EL>"}
{"name": "skiptoken", "value": "<EL>previousRequestResponseHeaders.get('token')==null ? '' :
    previousRequestResponseHeaders.get('token').get(0)</EL>"}
] 
Note

Le nom d'un paramètre de pagination particulier peut varier selon l'API REST avec laquelle vous êtes connecté. Par exemple, pour la pagination OFFSET, les paramètres peuvent être les suivants :
{"name": "startIndex", "value": "<EL>currentOffset</EL>"}
{"name": "count", "value": "<EL>limit</EL>"}
ou
{"name": "beginIndex", "value": "<EL>currentOffset</EL>"}
{"name": "increment", "value": "<EL>limit</EL>"}
Vous devez utiliser le nom spécifié par votre API, mais utilisez les valeurs décrites dans cet article.

Sortie du modèle de demande

La sortie du modèle de demande est retournée en tant que document JSON pour les entités et les opérations définies.

Sortie du modèle de demande

La sortie de votre modèle de demande sera semblable à celle fournie dans la mise en oeuvre de référence (<ReferenceBase>/functions/grc-schema-template/src/main/resources/request/applications/<YourApplicationName>/<EntityName>/<Operation>_TEMPLATE.json) :

Par exemple, à partir de l'implémentation de référence :

  • EntityName: UserAsIdentity
  • Opération : GET
{
  "id": "1",
  "name": "Get User As Identity By ID",
  "method": "GET",
  "uri": {
    "scheme": "<<SCHEME>>",
    "host": "<<HOST>>",
    "path": "/admin/v1/Users/<EL>attributes.get('uid').get(0)</EL>"
  },
  "headers": [
    {
      "name": "Content-Type",
      "value": "application/json"
    },
    {
      "name": "Authorization",
      "value": "<<CREDENTIALS>>"
    }
  ]
}
  • EntityName: UserAsIdentity
  • Opération : RECHERCHE
{
  "id": "1",
  "name": "Search Users As Identity sort by displayName",
  "paginationType": "OFFSET",
  "method": "GET",
  "uri": {
    "scheme": "<<SCHEME>>",
    "host": "<<HOST>>",
    "path": "/admin/v1/Users"
  },
  "queryParameters": [
    {
      "name": "startIndex",
      "value": "<EL>currentOffset</EL>"
    },
    {
      "name": "count",
      "value": "<EL>limit</EL>"
    },
    {
      "name": "sortBy",
      "value": "displayName"
    }
  ],
  "headers": [
    {
      "name": "Content-Type",
      "value": "application/json"
    },
    {
      "name": "Authorization",
      "value": "<<CREDENTIALS>>"
    }
  ]
}

Structure du modèle de réponse

Pour prendre en charge le format de réponse pour les données d'identité et de compte, vous devez créer votre modèle de réponse à l'aide de la structure prise en charge.

Structure de la réponse

L'outline de réponse que vous devez suivre lors de la création de votre modèle de réponse est :
{
  "items": "", // items json path
  "attributes": [
    {
      "name": "", // attribute name
      "value": "" // attribute value json path
    },
    {
      "name": "", // attribute name for subrequest response
      "responseOfSubRequestId": "", // subrequest id
      "items": "", // items json path for subrequest response
      "subAttributes": [ // sub attributes for subrequest response
        {
          "name": "", // subrequest response attribute name
          "value": "" // subrequest response attribute value json path
        }
      ]
    }
  ]
}

Sortie du modèle de réponse

La sortie du modèle de réponse est retournée en tant que document JSON pour les entités et les opérations définies.

Sortie du modèle de réponse

La sortie de votre modèle de réponse ressemblera à celle fournie dans la mise en oeuvre de référence (<ReferenceBase>/functions/grc-response-template/src/main/resources/response/applications/<YourApplicationName>/<EntityName>/<Operation>_TEMPLATE.json) :

Par exemple, à partir de l'implémentation de référence :

  • EntityName: UserAsIdentity
  • Opération : GET
{
  "attributes": [
    {
      "name": "uid",
      "value": "<JP>$.id</JP>"
    },
    {
      "name": "name",
      "value": "<JP>$.userName</JP>"
    },
    {
      "name": "email",
      "value": "<JP>$.emails[?(@.primary == true)].value</JP>"
    },
    {
      "name": "firstName",
      "value": "<JP>$.name.familyName</JP>"
    },
    {
      "name": "lastName",
      "value": "<JP>$.name.givenName</JP>"
    },
    {
      "name": "displayName",
      "value": "<JP>$.displayName</JP>"
    },
    {
      "name": "usageLocation",
      "value": "<JP>$.addresses[?(@.type == 'work')].country</JP>"
    },
    {
      "name": "country",
      "value": "<JP>$.addresses[?(@.type == 'work')].country</JP>"
    },
    {
      "name": "managerLogin",
      "value": "<JP>$.['urn:ietf:params:scim:schemas:extension:enterprise:2.0:User'].manager.value</JP>"
    },
    {
      "name": "preferredLanguage",
      "value": "<JP>$.preferredLanguage</JP>"
    },
    {
      "name": "status",
      "value": "<JP>$.active</JP>"
    }
  ]
}
  • EntityName: UserAsIdentity
  • Opération : RECHERCHE
{
  "items": "<JP>$.Resources[*]</JP>",
  "attributes": [
    {
      "name": "uid",
      "value": "<JP>$.Resources[<EL>currentIndex</EL>].id</JP>"
    },
    {
      "name": "name",
      "value": "<JP>$.Resources[<EL>currentIndex</EL>].userName</JP>"
    },
    {
      "name": "email",
      "value": "<JP>$.Resources[<EL>currentIndex</EL>].emails[?(@.primary == true)].value</JP>"
    },
    {
      "name": "firstName",
      "value": "<JP>$.Resources[<EL>currentIndex</EL>].name.familyName</JP>"
    },
    {
      "name": "lastName",
      "value": "<JP>$.Resources[<EL>currentIndex</EL>].name.givenName</JP>"
    },
    {
      "name": "displayName",
      "value": "<JP>$.Resources[<EL>currentIndex</EL>].displayName</JP>"
    },
    {
      "name": "usageLocation",
      "value": "<JP>$.Resources[<EL>currentIndex</EL>].addresses[?(@.type == 'work')].country</JP>"
    },
    {
      "name": "country",
      "value": "<JP>$.Resources[<EL>currentIndex</EL>].addresses[?(@.type == 'work')].country</JP>"
    },
    {
      "name": "managerLogin",
      "value": "<JP>$.Resources[<EL>currentIndex</EL>].['urn:ietf:params:scim:schemas:extension:enterprise:2.0:User'].manager.value</JP>"
    },
    {
      "name": "preferredLanguage",
      "value": "<JP>$.Resources[<EL>currentIndex</EL>].preferredLanguage</JP>"
    },
    {
      "name": "status",
      "value": "<JP>$.Resources[<EL>currentIndex</EL>].active</JP>"
    }
  ]
}

Autorisation de base - Exemple de code de création de jeton

Si vous utilisez l'autorisation de base avec votre système orchestré REST générique, vous devrez créer un jeton d'autorisation. L'exemple de code qui suit donne un exemple de codage de cette fonction :

Exemple de code de création de jeton

Si vous utilisez l'autorisation de base avec votre système orchestré REST générique, vous devrez créer un jeton d'autorisation. L'exemple de code qui suit donne un exemple de codage de cette fonction :
public static String getAuthorizationValue(Config config) {
    String TOKEN_PREFIX_BASIC = "Basic ";
    try {
      String vaultJsonValue =
              VaultUtil.getDataFromVault(
                      config.getAuthenticationDetail().get("secretId"),
                      config.getAuthenticationDetail().get("region"));
      String username = VaultUtil.getAttributeValueFromJson(vaultJsonValue, "username");
      String password = VaultUtil.getAttributeValueFromJson(vaultJsonValue, "password");
      String authHeader = username.concat(":").concat(password);
      return TOKEN_PREFIX_BASIC
              + Base64.getEncoder()
              .encodeToString(authHeader.getBytes(StandardCharsets.UTF_8));
    } catch (UnsupportedEncodingException | JsonProcessingException e) {
      System.err.println("Exception occurred while getting secret from vault. " + e.getMessage());
      throw new RuntimeException("Exception occurred while getting secret from vault", e);
    }
  }
  // secretId and region value will come from config.yaml file
  // username and password value will come from vault secret which has been configured in above steps.

Autorisation OAuth - Exemple de code de création de jeton

Si vous utilisez l'autorisation OAuth avec votre système orchestré REST générique, vous devrez créer un jeton d'autorisation. Les exemples qui suivent donnent un exemple de codage de cette fonction :

Exemple de code de création de jeton

Pour le système orchestré IDCS :

Ce code est fourni avec l'exemple de mise en oeuvre fourni avec le connecteur REST générique, disponible à l'adresse <SampleBase>/grc-serverless-function-samples/idm-agcs-serverless-multi-application-sample/grc-commons/src/main/java/com/oracle/idm/agcs/grc/fn/commons/provider/IDCSAuthenticationProvider.java.
/*
 * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved.
 * Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl.
 */
package com.oracle.idm.agcs.grc.fn.commons.provider;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.oracle.idm.agcs.grc.fn.commons.config.ConnectedSystemConfig;
import com.oracle.idm.agcs.grc.fn.commons.exception.ProcessingFailedException;
import com.oracle.idm.agcs.icfconnectors.commons.util.VaultUtil;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.InetSocketAddress;
import java.net.ProxySelector;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.text.MessageFormat;
import java.util.Base64;

public class IDCSAuthenticationProvider extends AuthenticationProvider {

  @Override
  public String getAuthorizationValue(ConnectedSystemConfig connectedSystemConfig) {
    String url =
        connectedSystemConfig
            .getAuthenticationDetail()
            .get("scheme")
            .concat("://")
            .concat(connectedSystemConfig.getAuthenticationDetail().get("host"))
            .concat(connectedSystemConfig.getAuthenticationDetail().get("path"));
    String requestBody = "grant_type=client_credentials&scope=urn%3Aopc%3Aidm%3A__myscopes__";
    String authHeader;
    try {
      String vaultJsonValue = VaultUtil.getDataFromVault(connectedSystemConfig.getAuthenticationDetail().get("secretId"), connectedSystemConfig.getAuthenticationDetail().get("region"));
      String clientCode =  VaultUtil.getAttributeValueFromJson(vaultJsonValue, "clientCode");
      String clientSecret = VaultUtil.getAttributeValueFromJson(vaultJsonValue, "clientSecret");
      authHeader = clientCode.concat(":").concat(clientSecret);
    } catch (UnsupportedEncodingException | JsonProcessingException e) {
      System.err.println("Exception occurred while getting secret from vault. " + e.getMessage());
      throw new ProcessingFailedException(
              "Exception occurred while getting secret from vault", e);
    }
    HttpClient client = HttpClient.newBuilder().build();
    String connectorProxyHost = System.getProperty(CONNECTOR_PROXY_HOST);
    String connectorProxyPort = System.getProperty(CONNECTOR_PROXY_PORT);
    if (null != connectorProxyHost
            && !connectorProxyHost.trim().isEmpty()
            && null != connectorProxyPort
            && !connectorProxyPort.trim().isEmpty()) {
      System.out.println(
              MessageFormat.format(
                      "connectorProxyHost {0} and connectorProxyPort {1} is available in system property",
                      connectorProxyHost, connectorProxyPort));
      try {
        client =
                HttpClient.newBuilder()
                        .proxy(
                                ProxySelector.of(
                                        new InetSocketAddress(
                                                connectorProxyHost, Integer.parseInt(connectorProxyPort))))
                        .build();
      } catch (NumberFormatException exception) {
        System.err.println("connectorProxyPort value is not integer : "+exception);
      }
    }
    final HttpRequest request =
        HttpRequest.newBuilder()
            .uri(URI.create(url))
            .header(HEADER_NAME_CONTENT_TYPE, HEADER_VALUE_CONTENT_TYPE_FORM_URL_ENCODED)
            .header(
                HEADER_NAME_AUTHORIZATION,
                TOKEN_PREFIX_BASIC
                    + Base64.getEncoder()
                        .encodeToString(authHeader.getBytes(StandardCharsets.UTF_8)))
            .POST(HttpRequest.BodyPublishers.ofString(requestBody))
            .build();
    HttpResponse<String> response;
    try {
      response = client.send(request, HttpResponse.BodyHandlers.ofString());
    } catch (IOException e) {
      System.err.println(
          "IDCSAuthenticationProvider Auth Token API HttpRequest failed due to IOException."
              + e.getMessage());
      throw new ProcessingFailedException(
          "IDCSAuthenticationProvider Auth Token API HttpRequest failed due to IOException.", e);
    } catch (InterruptedException e) {
      System.err.println(
          "IDCSAuthenticationProvider Auth Token API HttpRequest failed due to InterruptedException."
              + e.getMessage());
      throw new ProcessingFailedException(
          "IDCSAuthenticationProvider Auth Token API HttpRequest failed due to InterruptedException.",
          e);
    }
    System.err.println(
        "IDCSAuthenticationProvider Auth Token API HttpResponse is :: " + response.body());
    JsonNode jsonNode;
    try {
      jsonNode = objectMapper.readTree(response.body());
    } catch (JsonProcessingException e) {
      System.err.println(
          "IDCSAuthenticationProvider Auth Token API HttpResponse parsing to json is failed.");
      throw new ProcessingFailedException(
          "IDCSAuthenticationProvider Auth Token API HttpResponse parsing to json is failed.", e);
    }
    return TOKEN_PREFIX_BEARER.concat(jsonNode.get(ACCESS_TOKEN_ATTRIBUTE).textValue());
  }
}

Pour AzureAD système orchestré :

Ce code est fourni avec l'exemple de mise en oeuvre fourni avec le connecteur REST générique, disponible à l'adresse <SampleBase>/grc-serverless-function-samples/idm-agcs-serverless-multi-application-sample/grc-commons/src/main/java/com/oracle/idm/agcs/grc/fn/commons/provider/AzureAdAuthenticationProvider.java.
/*
 * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved.
 * Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl.
 */
package com.oracle.idm.agcs.grc.fn.commons.provider;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.oracle.idm.agcs.grc.fn.commons.config.ConnectedSystemConfig;
import com.oracle.idm.agcs.grc.fn.commons.exception.ProcessingFailedException;
import com.oracle.idm.agcs.icfconnectors.commons.util.VaultUtil;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.InetSocketAddress;
import java.net.ProxySelector;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

public class AzureAdAuthenticationProvider extends AuthenticationProvider {
  @Override
  public String getAuthorizationValue(ConnectedSystemConfig connectedSystemConfig) {
    String url =
        connectedSystemConfig
            .getAuthenticationDetail()
            .get("scheme")
            .concat("://")
            .concat(connectedSystemConfig.getAuthenticationDetail().get("host"))
            .concat(connectedSystemConfig.getAuthenticationDetail().get("path"));
    String requestBody;
    try {
      String vaultJsonValue = VaultUtil.getDataFromVault(connectedSystemConfig.getAuthenticationDetail().get("secretId"), connectedSystemConfig.getAuthenticationDetail().get("region"));
      requestBody =
              "client_id="
                      + VaultUtil.getAttributeValueFromJson(vaultJsonValue, "clientCode")
                      + "&client_secret="
                      + VaultUtil.getAttributeValueFromJson(vaultJsonValue, "clientSecret")
                      + "&grant_type="
                      + connectedSystemConfig.getAuthenticationDetail().get("grantType")
                      + "&scope="
                      + connectedSystemConfig.getAuthenticationDetail().get("scope");
    } catch (UnsupportedEncodingException | JsonProcessingException e) {
      System.err.println("Exception occurred while getting secret from vault. " + e.getMessage());
      throw new ProcessingFailedException(
              "Exception occurred while getting secret from vault", e);
    }
    final HttpClient client = getHttpClient(connectedSystemConfig);
    final HttpRequest request =
        HttpRequest.newBuilder()
            .uri(URI.create(url))
            .header(AuthenticationProvider.HEADER_NAME_CONTENT_TYPE, AuthenticationProvider.HEADER_VALUE_CONTENT_TYPE_FORM_URL_ENCODED)
            .POST(HttpRequest.BodyPublishers.ofString(requestBody))
            .build();
    HttpResponse<String> response;
    try {
      response = client.send(request, HttpResponse.BodyHandlers.ofString());
    } catch (IOException e) {
      System.err.println(
          "AzureAdAuthenticationProvider Auth Token API HttpRequest failed due to IOException."
              + e.getMessage());
      throw new ProcessingFailedException(
          "AzureAdAuthenticationProvider Auth Token API HttpRequest failed due to IOException.", e);
    } catch (InterruptedException e) {
      System.err.println(
          "AzureAdAuthenticationProvider Auth Token API HttpRequest failed due to InterruptedException."
              + e.getMessage());
      throw new ProcessingFailedException(
          "AzureAdAuthenticationProvider Auth Token API HttpRequest failed due to InterruptedException.",
          e);
    }
    System.err.println(
        "AzureAdAuthenticationProvider Auth Token API HttpResponse is :: " + response.body());
    JsonNode jsonNode;
    try {
      jsonNode = AuthenticationProvider.objectMapper.readTree(response.body());
    } catch (JsonProcessingException e) {
      System.err.println(
          "AzureAdAuthenticationProvider Auth Token API HttpResponse parsing to json is failed.");
      throw new ProcessingFailedException(
          "AzureAdAuthenticationProvider Auth Token API HttpResponse parsing to json is failed.",
          e);
    }
    return AuthenticationProvider.TOKEN_PREFIX_BEARER.concat(jsonNode.get(AuthenticationProvider.ACCESS_TOKEN_ATTRIBUTE).textValue());
  }

  private HttpClient getHttpClient(ConnectedSystemConfig connectedSystemConfig) {
    if (null == connectedSystemConfig.getAuthenticationDetail().get("proxyHost")
        || null == connectedSystemConfig.getAuthenticationDetail().get("proxyPort")) {
      return HttpClient.newHttpClient();
    }
    return HttpClient.newBuilder()
        .proxy(
            ProxySelector.of(
                new InetSocketAddress(
                    connectedSystemConfig.getAuthenticationDetail().get("proxyHost"),
                    Integer.parseInt(connectedSystemConfig.getAuthenticationDetail().get("proxyPort")))))
        .build();
  }
}