App Service にて Basic 認証機能の実装や設定をする

# はじめに
App Service にて Azure AD を用いた認証方法ではなく簡単な認証を設定したいことから Basic 認証は設定することが出来ないかという疑問からスタートしました。本記事では App Service を利用して Basic 認証を設定する方法をご紹介して参ります。

# App Service の Basic 認証について
App Service の Web Apps を使用することで Basic 認証機能の実現を行うことができることが分かりました。しかしながら、App Service プラットフォームそのものには組込みの Basic 認証モジュールの提供はしておりませんでした。App Service で Basic 認証を実現する方法として、下記 2 種類の方法がございます。

1. アプリケーション内にて第三者モジュールなどを使用して、独自にて実装をする
2. web.config や Nginx の default ファイルにて疑似的に Basic 認証と同等の動作を制御する

1.に関しましては、アプリケーション内にて独自でモジュールを選定いただくものとなりますので、本記事では、2.の方法について検証をしていきます。


## （Windows 版）web.config ファイルを利用した Basic 認証
App Service の Windows 版を使用した際には Web サーバが IIS が使用されます。IIS は web.config ファイルを読み込みことができ、制御する方法として rewrite を利用することで実現できます。
今回検証環境にて Basic 認証を実施するパスと OS、ランタイムスタックは以下の条件といたします。
```
例) 特定のURL配下の認証
OS : Windows
ランタイム スタック : .NET 6 (Webサーバー : IIS)
```

1） 高度なツール（Kudu）よりディレクトリを下記の通り構成する

* 一般ユーザーのアクセスを想定（認証しない）
  * ファイル : /home/site/wwwroot/ hostingstart.html
  * アクセスする際の URL : https:// App Service 名.azurewebsites.net （デフォルトのURL）
  * <App Service 名>.azurewebsites.net はカスタムドメインであっても問題ございません。
 
* 管理ユーザーのアクセスを想定（認証する）
  * ファイル : /home/site/wwwroot/admin/admin.html
  * アクセスする際の URL : https:// App Service 名.azurewebsites.net/admin/admin.html
  * <App Service 名>.azurewebsites.net はカスタムドメインであっても問題ございません。


2）`/home/site/wwwroot/` 配下の web.config へ下記を追記する
web.config 内に記載の <Base64 でエンコードした[ユーザ名:パスワード]> は、あらかじめユーザ名とパスワードを Base64 へエンコードした値として記載していただくことが必要となります。例えば、ユーザ名を admin としてパスワードを admin とした場合には、admin:admin の Base 64 エンコードとなるため、YWRtaW46YWRtaW4= となります。

### web.config 追記例:
```
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <system.webServer>
        <rewrite>
            <rules>
                <rule name="BasicAuthOK" stopProcessing="true">
                    <match url="^admin/.*$" />
                    <conditions>
                        <add input="{HTTP_Authorization}" pattern="Basic <Base64 でエンコードした[ユーザ名:パスワード]>" />
                    </conditions>
                    <action type="None" />
                </rule>
                <rule name="BasicAuthNG" stopProcessing="true">
                    <match url="^admin/.*$" />
                    <serverVariables>
                        <set name="RESPONSE_WWW-Authenticate" value="Basic Realm=SecretZone" replace="true"/>
                    </serverVariables>
                    <action type="CustomResponse" statusCode="401" />
                </rule>   
            </rules>    
        </rewrite>
  </system.webServer>
</configuration>
```

3）アクセスを試みる
`https:// <App Service 名>.azurewebsites.net` へのアクセスでは Basic 認証は要求されませんが、`https:// <App Service 名>.azurewebsites.net/admin/admin.html` へアクセスが行われると、Basic 認証が要求され、`web.config` にて設定した ID とパスワードを入力する事でアクセスができます。
尚、`match url` の値を `<match url=".*" />` と記載する事により、`https://<App Service 名>.azurewebsites.net/` のサイト全体に認証が適用させることも可能でございます。

**https:// <App Service 名>.azurewebsites.net へのアクセス**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/149402/e5a07135-c1ce-84be-2ded-732c15758590.png)

**https:// <App Service 名>.azurewebsites.net/admin/admin.html へのアクセス**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/149402/6f8bf4bc-10b9-d0cd-4391-103ee15e8c04.png)

---

## （Linux 版）Nginx の default ファイルを利用した Basic 認証
App Service on Linux にて Basic 認証を実施するには Nginx が事前に入っているランタイムスタックで設定が可能となります。Nginx があらかじめ入っているランタイムスタックは `PHP 8.x` からとなります。Nginx のカスタマイズ方法につきまして以下のブログの関連記事をご覧ください。
[PHP 8.X で Nginx の設定をカスタマイズする方法](https://jpazpaas.github.io/blog/2023/04/13/Customize-Nginx-On-PHP-8.X.html)

今回検証環境にて Basic 認証を実施するパスと OS、ランタイムスタックは以下の条件といたします。
```
例) ルートのURL配下の認証
OS : Linux
ランタイム スタック : PHP 8.2 (Webサーバー : Nginx)
```

1） Basic認証用の「. htpasswd」 コマンドを利用するため、下記のパッケージをインストールする
```
apt-get install apache2-utils
```

**apache2-utils のインストール状況**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/149402/84efc575-5787-107e-617a-73c4f1568bfe.png)

2） 以下のコマンドで、/.htpasswdファイルのパスを/home/.htpasswd に指定し、ユーザー名とパスワードを追加する
<任意のユーザー名> では Basic 認証に必要なユーザ名として入力を行い、その後新しいパスワードを対話型での登録となります。
```
htpasswd -c /home/.htpasswd <任意のユーザー名>
```

**ユーザ名とパスワードの設定**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/149402/fea36944-164c-994b-077f-e97283402c7a.png)

3）Nginx の default ファイルを /home/defaultファイルをコピー
cp コマンドを用いて nginx で動作している default ファイルを /home ディレクトリへコピーします。
```
cp /etc/nginx/sites-enabled/default /home/default
```

4）/home/default ファイルを編集する
vi /home/default コマンドを実行し、i キーを入力してファイルを編集します。
以下のように　Basic 認証を実施する auth_basic_user_file のパスを /home/.htpasswd にします。
```
auth_basic "Restricted";
auth_basic_user_file /home/.htpasswd;
```

**/home/default ファイルの内容**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/149402/296a4501-4a9f-9888-d046-7dfee6d19b21.png)


5）スタートアップコマンドより再起動後も Basic 認証 が行われるように設定する
以下のコマンドを用いて Basic 認証を設定した default ファイルを nginx 側へコピーを行い nginx の再起動コマンドをスタートアップコマンドへ記載します。
```
cp /home/default /etc/nginx/sites-enabled/default; service nginx restart
```

**スタートアップコマンドの設定**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/149402/9f6169aa-f438-8623-29d4-81c1b3dd9b49.png)


6）対象 App Serviceの「概要」メニューよりアプリケーションの再起動とアクセスを試みる
App Service を再起動後に `https:// <App Service 名>.azurewebsites.net` へのアクセスを試みると Basic 認証が要求されます。2. で設定したユーザ名とパスワードを入力することでアプリケーション内のコンテンツを閲覧することができます。

**https:// <App Service 名>.azurewebsites.net へのアクセス**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/149402/ee779dd3-0b4a-3ff2-e6c3-cb0fbfc0526c.png)