Allgemeine REST-Referenz

Ein generisches REST-Orchestriertes System wird mit einer minimalen Vorlage erstellt, die zur Laufzeit mit OCI Functions aktualisiert wird, um das Orchestrierte System mit Objektklassen, Lookup-Typen und ausgehenden Transformationsdaten zu aktualisieren.

Schema-Discovery - Workflow auf hoher Ebene

Schema-Discovery ist der Prozess, bei dem ein generisches REST-orchestriertes System OCI-Funktionsvorlagen anwendet, um das Discovery des Schemas, der Objektklassen, der Attribute und der Verbindungsdetails für die konfigurierte autoritative Quelle oder das konfigurierte verwaltete System zu ermöglichen.

Schema-Discovery erfolgt, wenn ein orchestriertes System in Oracle Access Governance erstellt wird. Vereinfachte Workflows für Day0- und DayN-Szenarios werden in den folgenden Tabellen beschrieben.

Day0 Workflow

Day0 Workflow
Schritt-Nr. Aufgabe/Arbeitsvorgang Beschreibung
1 Orchestriertes System erstellen

Orchestriertes System mit der Oracle Access Governance-Konsole erstellen

Das orchestrierte System wird mit Details der OCI-Funktion erstellt, die Sie erstellt haben, um Details aus der erforderlichen autoritativen Quelle oder dem verwalteten System zurückzugeben.

Basierend auf den im Orchestrierten System eingegebenen Details wird der folgende Vorgang erstellt.
  • Validieren
2 Vorgangsausführung validieren
Der Vorgang "Validieren" wird ausgeführt und ruft basierend auf der konfigurierten Schemavorlage das Schema ab, einschließlich der folgenden Objektklassen:
  • Identität: Ruft nur Core-Attribute ab. Die erforderlichen Core-Objekte müssen hier beschrieben sein
  • Keine Identität: Ruft alle Attribute ab. Die Mindestattribute müssen hier aufgeführt sein

Die Testvorlage "Konfigurieren" wird aufgerufen, um die Konnektivität mit dem verwalteten System zu validieren.

3 Postvalidierungsvorgang
Nach erfolgreicher Ausführung des Validierungsvorgangs werden die folgenden Vorgänge erstellt:
  • Lookup-Dataload
  • Vollständiger Dataload

DayN Workflow

DayN Workflow
Schritt-Nr. Aufgabe/Arbeitsvorgang Beschreibung
1 Wählen Sie auf der Seite Identitätsattribute der Oracle Access Governance die Option Attribute abrufen aus. Weitere Informationen finden Sie unter Letzte benutzerdefinierte Attribute abrufen. Im orchestrierten System wird ein Schema-Discovery-Vorgang erstellt
2 Ausführung des Schema-Discovery-Vorgangs Der Schema-Discovery-Vorgang wird ausgeführt und ruft basierend auf der konfigurierten Schemavorlage das Schema ab, einschließlich der folgenden Objektklassen:
  • Identität: Ruft Core- und benutzerdefinierte Attribute ab
  • Nicht identität: Ruft alle Attribute ab
3 Seite Identitätsattribute aktualisieren In der Liste der benutzerdefinierten Attribute werden die neuen benutzerdefinierten Attribute für die Identitätsobjektklasse angezeigt.
Wenn alle oben genannten Vorgänge erfolgreich abgeschlossen wurden, steht das orchestrierte System dem Scheduler zur Verfügung, um nachfolgende vollständige Dataload-Vorgänge zu erstellen.

Erforderliche Schemaattribute für generische REST-Schema-Discovery

Bei der Schemaerkennung müssen bestimmte obligatorische Attribute als Teil der Schemaausgabe zurückgegeben werden.

Identitätsobjektklasse

Die erforderlichen Attribute, die als Teil der Schemaausgabe für die Identity-Objektklasse zurückgegeben werden müssen, sind:

  • UID
  • Name
  • E-Mail
  • firstName
  • middleName
  • lastName
  • displayName
  • employeeType
  • title
  • empNo
  • Status
  • jobCode
  • Bundesland
  • Risiko
  • Standort
  • Abteilungen
  • managerUid
  • managerLogin
  • organizationUid
  • organizationName
  • Land
  • postalCode
  • territory
[
  {
    "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"
    ]
  }
]

Nicht-Identitätsobjektklasse

Die obligatorischen Attribute, die als Teil der Schemaausgabe für die Nicht-Identitätsobjektklasse zurückgegeben werden müssen, sind:

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

Schemavorlagenstruktur

Um die Schemaerkennung zu unterstützen, müssen Sie Ihre Schemavorlage mit dem unterstützten Outline erstellen.

Schemagliederung

Die Schema-Outline, die Sie beim Erstellen der Schema-Vorlage befolgen sollten, lautet:
{
 "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
                    ]
                }
            }
        ]
    }
  ]
}

Schemavorlagenausgabe

Die Ausgabe der Schemavorlage wird als JSON-Dokument zurückgegeben.

Schemavorlagenausgabe

Die Ausgabe der Schemavorlage sieht ähnlich aus wie in der Referenzimplementierung (<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"
          ]
        }
      ]
    }
  ]
}

Anforderungsvorlagenstruktur

Um Anforderungen an die erforderliche autoritative Quelle oder das verwaltete System zu unterstützen, müssen Sie Ihre Anforderungsvorlage mit der unterstützten Gliederung erstellen.

Gliederung anfordern

Die Anforderungsstruktur, die Sie beim Erstellen Ihrer Anforderungsvorlage befolgen sollten, lautet:
{
  "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
      }
    }
  ]
}

Paginierungsunterstützung

