CASの動作についてまとめたもの

CASの動作についてのまとめ
- あくまで私家版という立場をくずしませんが -
名古屋大学
全学技術センター
太田芳博
シングルサインオンの仕組みであるCASの説明。
よくこんな感じで書かれてる。
ブラウザ
(ユーザ)
sampleapp
1. 最初のリクエスト
2. service=url_back_sampleapp_pageをつけて,CAS loginページにリダイレクト指示
3. 2を受けて,
CAS loginページにアクセス
CASサーバ
4. CAS loginページを送信
5. username, passwordを送信
9. STが正しいならアクセスOK
8. STが正しいものか確認
(Validation)
6. 認証OKなら,
(1)CASTGCを発行し,
(2)STをつけてurl_back_sampleapp_pageに
リダイレクト指示
(CASTGC: CAS Ticket Granting Cookie
ST: Service Ticket)
7. 6を受けて,ticket=STをもってurl_back_sampleapp_pageへ
10.これでやっと認証後のsampleappのページを送信
これで分かる人は
ここで終了です。
実際の動作に照らし合わせると
かなり端折られているので
全体動作を把握するのは
(普通は)難しいと思います
ブラウザ
(ユーザ)
だって,動作を理解しようとすると
疑問がいっぱい...(じゃない?)
sampleapp
1. 最初のリクエスト
2. service=url_back_sampleapp_pageをつけて,CAS
loginページにリダイレクト指示
service= ってなに?
どこで設定するの?
3. 2を受けて,
CAS loginページにアクセス
CASサーバ
4. CAS loginページを送信
実際の
認証はどう
5. username,
passwordを送信
なってるの?
6. 認証OKなら,
(1)CASTGCを発行し,
(2)STをつけてurl_back_sampleapp_pageに
CASTGC?
リダイレクト指示
ST? Ticket Granting Cookie
(CASTGC: CAS
ST: なにそれ?
Service Ticket)
CASサーバにリ
ダイレクトする
ときとしないと
きがあるけど,
どう判定してる
の?
9. STが正しいならアクセスOK
8. STが正しいものか確認
(Validation)
STって毎回もっていく
7. 6を受けて,ticket=STをもってsampleappへ
必要があるの?
10.これでやっと認証後のsampleappのページを送信
認証後,sampleappへアクセスしたとき
の流れは?
他のCASアプリにいくときの流れは?
以下は基本的に
最初の図をみながら
追っていって下さい。
あ,ほとんど字なので
覚悟して下さい。
1,2のやりとり
ブラウザ(ユーザ)は:
sampleappにアクセスする。(1の矢印)
この 1の矢印は,sampleapp内の,認証ロジックへのアクセスになります。
(→CAS LoginボタンやCAS Loginリンクを押したとか。)
sampleappは:
上のアクセスを受けるのは sampleappに組み込まれたCASクライアントです。
(アプリをそう作っておきます。)
CASクライアント内で,認証が済んでいないと判定された場合(*),
「CASサーバへいって来てね。あ,認証後の戻りのURLはここね」と
いう情報を含んだレスポンスをブラウザに返します。(2の矢印)
◎「CASサーバのURL」及び「戻りのURL」はsampleapp内で指定されています。
◎CASサーバに誘導するのには,HTTP Redirectを使います。
具体的にはHTTPレスポンスのLocationヘッダに,以下のように設定されています。
Location: https://(CASサーバのURL)?service=(戻りのURL)
「戻りのURL」は単なるURLパラメータ(文字列)として使用されます。
(*) 判定基準はここで説明するとややこしくなるので,最後に!
3,4,5のやりとり
ブラウザ(ユーザ)は:
「CASサーバにいけ」と言われたので,素直にアクセスします。(3の矢印)
https://(CASサーバのURL)?service=(戻りのURL)
そこはCASログインのフォームページになります。
CASサーバは:
ブラウザに対し,ログインページ(フォーム)データを生成して返します。(4の矢印)
CASサーバは,このログインフォーム生成時に,ワンタイムチケット(LT; Login Ticket)を
発行しており,[戻りのURL」 と共に,フォーム内にhidden属性で埋め込んで
ブラウザに渡しています。(当然,この LT もCASサーバ内で管理されてます。)
ブラウザ(ユーザ)は:
表示されたフォームにUsername, PasswordをいれてCASサーバに送ります。(5の矢印)
ユーザは意識してませんが,このとき裏で LTや,「戻りのURL」情報も一緒に送られてます。
(興味のある人は,CASログインフォームのソースを見てみて下さい)
◎ユーザパスワードは,CASサーバに対してしか送られません。
CAS的には,これがセキュリティ上,素敵な実装ということになってます。 
6,7のやりとり
CASサーバは:
ログインフォームから送られてきた情報で,ユーザ認証を行ない,OKならば
いろんな情報をつけてブラウザにレスポンスを返します。(6の矢印)
1) CASTGC (CAS Ticket Granting Cookie)
ブラウザに対して,CASサーバのクッキーとして送ります。
Set-Cookie: CASTGC=TGC-371119-UndB(略)vdVuFrE
2) ST (Service Ticket)
これも,CASサーバが発行するワンタイムチケットです。
3) 「STを持って,戻りのURLに行ってみな」というレスポンスを返します。
ブラウザ(ユーザ)は:
CASサーバに言われた通り, STを持って,「戻りのURL」にRedirectで飛びます。 (7の矢印)
◎ここまででの状態としては,「CASサーバに無事認証していただいた」ので,
あとはsampleappアプリにも認証したことを理解していただくだけです。もう少し。
8,9,10のやりとり
sampleappは:
ブラウザからSTつきのアクセスリクエストがきたら,そのSTがちゃんとCASサーバで
認証された結果として発行されたものか,CASサーバに問い合わせて検証をします。
(8の矢印)
CASサーバは:
STの情報が,自分が認証OKとして発行したものか検証し,OKならsampleappに
「こいつはアクセスさせてOKだよー」というレスポンスを返してやる。(9の矢印)
ここで,sampleappに,認証したユーザの情報が送られます。
(何が送られるかはCASサーバの設定次第。)
sampleappは:
CASサーバからお墨付きが得られたら,
ある場所に認証情報を書き込んだ後,
ブラウザに対してやっと認証後のページデータを送り,表示させる。(10の矢印)
× 「『ある場所』ってなんだよ!」 「あとで!」
これでやっと画面が表示されたよ! 
説明長かったですね...。でも実際にアクセスしてみるとわかりますが,
パスワードを入力するところを除けば処理は一瞬です。
積み残しの疑問解決 その1:
Q.
A.
Q.
A.
あれ?CASTGC は使ってないけどいいの?
今回の説明では特に使わない。
いつ使うの? そもそも必要なの?
CASTGC は他のCAS対応アプリに行く時に必要なんだよ。
CASTGC は,CASサーバで認証されたあと,CASサーバからブラウザに対して
発行されるCookieでした。
例えば,あるアプリAで認証したあと,別のCAS対応アプリBにアクセスした場合,
CASTGCは 図中の 3の矢印 でのアクセス時に一緒にCASサーバに送られます。
すると...CASサーバ側で,「認証済」と判定されます。
(→CASサーバは,ブラウザに向けて発行した情報管理をしてるからね。)
その場合,アプリBへのアクセスでは,図中の4,5の矢印は端折られるので...
CASログイン画面は出ない。これがSSOの実現ってことだね!
当然ですが,別のCAS対応アプリにいった場合,6では,CASTGCは
二重発行されません。 STだけ発行されます。
積み残しの疑問解決 その2:
Q. 1〜2の間や,7〜10の間,そして認証完了後のアクセス(図にはないけど,
言うなら11〜12に相当?)は動作が違うと思うんだけど,sampleappp内では
どう判定しているの? 動作判定基準は?
A. これは,10の矢印の説明時に,「あとで」といっておいた所です。
sampleappに対して,CAS認証が一度正しく行なわれた後,
JSESSIONIDが示すセッションに対して,セッション変数(認証情報)が書き込まれ,
それをチェックすることで認証済みかどうかを判定しているようです。
つまり,sampleappのCASクライアントは,ブラウザから送られてくるJSESSIONIDが
示すセッション中に書き込まれたセッション変数をチェックすることで認証済か
未認証かを調べています。
・未認証なら,CASサーバへ行ってこい,とredirectを出す。 (1〜2)
・リクエストに ST がついてたら,CASサーバにValidate伺いをする。(7〜10)
※ 適当なSTを指定すると,org.jasig.cas.client.validation.TicketValidationException と言われて蹴られます。
・認証済みならそのままページを表示する。
このページの記述は以下を参考にしました。
https://groups.google.com/forum/#!msg/jasig-cas-user/qxjqGpHoKNQ/p3xyk8msLUYJ
ほんとうはログアウト時の処理ももう少し詳しく調べて書きたいのですが疲れたので少しだけ。 (おい)
ので,このページは,推測も疑問も含まれたままになっています。信用度低。
あるアプリ上にCASクライアントライブラリでCASログアウト処理を実装した時は,
CASサーバ上にある,認証済みの管理情報が消える動作になると思います。
このとき,ブラウザのCASTGCまでも消すか?というと,消さないような...。(←ここ,詳しく調べてません)
ただ,少なくとも CASサーバ上で管理されてる認証情報が消えれば,ブラウザに残ってるCASTGCは
意味がなくなり,それ以上新しいCAS対応アプリにはSSOログインできなくなります。
この残ったCASTGCも,ブラウザを終了すると消えるので,まぁ...
しかし,その場合でも気をつけないといけないのは,ウインドウを開きっぱなしでどっかいっちゃったときとか。
例: (ブラウザの種類は同じなのが前提。)
1) アプリAで初期認証。
2) アプリAはそのままおいといて別ウインドウを開き,アプリBも SSOで利用。
3) アプリBでログアウト。
この状態で,アプリAのウインドウが開いたままであれば,アプリAはまだそのまま使える。
(アプリA内では,まだJSESSIONIDに認証済の情報が残ってるから。)
でも,アプリB,C, D をもう一度使うにはもう一度認証が必要。
ここで,アプリAのウインドウをこのままで,最初に認証した人と別のIDでアプリBにアクセスすると...?
アプリAの動作は最初の人で,アプリBは2番目の人となってなんかおかしくなるような。
さらに,2番目の人が,また別ウインドウでアプリAにアクセスすると...?
最初の人が開いていたアプリAのウインドウはどうなるんでしょ?
とりあえずの結論: CASログアウト実装は各アプリに依存するような気がするので,
共用のPCで,席を離れるときは,確実にブラウザを終了しましょう。
終了すれば,CASTGCが消えるから。それが安全。
間違ってるとこがあったら
是非是非ご連絡ください。