Azure App Service 認証のサイトに Curl でアクセスしてみた

Azure App Service 認証で、簡単に社内ユーザーに限定したサイトができるので大変便利です。便利な反面、プログラムから Azure App Service 認証のサイトにアクセスする場合は、どうするんだろうとなります。試しに Curl でアクセスしてみました。

## 検証用 App Service を作成

```bash:bash
region=japaneast
prefix=mnreasyauth

az group create \
  --name ${prefix}-rg \
  --location $region

az appservice plan create \
  --name ${prefix}-plan \
  --resource-group ${prefix}-rg \
  --is-linux \
  --sku F1

az webapp create \
  --name ${prefix} \
  --resource-group ${prefix}-rg \
  --plan ${prefix}-plan \
  --runtime "PHP|8.2"
```

## 認証がない状態で Curl からアクセス

```bash:bash
$ curl -i https://${prefix}.azurewebsites.net
HTTP/2 200
```

## App Service 認証を設定

![appservice-easyauth-appclient-01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/675885/3ff4fb55-3e55-9f44-778c-0e41c33d5ebb.png)

![appservice-easyauth-appclient-02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/675885/81685d49-58a0-3590-9c65-541aa8819f03.png)

![appservice-easyauth-appclient-03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/675885/a59aa522-7b5b-badf-3d4d-e14db366712e.png)

## 認証がある状態で Curl からアクセス

```bash:bash
$ curl -i https://${prefix}.azurewebsites.net
HTTP/2 401
```

## Curl 用のアプリ登録とトークン取得に必要な情報を変数にセット

```bash:bash
appid=$(az ad app create \
  --display-name ${prefix}-client \
  --query appId \
  --output tsv)

apppw=$(az ad app credential reset \
  --id $appid \
  --append \
  --display-name ${prefix} \
  --years 10 \
  --query password \
  --output tsv)

tenantid=$(az account show \
  --query tenantId \
  --output tsv)

targetid=$(az webapp auth show \
  --name ${prefix} \
  --resource-group ${prefix}-rg \
  --query properties.identityProviders.azureActiveDirectory.registration.clientId \
  --output tsv)
```

## アクセストークンを取得して Curl でアクセス

401 が 403 に変化しました。

```bash:bash
token=$(curl -s "https://login.microsoftonline.com/$tenantid/oauth2/v2.0/token" \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "client_id=$appid" \
  -d "scope=$targetid/.default" \
  -d "client_secret=$apppw" \
  -d "grant_type=client_credentials" \
  | jq -r .access_token)

curl -i https://${prefix}.azurewebsites.net \
  -H "Authorization: Bearer $token"
HTTP/2 403
```

## App Service 認証でアプリからのアクセスを許可

![appservice-easyauth-appclient-04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/675885/c61ec204-36f0-6e2f-5bf1-dac6850df097.png)

![appservice-easyauth-appclient-05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/675885/c17d0e1e-6661-e316-20be-6727e6a069f9.png)

Client application requirement を Allow request from any application に変更して保存します。

## もう一度アクセストークンを取得して Curl でアクセス

200 になりました。

```bash:bash
token=$(curl -s "https://login.microsoftonline.com/$tenantid/oauth2/v2.0/token" \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "client_id=$appid" \
  -d "scope=$targetid/.default" \
  -d "client_secret=$apppw" \
  -d "grant_type=client_credentials" \
  | jq -r .access_token)

curl -i https://${prefix}.azurewebsites.net \
  -H "Authorization: Bearer $token"
HTTP/2 200
```

## 後片付け

```bash:bash
az group delete \
  --name ${prefix}-rg \
  --yes

az ad app delete --id $appid

az ad sp delete --id $targetid
```

## 参考

https://learn.microsoft.com/ja-jp/azure/app-service/configure-authentication-provider-aad?tabs=workforce-tenant#daemon-client-application-service-to-service-calls

https://learn.microsoft.com/ja-jp/entra/identity-platform/v2-oauth2-client-creds-grant-flow#first-case-access-token-request-with-a-shared-secret