認証と認可
認証(Authentication)
ユーザの識別、パスワードや生体情報、などを利用しユーザを識別する
認可(Authorization)
ユーザの権限、理論的には認証が必須ではないが、ユーザを識別(認証)せずに決定は困難なため、認証とセットになる場合が多い
はじめに
Spring Securityはとりあえずここ読んどけhttps://t.co/wdZDs7GAQS
— Toshiaki Maki (@making) 2016年6月3日
これのJavaConfig版は書籍オンリー(Spring徹底入門)。
その上でSpring BootのAutoConfigureのソース嫁
=> 読んだ感想、Spring徹底入門の解説がすごく分かりやすい。
各クラスの関係や処理の流れがまとまっていて、Spring Securityに関しての最低限の知識は十分に理解出来る(Spring Security OAuth、Spring Cloud Securityは別途理解が必要)
@okapies オレオレ実装よりメンテナンス性が低いってことはないかと。標準的なお作法の方がSpring Security知っている人は分かりやすいかと(どうしても集約したいならAuthenticationProviderを実装してしまえば認証周りは全部実装できちゃいますが)
— Toshiaki Maki (@making) 2016年9月23日
=> Spring徹底入門を読めばここの趣旨は十分理解できる。
SlackのOAuth2.0を利用した認証が簡単に出来てしまった。Spring Security OAuthの@EnableOAuth2Ssoやばい。
— Suzuki Junya (@suzukij) 2016年6月28日
これ社内の運用ツール達に埋めてあげればSlackのアカウントでログインできるな。
java: SpringBootとSpring Security OAuth2で自作OAuthサーバと認証する - Qiita https://t.co/XzMQe0gN8C
— はてブ::プログラミング言語非公式bot (@RSS_hateb_l_Roy) 2016年3月1日
@bati11_ ちょっと古いですが https://t.co/mMT0noTLEL
— Toshiaki Maki (@making) 2015年6月7日
@susumuis http://t.co/XWAc2CuT69 Spring Security OAuthだったらOAuthRestTemplateありますが。 https://t.co/DppUMCumZO
— Toshiaki Maki (@making) 2014年4月5日
Json Web Tokensはクソ
— せろめたる (@cero_t) 2017年1月3日
=> JWT関連の話題、以下詳細
Json Web Tokensはクソ
@daisuke_m お前ちゃんと知ってんのか、概要とメリットを説明してみろよ
@cero_t いくつか種類があるけど、最もメジャーなのは「JSON+その電子署名」のパターン。署名によって改変が防止されるJSONドキュメントだと思えばいい。
@daisuke_m なるほど、そのパターン。OAuthがらみでも似たような話を聞いてましたけど、同じ感じですかね *1
@cero_t でもこれだとAPIアクセスの度に認可鯖への問い合わせが発生してコスト高い。キャッシュはできるけどね。
しかし、アクセストークンかランダムトークンではなく、JWTでできていたらどうか? つまり「{user:daisuke, exp:12345678}」というJWT。*2
@daisuke_m ふむ、それだとexpireまではキャッシュすればええやんと(ただしログアウト処理さえ考えない前程)
@cero_t oauthにログアウトって概念ないけどねーw
*1 @cero_t うん。oauthではリソース鯖(API鯖)が受け取ったアクセストークンをリソース鯖自身が「これって正しいトークンなの?」という判断をする手段を規定してません。なので一般的には、トークン発行元(認可鯖)にHTTP で問い合わせたり、認可鯖と同じDBを共有したりする。
@daisuke_m なるほどなるほど、そんで後は各API鯖でキャッシュするか、都度問い合わせるかは、まぁポリシー次第と。
*2 @cero_t リソ鯖は、認可鯖の公開鍵を持って入れば、そのトークンの署名検証すれば、認可鯖に問い合わせなくても、そのトークンの正当性を確認できる。そして、電子署名がついているので、偽造もできない。
@daisuke_m 秘密鍵で暗号化して、公開鍵で復号する、って理解であってる?
@cero_t いや、暗号の機能はもたない。あくまでも、改変防止の電子署名。JSONベースの情報は、特に秘匿されない。
@daisuke_m あぁなるほど、電子署名の正当性を公開鍵で検証する、っていう?
@cero_t そそ。認可鯖はトークン発行時に、認可鯖の秘密鍵で署名。リソ鯖は、トークン受信時に、認可鯖の公開鍵で検証。
@daisuke_m なるほどなるほど、理解!
まぁ規格としてJWTかOAuthかの違いしかなくて、考え方は同じものが使える気がしてきた。
@cero_t で、ここまで理解してから、これを読む。
@daisuke_m 読みました! 確認メールのくだりはただの暗号化と復号の話なので、JWTでなくていいやんって気になりましたが気にしないことにします!
あざす!!
@cero_t いや、暗号関係ないど?
@daisuke_m あぁいや、改竄できないように何か適当なチェックサムを(暗号化して?)URLに乗っければいいのではないかと
@cero_t それって、やってることJWTと変わらんし、オレオレ仕様を作るより、スタンダードがいいんじゃないかな。
@daisuke_m ああそうか、JWTって別にトークンであって認可のためのなにがしかではないから、強引な利用ではないのか
@cero_t @daisuke_m リクエスト送る側はオレだオレだって情報をトークンに入れて署名して、受け取る側はverifyするだけで済むのでトークンからユーザー情報に変換する問い合わせコストがなくなる。JWT知らなかった時代、キャッシュサーバー立てて変換処理キャッシュしてた
@cero_t @daisuke_m トークン自体はBase64でデコードできてユーザー名とかメールアドレスとか見れる
@making @daisuke_m ふむふむ、そこが標準化されたと思えばいいんすねー
役立った資料
マイクロサービスで必要になるかなぁって思って僕がOAuth2とOpenID Connectをなんとなく分かるようになるまでの物語
=> 全ての資料は理解できないけど、段階的に理解していく手助けになる
from-zero-to-hero-with-rest-and-oauth2
=> OAuthを使用した、AuthrizationServerとResourceServerをSpringで構築 create by @making
Microservices /w Spring Security OAuth
=> Spring Security OAuthの仕組みの一部解説。分かりやすい
第一回 認証基盤のこれからを支えるOpenID Connect
=> OpenID connectに関して分かりやすくまとまっている
OAuth 2.0 の仕組みと認証方法
=> OAuthに関連する用語や仕組みがまとまっている、単語が分からない場合にはまず見てみるといい
単語集
関連単語をまとめているので粒度とか分類はバラバラ(あくまでも不明な単語を羅列して整理するための材料)
単語 | 説明 |
---|---|
OAuth | 認可の仕組みの一つ 1と2がある |
OAuth認証 | |
OpenID | 認証の仕組みの一つ |
OpenID Connect | |
JWT | |
ID Token | |
Access Token | 認可サーバから発行され、リソースサーバへのアクセスを行うためのトークン(TwitterやFacebookの認証を使うと、同じサーバにアクセスしているように見えるが実際は認可サーバとリソースサーバが異なっている可能性がある) |
認可グラント | 認可オーナーによる認可を示す 認可サーバは認可グラントにもとづき、クライアントにアクセストークンを発行する 4タイプあり、それぞれアクセストークンの発行手順が違う |
4タイプの認可グラント | 認可コード インプリシット リソースオーナーパスワードクレデンシャル クライアントクレデンシャル |
Authentication Server(認証サーバ) | |
Authorization Server(認可サーバ) | Access Tokenなどの発行? Userinfoの提供 |
Authentication | Springクラス ユーザ情報? |
userinfo | Spring Securiry OAuthのエンドポイントの一つ |
security.oauth2.client.client-id | Spring Securiry OAuthのpropertyの一つ |
security.oauth2.client.client-secret | Spring Securiry OAuthのpropertyの一つ |
security.oauth2.client.scope | Spring Securiry OAuthのpropertyの一つ |
security.oauth2.client.authorized-grant-types | Spring Securiry OAuthのpropertyの一つ認可グラント
|
OpenID Provider (OP) |
OpenID Connect用語 ユーザーの認証を行う機能を有するサーバー。また、ユーザーの認証時にRelying Partyから要求されたアイデンティティ情報を供給することができるRESTエンドポイントを有するサーバー。 |
Relying Party (RP) |
OpenID Connect用語 OpenID ProviderにID Tokenとアイデンティティ情報を要求するサーバー。SSO対象のアプリケーション(ウェブアプリケーション、ネイティブアプリケーション問わず)を指す。 |
ID Token |
OpenID Connect用語 認証と認可の情報を含むJWT(JSON Web Token)形式のトークン。 |
Access Token |
OpenID Connect用語 UserInfoエンドポイントにアクセスするためのトークン |
UserInfo |
OpenID Connect用語 Access Tokenを提示するクライアントに対して、アイデンティティ情報を提供する。 |
つまずきポイント
認証サーバ、認可サーバ、ユーザ情報、リソースサーバ、クライアント、エンドユーザなどの関係が分からなくなる
最小構成の場合、認証サーバと認可サーバはほとんど同じものとして捉えたほうが分かりやすい(実際は違う可能性はある)。認証機能無しに、認可は基本できない。結果、認証/認可サーバは多くの場合、ユーザを一意に特定するための機能を有している(直接データストアか更にバックエンドにAPIなどを利用していると想定)。
=> 最小構成の場合、認証/認可/ユーザ情報サーバとなる
ex.) Wantedly
エンドユーザ => Wantedly => Facebook
この構成の場合、Facebookは認証/認可/ユーザ情報を提供、Wantedlyはサービスを提供する、Facebookのクライアントとして考えられるが、Facebookに関する情報をWantedlyに提供しているのであれば、Wantedlyから見ると、Facebookはリソースサーバという機能も有していることになる。
エンドユーザから見ると、Wantedlyは単純にFacebook連携をしているように見える。