AzureResourceをRestで操作しようとして詰まった話

#AzureAPIManagerにRestでGroupを追加する

**今回使用する環境**

1. Azure
2. Advanced REST client (chorome拡張機能)

※この記事は2019年6月17日に記載しました。

**詰まった経緯**
　マイクロサービスを使用するユーザーをAzureAPIManagerのUserで管理しようと
　試みた。下記資料を参考にプログラムからRESTで通信をしたところ
　HTTP要求がRejectされた。[MicrosoftDocs(AzureAPI)](https://docs.microsoft.com/ja-jp/rest/api/apimanagement/)

**詰まった原因**
　[AzureRestAPIReferenceの最初のページ](https://docs.microsoft.com/ja-jp/rest/api/azure/)を読みとばしていた(以下画像)
　→　APIManagerを操作するためのREST内容ばかりよんでいた…:joy:

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/439931/22a1ada3-321a-77fc-ca31-bcb02df8522c.png)




##操作内容

1. AAD(AzureActiveDirectory)にアプリの登録
2. 登録したアプリでトークンを許可
3. 登録したアプリにAPIManagerを管理するRoleを割り当てる
4. Advanced REST Client に取得したTOKENを載せて、APIManagerを操作する通信を送りこむ

---
####1. AAD(AzureActiveDirectory)にアプリを登録する
　**※まず、前提としてAADでアプリ登録に関連する操作の為には管理者権限が必要です。**
　**一部の操作ができない場合、その多くは権限の問題であることが多いです。**

最初にAADを表示します。
Azureにアクセスし、Portal画面左のメニューバーからAzureActiveDirectoryを選びます。
下の画像でいうと、下から三つ目がAADです。
　<img width="125" alt="無題.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/439931/5b4e089e-7958-3d5b-5f55-606d094eec92.png">

AADにアプリを登録する理由は[MSDN](https://docs.microsoft.com/ja-jp/azure/active-directory/develop/app-objects-and-service-principals)に記載されています。
基本的には、プログラムからAzureResourceを操作するためにAzureのGetewayである
AADにアプリを登録しておく程度の理解で大きな問題は起きません。


次に、AADのApp registrationsを選択し、新規登録を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/439931/1ad08fd1-0e15-eacd-264c-e3b246f806f7.png)


登録画面がでてくるので、スコープとトークンの返答先を以下の画像の通り登録します。
[各登録内容の詳細はこちら](https://docs.microsoft.com/ja-jp/graph/auth-register-app-v2)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/439931/de14ac86-6a13-a44b-42f1-1540d34eb6e0.png)


####2. 登録したアプリでトークンから取得することを許可

アプリの登録が完了したので、認証の通信をおこなった後トークンが取得できるように設定をしていきます。
[AAD] > [App Registration] > [登録したアプリ(testRegistration)]
を選択し、サイドバーに表示されている認証を選択し、アクセストークンにチェックを入れて保存します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/439931/c97a1abe-2d20-ebee-c9f7-3bdc9c6fec4c.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/439931/09b88536-13f5-e9d5-5341-a76acbda3275.png)

これで、認証成功時にアクセストークンがレスポンスされるようになりました。


####3. 登録したアプリにAPIManagerを管理するRoleを割り当てる


次に、取得したアクセストークンでAzureAPIManagementを操作できるように認可の設定をしていきます。
具体的にはRoleを割り当てます。

以下の通り進みます。
[すべてのサービス]　＞　[サブスクリプション]
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/439931/f295f8b8-59f7-3ac5-f8a5-056f0f4019ca.png)

サブスクリプションを選択して、サイドバーの　[アクセス制御(IAM)]　 を選択。
そこでAddします。
今回は、AzureAPIManagement　を管理するRoleのみを割り当てたいため、__API Management Service Contributor__を選択します。
割り当てるのは先ほど作成したアプリ(testRegistration)です。


####4. Advanced REST Client に取得したTOKENを載せて、APIManagerを操作する通信を送りこむ

今までの手順で認証に必要な資材が整いました。
ここからは、HTTPでAzureのGateway(AAD)からアクセストークンを取得するために必要な情報を揃えていきます。

