Basic認証をGo言語で実装して挙動を理解する

HTTPに定義されている認証であるBasic認証について概要を調べ、ちょっとさわってみたので、それの紹介をします。

Basic認証とは

Basic認証とは、ユーザー名とパスワードの組み合わせによる、とてもシンプルな認証方式です。
簡易的で、基本的なシステムなので、多くのサーバーやブラウザに対応しており、環境を問わず利用できるメリットがあります。

動作手順

  1. クライアントがサーバーにリクエストを送る
  2. サーバーが401レスポンスコードを返す
  3. クライアントが認証領域をユーザーに提示し、ユーザー名、パスワードの入力を求める
  4. 入力されると、クライアントはリクエストに認証ヘッダを追加して再び送信する
  5. 認証が合っていれば、リクエストを処理し、間違っていれば再び401レスポンスコードを返す

実際に試してみる

では、golangで実装したサーバーとcurlコマンドでこのBasic認証を触りながら理解していきます。

上記のコードを「basic.go」などのファイル名で保存して、$ go run basic.goでサーバーを立ち上げます。

少しコードの解説をすると、ユーザー名と、パスワードが一緒に送られてきたかどうかや、それが設定しているものと一致しているかどうかを判断し、それによって401を返したり、認証がうまく行った場合のページを表示したりしています。

ユーザー名は「user」、パスワードは「pass」とし、ポート番号を18888番にセットしています。

詳しくは後述しますが、コード内で標準ライブラリのBasicAuth()メソッドを用いています。

リクエストを送る

ではさっそく、普通にリクエストを送ってみますが、このときユーザーは認証が必要だということを知らない状態です。

別のシェルを開き、curlコマンドを使って、このサーバーにリクエストを送ってみます。
-vオプションを付けることで、詳細が見れます。

$ curl -v http://localhost:18888/basic

すると、こんな感じのログが表示されました。

行頭が「>」になっている行がリクエストで、「<」になっている部分がレスポンスです。

レスポンスの1行目のステータスラインを見てみると、「401 Unauthorized」とあるので、認証が必要だということがわかります。

ヘッダには「WWW-Authenticate: Basic realm=”my private area”」とあるので、Basic認証ありのページだということがわかります。

realmは認証領域という意味で、サイト上のリソースのコレクションを識別するために付けられています。
普通は、同じrealmには、id/passの再入力を求めないように実装されています。

ヘッダをセットして再送信する

 先ほどのレスポンスを受け取ったら、クライアントはAuthorizationヘッダを付けて再送信します。

Authorizationヘッダはこのようなものです。
Authorization: Basic dXNlcjpwYXNzCg==

Basic以下の文字列は、ユーザー名とパスワードをコロンで接続した文字列をbase64エンコーディングしたものです。

ここでは、ユーザー名が「user」、パスワードが「pass」なので、「user:pass」とし、これをbase64エンコーディングします。

opensslを使えば端末上でもエンコーディングできます。
$ echo "user:pass" | openssl base64
dXNlcjpwYXNzCg==

これを、ヘッダにセットしてリクエストを送ってみます。
curlコマンドでは、-uオプションを付けることで、ユーザー名とパスワードを送信できます。

--basicオプションでBasic認証方式を扱えますが、デフォルトがBasic認証なので付けても付けなくも同じ結果になります。

$ curl -v -u user:pass http://localhost:18888/basic

上手く認証されましたね。

一つ注意点なのはこのbase64エンコーディングは可逆変換であるということです。
つまり、簡単にデコードし「user:pass」という文字列を復元できます。
$ echo "dXNlcjpwYXNzCg==" | openssl enc -d -base64
user:pass

ですので、これは平文をそのまま送信しているのとほぼ同じで、セキュリティ的にはガバガバです。

ちなみに、golangコード内BasicAuth()の実装コードを少し覗いてみます。

コードはこちら

内部で使われている関数の中でbase64エンコーディングしているのがわかるかと思います。

 

以上、Basic認証について見てきました。
次の記事ではDigest認証について見ていきます。

 

参考