はじめに
この記事ではJavaによるOP実装例をベースに、シングルサインオン(SSO)を実現する方法を書いてみます。
https://qiita.com/namikitakeo/items/c4f1a23ed7609c65342e
実行環境
下記バージョンで動作確認しています。myopはJavaアプリケーションでApacheのリバースプロキシ設定で中継します。
- Ubuntu on Windows(14.04.6 LTS, Trusty Tahr)
- Apache2 Ubuntu(Apache/2.4.7)
ProxyPass /myop/ http://127.0.0.1:8080/myop/
ProxyPassReverse /myop/ http://127.0.0.1:8080/myop/
実装方針
mod_auth_formを利用する事でログイン/ログアウトをApacheで行いセッション管理にCOOKIEを用いる事でSSOを実現します。
以下の例ではフォーム認証のID/パスワードにはファイルを利用します。もちろんDBやLDAPに対応する事も可能ですので認証に依存しない認可の仕組みをつくる事が可能となります。
$htpasswd -b /etc/apache2/passwd user01 user01
以下のURL構成を想定しています。
https://myop.example.com/myop/authorize
https://myop.example.com/myop/jwk_uri
https://myop.example.com/myop/tokeninfo
https://myop.example.com/myop/.well-known/openid-configuration
https://myop.example.com/login.html
https://myop.example.com/dologin.html
https://myop.example.com/logout.html
https://myop.example.com/dologout.html
以下のURLのみID/パスワードで保護します。ユーザーが最初にアクセスした際は有効なCOOKIEがありませんので、
https://myop.example.com/myop/authorize?param=aaa
ログイン画面にリダイレクトされます。
https://myop.example.com/login.html?param=aaa
ログイン画面では/dologin.htmlにパラメータをPOSTする事で有効なCOOKIEを発行します。
httpd_username:user01
httpd_password:user01
httpd_location:https://myop.example.com/myop/authorize?param=aaa
Apacheのリバースプロキシ設定でTomcatのmyopに中継する際にHTTPヘッダ(uid)で有効なID(user01)を連携します。
<Location "/myop/authorize">
require valid-user
AuthUserFile /etc/apache2/passwd
AuthType form
AuthName realm
AuthFormLoginRequiredLocation /login.html?%{QUERY_STRING}
Session On
SessionCookieName session path=/
SessionCryptoPassphrase secret
RewriteEngine On
RewriteCond %{LA-U:REMOTE_USER} (.+)
RewriteRule . - [E=RU:%1,NS]
RequestHeader set uid %{RU}e
</Location>
<Location /dologin.html>
SetHandler form-login-handler
AuthFormProvider file
AuthUserFile /etc/apache2/passwd
AuthType form
AuthName realm
AuthFormLoginSuccessLocation /myop/authorize?%{QUERY_STRING}
AuthFormLoginRequiredLocation /login.html
Session On
SessionCookieName session path=/
SessionCryptoPassphrase secret
</Location>
<Location /dologout.html>
SetHandler form-logout-handler
AuthFormLogoutLocation /logout.html
AuthName realm
Session On
SessionCookieName session path=/
SessionCryptoPassphrase secret
</Location>