必要なものは３つです。
ここの名前が本当にわかりずらいです。混乱しやすいので軽くまとめてみました。

1.ClientId　：　AADで登録したアプリの　ApplicationID
2.ClientSecret　：　AADで登録する(あとで説明)
3.TenantId　：　ディレクトリID

いや、なんで名前こんな違うねん…まじで:kissing:

それぞれの取得方法
ClientID　＆　TenantedId
　：[AAD] > [App Registrations] > [登録したアプリ] > [概要(overview)]
　　左側をみれば、アプリケーションIDとテナントIDの記載があり、文字列が表示されています。
　　取得してください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/439931/00d37cfa-5838-a86d-3a78-9b9d6ea44468.png)


ClientSecret
　：[AAD] > [App Registrations] > [登録したアプリ] > [証明書とシークレット]
　　ここでクライアントシークレットで、新しいクライアントシークレットを選択。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/439931/e6f6728b-abf5-2c08-11fb-d3b16449263b.png)



　　説明とシークレットの有効期限を選択して追加。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/439931/979dd034-8180-800f-8e80-ef823fe73d8e.png)

　　追加を選択するとクライアントシークレットに新しい列が追加されます。
　　この時しか表示されないので、確実に保存してください。(黄色い部分)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/439931/2a2bb837-64ab-c20b-c1fb-ec5997378df9.png)


これで、トークンを取得するために必要な情報がそろいました。
ではRequestURIですが、[AAD] > [App Registrations] > [登録したアプリ]　から取得します。
アプリを選択して、エンドポイントを参照してください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/439931/1aa94fa8-317e-31d4-a2f9-a6a05e3072f1.png)

今回は
　https://login.microsoftonline.com/[tenantedId]/oauth2/token
を使用します。
(上記エンドポイントから取得するとテナントIDは自動で入力されています)

Token取得用のPostRequest
ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー　
【Header】
  Content-Type : application/x-www-form-urlencoded

【Body】
  grant_type : client_credentials
  resource : https://management.core.windows.net/
  client_id : [client_id]
  client_secret : [client_secret]
ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー
※今回はAzure操作をしたいのでresourceにhttps://management.core.windows.net/を入力


PostRequest　を以下の通り入力していきます。
HeaderとBodyの入力が完了したら、Sendします。
正確に入力できていれば、Httpstatus200が返却され、access_tokenが返ってきているはずです。
※Bodyを自動的にエンコードしてくれないツールを使用する場合はBodyを以下のように記載ください。
ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー
grant_type=client_credentials
&resource=https://management.core.windows.net/
&client_id=[client_id]
&client_secret=[client_secret]
ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/439931/590cdc49-ac7b-77a7-3d83-f6956a89c33a.png)
<img width="766" alt="無題.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/439931/7531617d-b8da-8b97-6859-673928942ccb.png">


次に、取得したアクセストークンを基にAzureResourceを操作します。
今回はAzureAPIManagementにGroupを追加します。
以下の手順に従って、Requestを作成します。

ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー
URI
　https://management.azure.com/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.ApiManagement/service/{serviceName}/groups/{groupId}?api-version=2019-01-01

Header
　Authorization　：　Bearer [access_token]

Body
 properties.displayName　：　グループ名を書く
 properties.description　：　適当にグループの説明を書く
ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー
※BodyをJsonにする場合以下の通り記載ください。
{
 "properties.displayName":"グループ名"
 ,"properties.description":"テスト用のグループです"
}
　
上記の通り、通信内容を記載するとAPIManagementにGroupが追加されるのを確認できるはずです。
※この際、HeaderでAuthorizationの値でAccess_tokenを記載するまえに**「Bearer」**と入力するのを忘れると認証できません。はまっている人が多いので注意です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/439931/7a6dc6cd-a70f-fe71-78ac-911649cc0b3a.png)


以上、RestでAPIManagementを操作する方法でした。
WebAppsから操作したい場合、ほかの設定が必要なのでDOCSを確認してください。
また、今回コードからトークンを取得しませんでしたが、公式てきには先にコードを取得する必要があります。
これも、DOCSを確認してください。