システム開発で思うところ

Javaで主にシステム開発をしながら思うところをツラツラを綴る。主に自分向けのメモ。EE関連の情報が少なく自分自身がそういう情報があったら良いなぁということで他の人の参考になれば幸い

ログインユーザーの管理

ログインしたユーザー情報を管理するにあたって必要そうなことの整理。

順不同で、あれこれ。

各種部品を作ったりするための整理。

EEとかSpringの認証ライブラリは?

とりあえず、各種ライブラリを 使わないで 自前のForm認証から試してみようかと考えています。
今回のテーマは、認証認可をするための仕組み というよりも、ログイン後の権限に対する仕組み を考えてみようと思っているからです。

イントラネット(プライベート)だったら 自前のものや、Firewallの後ろだからBasic認証でも良いかなと思うし、インターネット(パブリック)だったら、自前でログインによる認証・認可を管理するよりも Googleとかのサービスを使うことになると思っています。
つまり、仕組みとして注力するのは ライフサイクルや アクセス権限のことを考える方を優先した方が良いかな?と。

名前付け

ログインユーザーとか、セッションユーザーとか、そんな感じ。
操作者の情報という意味を鑑みて「ClientAgent」にしようと思っています。

ライフサイクル

Scopedアノテーションを付与したクラスと 振る舞いを行うクラスは別にして、ライフサイクルだけを管理するものにしておく。

今回はセッションスコープ

リクエストスコープにして、都度 永続化情報やキャッシュへ問い合わせるというやり方もあると思います。
(可用性の高い仕組みを設けたい場合は、こっちかな?)
アクセスキーは、ログインIDか、そこから生成したハッシュ値を使うイメージ。

ログアウト

もしくは、セッション破棄。
これはクライアントが関係するので、JavaScript による close をトリガーとして サーバーサイドの操作をします。

セッションハイジャック対策

ログインしたところで、セッションIDを書き換えます。
自前のForm認証じゃない場合でも、使えるような仕組みにしたいところですが、そのためには Basic認証とか コンテナによる認証機構を使うとか、そのあたりも調べないといけないので 後回しにするかも。

パスワードのハッシュ化

生パスワードでチェックをするのではなく、ハッシュ化したもので判定をする。
SALTとか使って云々をするところとか、そのあたりもかな。
一応、自前のForm認証用のUtilityとして作るところを最低限と言う感じかなぁ。
この機能は ユーザー登録みたいなところでも使えるような可搬性も踏まえた作りにしておきたいところ。

認証と認可を分ける

若干YAGNIな気もするけど、OAuth2を使った仕組みへの連携とか、そのあたりを ある程度 考慮した仕組みも考えておきたいところ

権限判定

アクションに対するロールとか、そのあたりの仕組み。
悩んでいるところとしては、アクションに対するロールという整理が良いのか、アクターとユースケースとする整理が良いのか、というところ。

これについては、デブサミで 偶然 良い視座をいただきました。

リダイレクト

ログイン画面へのリダイレクトさせるケース

未ログイン

操作に対して、そもそもログインしているか、していないか、というレベルの話。
権限が付与されていない状態での操作、というものも これに含まれるかな。
OAuth2の発想が参考になりそうな気がします。

タイムアウト

セッションタイムアウトしていたら、再ログインを促します。
未ログインとの違いは、長時間の操作をしていなかったことを ユーザーに通知してからログイン画面に遷移させるか、いきなりログイン画面に遷移させるか、というところ。
自分の観測範囲では、遷移パターンはサービスによって異なるように思います。

  • ログイン画面へタイムアウトメッセージを添えて遷移する
  • タイムアウトした旨を伝える画面に遷移して、そこからログイン画面へ遷移する

と思ったけど、機能としては タイムアウトを検知時に 遷移する先の遷移先を指定するだけだから、実質一緒かな?

権限の異なる操作

異なる権限のユーザーで、URLを直接実行するケース。
悪意が無ければ普通は無さそうなケースだけど、だからこそ外せないところ。
通常なら URL Filterで制御するようなところです。
なので、Serviceで権限制御をしようとすると、この点については 対処できないケースがあるような気がしています。 ただ、適切に権限指定すれば 大丈夫な気もしています。

ログイン前後の情報喪失を防ぐ

具体的には、ログイン前にカートに入れた商品を いざ購入しようとしたら ログインを促されて ログインしたらカートの中身が空になるみたいなケース。
なんだけど、これは そもそも可用性の話であって権限とは話が違うので除外。

考えようとしたことのメモとしては

  • カートに商品を入れる という操作は 商品購入というユースケースとして 購入者権限が必要(=ログインしないといけない)として、ログイン画面を介在させる
  • 購入する という操作前後で カートの情報が喪失しないように引き継ぐ

セッションハイジャックのことを考えると*1、そもそも後者って どうやってやっているんだろう?という感じです。
セッションではなく、別のトークンみたいなものをもたせて、セッションとは異なる キャッシュで管理している?
クライアントに保持しておいて 毎回 全部引き回す?

参考情報

以前の自分の認証認可のメモのリンクは、一通り 改めて 読み直しておきたいところ

vermeer.hatenablog.jp

*1:セッションIDを書き換えるだけだから使えるのかな?