汎用REST参照
Generic REST Orchestrated Systemは、最小限のテンプレートで作成されます。このテンプレートは、OCI Functionsを使用して実行時に更新され、オブジェクト・クラス、参照タイプおよびアウトバウンド変換データでオーケストレート済システムを更新します。
スキーマ検出の高度なワークフロー
スキーマ検出とは、Generic REST Orchestrated SystemがOCI関数テンプレートを適用して、構成された認可ソースまたは管理対象システムのスキーマ、オブジェクト・クラス、属性および接続詳細の検出を有効にするプロセスです。
スキーマ検出は、Oracle Access Governanceでオーケストレート済システムが作成されたときに発生します。次の表に、Day0およびDayNシナリオの簡略化されたワークフローを示します。
Day0ワークフロー
| ステップ番号 | タスク/操作 | 説明 |
|---|---|---|
| 1 | オーケストレート済システムの作成 |
Oracle Access Governanceコンソールを使用して、オーケストレート済システムを作成します。 オーケストレート済システムは、必要な認可ソースまたは管理対象システムから詳細を戻すために作成したOCI関数の詳細とともに作成されます。 オーケストレート済システムに入力された詳細に基づいて、次の操作が作成されます。
|
| 2 | 操作実行の検証 |
検証操作が実行され、構成済のスキーマ・テンプレートに基づいて、次のオブジェクト・クラスを含むスキーマがフェッチされます。
構成テスト・テンプレートは、管理対象システムとの接続を検証するためにコールされます。 |
| 3 | 検証後操作 |
検証操作が正常に実行されると、次の操作が作成されます。
|
DayNワークフロー
| ステップ番号 | タスク/操作 | 説明 |
|---|---|---|
| 1 | Oracle Access Governanceの「アイデンティティ属性」ページから「属性のフェッチ」を選択します。詳細は、最新のカスタム属性のフェッチを参照してください。 | スキーマ検出操作がオーケストレート済システムに作成されます |
| 2 | スキーマ検出操作の実行 | スキーマ検出操作が実行され、構成済のスキーマ・テンプレートに基づいて、次のオブジェクト・クラスを含むスキーマがフェッチされます。
|
| 3 | アイデンティティ属性ページをリフレッシュします | カスタム属性リストでは、アイデンティティ・オブジェクト・クラスの新しいカスタム属性の表示が開始されます。 |
汎用RESTスキーマ検出必須スキーマ属性
スキーマ検出中に、特定の必須属性をスキーマ出力の一部として返す必要があります。
IDオブジェクトクラス
Identityオブジェクト・クラスのスキーマ出力の一部として返す必要がある必須属性は、次のとおりです。
- uid
- 名前
- Eメール
- firstName
- middleName
- lastName
- displayName
- employeeType
- タイトル
- empNo
- ステータス
- jobCode
- 国家
- リスク
- 場所
- 部門
- managerUid
- managerLogin
- organizationUid
- organizationName
- 国
- 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"
]
}
]
アイデンティティ以外のオブジェクト・クラス
Non-Identityオブジェクト・クラスのスキーマ出力の一部として返す必要がある必須属性は、次のとおりです。
- uid
- 名前
[
{
"name": "uid",
"dataType": "TEXT",
"nature": [
"REQUIRED"
],
"usage": [
"READ"
]
},
{
"name": "name",
"dataType": "TEXT",
"nature": [
"REQUIRED"
],
"usage": [
"READ"
]
}
]
スキーマ・テンプレート・アウトライン
スキーマ検出をサポートするには、サポートされているアウトラインを使用してスキーマ・テンプレートを作成する必要があります。
スキーマ・アウトライン
{
"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
]
}
}
]
}
]
}
スキーマ・テンプレート出力
スキーマ・テンプレートの出力は、JSONドキュメントとして返されます。
スキーマ・テンプレート出力
<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"
]
}
]
}
]
}
リクエスト・テンプレート・アウトライン
必要な認可ソースまたは管理対象システムへのリクエストをサポートするには、サポートされているアウトラインを使用してリクエスト・テンプレートを作成する必要があります。
リクエスト・アウトライン
{
"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
}
}
]
}
ページ区切りサポート
- オフセット
- PAGE_INCREMENT
- PAGE_TOKEN
| ページ区切りタイプ | 前提条件 | 構成 |
|---|---|---|
| オフセット | Oracle Access Governanceと統合するREST APIは、レスポンスを返すときにOFFSETページ区切りをサポートする必要があります。 |
|
| PAGE_INCREMENT | Oracle Access Governanceと統合するREST APIでは、レスポンスを返すときにPAGE_INCREMENTページ区切りをサポートする必要があります。 |
|
| PAGE_TOKEN | Oracle Access Governanceと統合するREST APIでは、レスポンスを返すときにPAGE_TOKENページ区切りをサポートする必要があります。 |
|
特定のページ区切りパラメータの名前は、接続しているREST APIによって異なる場合があります。たとえば、OFFSETページ区切りの場合、パラメータは次のようになります。
{"name": "startIndex", "value": "<EL>currentOffset</EL>"}
{"name": "count", "value": "<EL>limit</EL>"}または{"name": "beginIndex", "value": "<EL>currentOffset</EL>"}
{"name": "increment", "value": "<EL>limit</EL>"}
APIで指定されている名前を使用する必要がありますが、この記事で説明するように値を使用してください。リクエスト・テンプレート出力
リクエスト・テンプレートの出力は、定義されたエンティティおよび操作のJSONドキュメントとして返されます。
リクエスト・テンプレート出力
リクエスト・テンプレートの出力は、リファレンス実装(<ReferenceBase>/functions/grc-schema-template/src/main/resources/request/applications/<YourApplicationName>/<EntityName>/<Operation>_TEMPLATE.json)に用意されているものと似ています。
たとえば、リファレンス実装から次のようにします。
- EntityName: UserAsIdentity
- 操作: 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
- 操作: 検索
{
"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>>"
}
]
}
レスポンス・テンプレート・アウトライン
アイデンティティおよびアカウント・データのレスポンス・フォーマットをサポートするには、サポートされているアウトラインを使用してレスポンス・テンプレートを作成する必要があります。
応答概要
{
"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
}
]
}
]
}
応答テンプレート出力
レスポンス・テンプレートの出力は、定義されたエンティティおよび操作のJSONドキュメントとして返されます。
応答テンプレート出力
レスポンス・テンプレートの出力は、リファレンス実装(<ReferenceBase>/functions/grc-response-template/src/main/resources/response/applications/<YourApplicationName>/<EntityName>/<Operation>_TEMPLATE.json)に用意されているものと似ています。
たとえば、リファレンス実装から次のようにします。
- EntityName: UserAsIdentity
- 操作: 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
- 操作: 検索
{
"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>"
}
]
}
Basic認可- サンプル・トークン作成コード
Generic RESTオーケストレート済システムで基本認可を使用する場合は、認可トークンを作成する必要があります。次のサンプル・コードは、この関数のコーディング方法の例を示しています。
サンプル・トークン作成コード
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認可- サンプル・トークン作成コード
Generic RESTオーケストレート済システムでOAuth認可を使用する場合は、認可トークンを作成する必要があります。次に、この関数のコーディング方法の例を示します。
サンプル・トークン作成コード
IDCSオーケストレート済システムの場合:
<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());
}
}
AzureADオーケストレート済システムの場合:
<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();
}
}