Digest認証の確認環境、サーバ側とiOSクライアント環境
発端
teratailの「Alamofireでdigest認証について」という質問でした。今までhttps+Basic認証しかやったことがなく、Digest認証自体知りませんでした。また、開発効率を考えswiftでWebアクセスすると言えばAlamofireのみでしかやっていなかったので、もう少しコア技術についても知りたいという点もあり、実際に調査してみたのが発端で、その過程で確認環境などを構築したので、それを公開してしまおうという流れです。
一式
githubに以下の説明に利用したファイル一式をアップしています。説明で省いた詳細をご確認いただきたい方はご覧ください。
サーバ側
nginxはデフォルトではDigest認証に対応していない様で、手っ取り早くNode.jsで実装しようとしたけれど、Node.jsを普段使いしていないので、全く手っ取り早くできず断念。。最終的にApache2.4で構築することに。
細かな設定は、既に色々と情報があるのでそちらに任せますが(例えば)、ポイントだけ提示したいと思います。
httpd.conf
dockerイメージのhttpd:2.4を使いますが、httpd.confはそのイメージに含まれているものをコピーして必要な部分を追記修正しました。
conf/extraに追記分だけ入れたいところですが、デフォルトでIncludeされているのは、conf/extra/proxy-html.confだけだったので、影響範囲を最小限にするという意図で直接httpd.confを修正してしまっています。
# digest認証用のモジュールをロード
LoadModule auth_digest_module modules/mod_auth_digest.so
# 認証をかけたい場所(例として/digestとしている)に以下を設定
# さらに例としてhttpd.confに記載しているが、もちろん.htaccessでも良い
<Location /digest>
AuthType Digest
AuthName "private Web"
AuthUserFile "/usr/local/apache2/conf/.htdigest"
Require valid-user
</Location>
LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Authorization}i\"" combined
Logフォーマット
発端となったDigest認証時のalgorithmがどの様に設定されているのかを表示させるため、LogFormatでAuthorizationヘッダを表示する様にしています。
docker
基本は上記のhttpd.confを読み込ませる様にする、そして認証するためのディレクトリを公開します。
./auth -> /usr/local/apache2/conf
./webroot -> /usr/local/apache2/htdocs
.htdigest
サーバ側で認証する際のユーザとパスワードを管理するファイルになります、名前はなんでもよく、前述したconfのAuthUserFileで指定したものになります。
Basic認証ではhtpasswdを利用することと同様にDigest認証でもhtdigestコマンドがあり、それを利用すれば良いのだけれど、自動化する際にはhtpasswdより使い勝手が悪いです。
htdigest -c .htdigest [[AuthName]] USERNAME
パスワードを標準入力から設定する必要があることと、結果に不要なデータ(’ー’)が含まれていたりします。
また、今回の環境作成では可能な限りシンプルに構築したかったので、別の方法を採用しています。結局MD5でハッシュしたものとのことと、環境依存性も考慮し、docker内で行いました。
docker-compose
最終的に、上記の様な環境を構築するためにdocker-composeを利用しました。そのymlを以下に提示します。
version: "2"
services:
digest:
image: "httpd:2.4"
environment:
- HTTPD_DIGEST_PASS=pass
- HTTPD_DIGEST_USER=admin
- HTTPD_DIGEST_NAME=private Web
volumes:
- conf:/usr/local/apache2/conf
- web:/usr/local/apache2/htdocs
command: >
bash -c 'echo -n $$HTTPD_DIGEST_USER:$$HTTPD_DIGEST_NAME:>conf/.htdigest &&
echo -n $$HTTPD_DIGEST_USER:$$HTTPD_DIGEST_NAME:$$HTTPD_DIGEST_PASS|md5sum -|cut -f 1 -d " ">>conf/.htdigest
'
apache:
image: "httpd:2.4"
hostname: mobilework.kddilabs.jp
ports:
- 8888:8888
volumes:
- conf:/usr/local/apache2/conf
- web:/usr/local/apache2/htdocs
depends_on:
- digest
volumes:
conf:
driver_opts:
type: none
device: $PWD/auth
o: bind
web:
driver_opts:
type: none
device: $PWD/webroot
o: bind
最初のdigestで.htdigestを生成、apacheでhttpサーバ用インスタンスを起動します。
一応正常にサーバ側が構築できたのかを確認するためにcurlを利用します。
curl -v --digest -u admin:pass http://localhost:8888/digest/
上記のコマンドでwebroot/digest/index.htmlに置いたindex.htmlの内容が表示されたらOKとなります。うまく動作しない場合には、標準出力に表示されたログを参照するとか、webroot/error内容を確認すると良いでしょう。
クライアント側
swiftでの実装ですが、基本はAppleのマニュアルFetching Website Data into Memoryを参考にしています。
Completion HandlerとDelegateを利用する2種類の方法があるが、今回詳細な状況を把握するためにDelegateを利用しました。URLSessionDataDelegateとURLSessionTaskDelegateの二つで良いようです。
今回のポイントとして、認証時に呼び出されるurlSession(_:task:didReceive:completionHandler:)が重要となります。
func urlSession(_ session: URLSession, task: URLSessionTask, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) {
print(#file, #function, #line, separator:":")
print("authentication method: ", challenge.protectionSpace.authenticationMethod)
print("protection space , host: ", challenge.protectionSpace.host)
let cnt = challenge.previousFailureCount
print("previous failure count: ", cnt)
guard cnt == 0 else {
completionHandler(.cancelAuthenticationChallenge, nil)
return
}
let cred = URLCredential(user: "admin", password: "pass", persistence: .forSession)
completionHandler(.useCredential, cred)
}
URLCredentialのインスタンス生成時に引き渡すユーザ・パスワードを.htdigest作成時と一致させることになります。
クライアント側は短いですがこれだけ。ソースを見るのが一番ですね。
Author And Source
この問題について(Digest認証の確認環境、サーバ側とiOSクライアント環境), 我々は、より多くの情報をここで見つけました https://qiita.com/to_obara/items/3cdac7d650abede20b36著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .