Oracle Identity Cloud ～ 認証からユーザー情報の参照までのシーケンス

# はじめに

Oracle Identity Cloud の Confidential Application で認証からユーザー/グループ情報の参照までに複数回リクエストを送る必要があり、備忘も兼ねて一連の処理シーケンスを整理してみました。

Python で書いたサンプル・コードはこちらにあります。

https://gist.github.com/tkote/efb0f6eb548091bf506caff5e422927a

ドキュメンテーションは、この辺りが参考になると思います。
[認証APIを使用したアクセス・トークンの生成](https://docs.oracle.com/cd/E83857_01/paas/identity-cloud/rest-api/generateacctokenusingauthn.html)


# 手順

## Step 0: OAuthアクセストークンを取得する
### [POST {{tenant_url}}/oauth2/v1/token](https://docs.oracle.com/en/cloud/paas/identity-cloud/rest-api/op-oauth2-v1-token-post.html)

[必要な入力]
client_id, client_secret

```python
url = idcs_url + '/oauth2/v1/token'
headers = {'content-type': 'application/x-www-form-urlencoded'}
payload = {'grant_type' : 'client_credentials', 'scope' : 'urn:opc:idm:__myscopes__'}
response = requests.post(url, data=urllib.parse.urlencode(payload), headers=headers, auth=(client_id, client_secret))
```

[後続の処理で使うもの]
access_token = response.json().get("access_token")

## Step 1: 認証フローを開始する
### [GET {{tenant_url}}/sso/v1/sdk/authenticate?appName={{appName}}](https://docs.oracle.com/en/cloud/paas/identity-cloud/rest-api/op-sso-v1-sdk-authenticate-get.html)

[必要な入力]
access_token, app_name

```python
url = idcs_url + '/sso/v1/sdk/authenticate'
headers = {'Authorization': 'Bearer ' + access_token}
paramas = {'appName' : app_name}
response = requests.get(url, headers=headers, params=paramas)
```
[後続の処理で使うもの]
request_state = response.json().get('requestState')

## Step 2: ユーザー資格証明(ID/PW)をサブミットする
### [POST {{tenant_url}}/sso/v1/sdk/authenticate](https://docs.oracle.com/en/cloud/paas/identity-cloud/rest-api/op-sso-v1-sdk-authenticate-post.html)

[必要な入力]
access_token, request_state, username, password

```python
url = idcs_url + '/sso/v1/sdk/authenticate'
headers = {'Authorization': 'Bearer ' + access_token}
payload = {
   'op': 'credSubmit',
   'credentials':{  
      'username' : username,
      'password' : password
   },
   'requestState' : request_state
}
paramas = {'appName' : app_name}
response = requests.post(url, headers=headers, json=payload)
```
[後続の処理で使うもの]
auth_token = response.json().get('authnToken')

## Step 3: ユーザのアクセス・トークンを取得する
### [POST {{tenant_url}}/oauth2/v1/token](https://docs.oracle.com/en/cloud/paas/identity-cloud/rest-api/op-oauth2-v1-token-post.html)

[必要な入力]
client_id, client_secret, auth_token

```python
url = idcs_url + '/oauth2/v1/token'
headers = {'content-type': 'application/x-www-form-urlencoded'}
payload = {
    'grant_type' : 'urn:ietf:params:oauth:grant-type:jwt-bearer', 
    'scope' : 'urn:opc:idm:__myscopes__',
    'assertion' : auth_token
}
response = requests.post(url, data=urllib.parse.urlencode(payload), headers=headers, auth=(client_id, client_secret))
```
[後続の処理で使うもの]
my_access_token = response.json().get("access_token")

## Step 4: ユーザ情報を取得する / ユーザが属するグループ情報を取得する
### [GET {{tenant_url}}/admin/v1/Me](https://docs.oracle.com/en/cloud/paas/identity-cloud/rest-api/api-self-service-me.html)

[必要な入力]
my_access_token

```python
url = idcs_url + '/admin/v1/Me'
headers = {'Authorization': 'Bearer ' + my_access_token}
response = requests.get(url, headers=headers)
```
### [GET {{tenant_url}}/admin/v1/MyGroups](https://docs.oracle.com/en/cloud/paas/identity-cloud/rest-api/api-my-access-my-groups.html)
```python
url = idcs_url + '/admin/v1/MyGroups'
headers = {'Authorization': 'Bearer ' + my_access_token}
response = requests.get(url, headers=headers)
```