Die Anforderungsstruktur unterstützt eine Reihe von Paginierungsmethoden, um zu verhindern, dass große Suchergebnisse zu einem übermäßigen Netzwerk-Traffix führen. Die folgenden Paginierungsmethoden werden unterstützt:
  • VERRECHNUNG
  • PAGE_INCREMENT
  • PAGE_TOKEN
Parameter für diese Methoden werden wie folgt beschrieben. Diese sollten der Anforderungsstruktur hinzugefügt werden.
Paginierungsunterstützung
Paginierungstyp Voraussetzung Konfiguration
VERRECHNUNG Die REST-API, die Sie in Oracle Access Governance integrieren, muss die OFFSET-Paginierung unterstützen, wenn Sie eine Antwort zurückgeben.

Wenn paginationType auf OFFSET gesetzt ist, müssen Sie der Outline die folgenden Parameterwerte hinzufügen:

"queryParameters": [
{"name": "startIndex", "value": "<EL>currentOffset</EL>"}
{"name": "count", "value": "<EL>limit</EL>"}
] 
PAGE_INCREMENT Die REST-API, die Sie in Oracle Access Governance integrieren, muss die PAGE_INCREMENT-Paginierung unterstützen, wenn Sie eine Antwort zurückgeben.

Wenn paginationType auf PAGE_INCREMENT gesetzt ist, müssen Sie der Outline die folgenden Parameterwerte hinzufügen:

"queryParameters": [
{"name": "currentPage", "value": "<EL>currentPage</EL>"}
{"name": "pageSize", "value": "<EL>pageSize</EL>"}
] 
PAGE_TOKEN Die REST-API, die Sie in Oracle Access Governance integrieren, muss die PAGE_TOKEN-Paginierung unterstützen, wenn Sie eine Antwort zurückgeben.

Wenn paginationType auf PAGE_TOKEN gesetzt ist, müssen Sie der Outline die folgenden Parameterwerte hinzufügen:

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

Der Name für einen bestimmten Paginierungsparameter kann je nach REST-API, mit der Sie eine Verbindung herstellen, variieren. Beispiel: Bei der OFFSET-Paginierung können die Parameter wie folgt lauten:
{"name": "startIndex", "value": "<EL>currentOffset</EL>"}
{"name": "count", "value": "<EL>limit</EL>"}
oder
{"name": "beginIndex", "value": "<EL>currentOffset</EL>"}
{"name": "increment", "value": "<EL>limit</EL>"}
Sie sollten den von Ihrer API angegebenen Namen verwenden, aber die Werte wie in diesem Artikel beschrieben verwenden.

Anforderungsvorlagenausgabe

Die Ausgabe der Anforderungsvorlage wird als JSON-Dokument für definierte Entitys und Vorgänge zurückgegeben.

Anforderungsvorlagenausgabe

Die Ausgabe der Anforderungsvorlage sieht ähnlich aus wie in der Referenzimplementierung (<ReferenceBase>/functions/grc-schema-template/src/main/resources/request/applications/<YourApplicationName>/<EntityName>/<Operation>_TEMPLATE.json):

Beispiel aus der Referenzimplementierung:

  • EntityName: UserAsIdentity
  • Vorgang: 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
  • Operation: SUCHEN
{
  "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>>"
    }
  ]
}

Antwortvorlagenstruktur

Um das Antwortformat für Identitäts- und Accountdaten zu unterstützen, müssen Sie Ihre Antwortvorlage mit der unterstützten Modellstruktur erstellen.

Antwortstruktur

Die Antwortstruktur, die Sie beim Erstellen der Antwortvorlage befolgen sollten, lautet:
{
  "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
        }
      ]
    }
  ]
}

Antwortvorlagenausgabe

Die Ausgabe der Antwortvorlage wird als JSON-Dokument für definierte Entitys und Vorgänge zurückgegeben.

Antwortvorlagenausgabe

Die Ausgabe der Antwortvorlage sieht ähnlich aus wie in der Referenzimplementierung (<ReferenceBase>/functions/grc-response-template/src/main/resources/response/applications/<YourApplicationName>/<EntityName>/<Operation>_TEMPLATE.json):

Beispiel aus der Referenzimplementierung:

  • EntityName: UserAsIdentity
  • Vorgang: 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
  • Operation: SUCHEN
{
  "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>"
    }
  ]
}

Basisautorisierung - Beispieltokenerstellungscode

Wenn Sie die Basisautorisierung mit Ihrem generischen REST-Orchestrierungssystem verwenden, müssen Sie ein Autorisierungstoken erstellen. Der folgende Beispielcode enthält ein Beispiel für das Codieren dieser Funktion:

Beispieltokenerstellungscode

Wenn Sie die Basisautorisierung mit Ihrem generischen REST-Orchestrierungssystem verwenden, müssen Sie ein Autorisierungstoken erstellen. Der folgende Beispielcode enthält ein Beispiel für das Codieren dieser Funktion:
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.

OAuth-Autorisierung - Beispiel-Tokenerstellungscode

Wenn Sie die Autorisierung OAuth mit Ihrem generischen REST-Orchestrierungssystem verwenden, müssen Sie ein Autorisierungstoken erstellen. Die folgenden Beispiele geben ein Beispiel für die Codierung dieser Funktion:

Beispieltokenerstellungscode

Für IDCS-orchestriertes System:

Dieser Code wird mit der Beispielimplementierung bereitgestellt, die mit dem generischen REST-Connector geliefert wird. Sie finden ihn unter <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());
  }
}

Für AzureAD orchestriertes System:

Dieser Code wird mit der Beispielimplementierung bereitgestellt, die mit dem generischen REST-Connector geliefert wird. Sie finden ihn unter <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();
  }
}