速習 OAuth 2.0とOpenID Connect
View Slide
今日話すこと ● 認証認可 ● OAuth 2.0 ● OpenID Connect ● アクセストークン ● 認可リクエスト
認証と認可 ● 認証(Authentication) ○ 通信相手が誰か確認すること。 ○ 「あなたは誰?」に答える。 ● 認可(Authorization) ○ リクエストに対して権限が許可されているか。 ○ 認証が成功した結果、その人がどのような権限を持っているか。 ○ 「あなたが誰かはわかっている。権限があるか確認させてくれ。」 ○ 本日のメイントピック。 参考: https://dev.classmethod.jp/articles/authentication-and-authorization/
認証認可に関連するプロトコルとサービス ● プロトコル ○ OAuth 2.0 ○ OpenID Connect ○ GNAP ○ SAML ● サービス ○ Auth0 ○ Okta ○ Ping Identity ○ OneLogin ○ Authlete
OAuth 2.0 ● 認可のフレームワーク。 ● アクセストークンを使ってAPIアクセスするための権限を委譲することができる。 ● IETFのOAuth working Groupが推進している。 ○ 最近はOAuth 2.1を頑張っている。(後述) ● ざっくり言うと... ● アクセストークンの発行手順を策定した技術仕様
OAuth 2.0 Security Best Current Practice ● セキュリティに関する事項をまとめたもの。 ○ PKCEを使いましょう。 ○ Implicit Flowは使うべきではない。 ○ など。 ● OAuth 2.1はこのPracticeを組み込んだ内容になっている。 小ネタ PKCE = Proof Key for Code Exchange
OpenID Connect ● OAuth 2.0を拡張して作成されたフレームワーク。 ○ OpenID + OAuth 2.0 = OpenID Connect ● OpenID Foundationが推進している。 ○ ベースとなるOpenID Connect Coreに様々な追加仕様も定義している。 ○ 例:FAPI, eKYC and IDA, CIBA. ● ざっくり言うと... ● アクセストークンに加えてIDトークンを発行する技術仕様を追加したもの。
OIDCで最近話題になるトピック ● Financial-grade API(FAPI) ○ 金融サービスでのユースケースに対応した仕様。 ○ セキュリティが一段と厳しく定義されている。 ● Client Initiated Backchannel Authentication Flow(CIBA) ○ リソースサーバーにアクセスするサービスに対して、別のデバイスから認可を行う仕様。 ● Identity Assuarance(OIDC for IDA) ○ eKYC、つまり身元確認をする仕様。 小ネタ PKCE = Proof Key for Code Exchange
他の仕様との関係性 資料拝借: https://youtu.be/I8wijU3L4aw 小ネタ
注釈 ● 発表時間の制限のため、本資料はアクセストークンについて説明します。 ● IDトークンやリフレッシュトークンは説明しません。 ● OAuthとOIDCもあまり区別せずに聞いてもらってOKです。
ざっくりフロー解説(Kleinの例) リソースサーバー(BFF)クライアント(Reactアプリ)認可サーバー※(Auth0)/authorize?token_type=code&.../callback?code=ABCDEF認可リクエスト /oauth/tokencodecodetoken/api/graphqltoken※OIDCの文脈だとIdPと呼ばれる
詳細なフロー、今回は省略します 参考 https://www.authlete.com/ja/resources/videos/20200131/01/ https://developer.yahoo.co.jp/yconnect/v2/authorization_code/
アクセストークンを説明 リソースサーバー(BFF)クライアント(Reactアプリ)認可サーバー※(Auth0)/authorize?token_type=code&.../callback?code=ABCDEF認可リクエスト /oauth/tokencodecodetoken/api/graphqltoken※OIDCの文脈だとIdPと呼ばれる
アクセストークン ● リソースサーバーにAPIでリクエストする時に使用する。 ○ Authorizationヘッダーに設定する。 ○ authorization: Bearer ${token}● JWT(Json Web Token)と言う形式になっている。 ○ JWTは「ジョット(jot)」と読む。
Authorizationヘッダーの中身 eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJodHRwczovL2V4YW1wbGUuYXV0aDAuY29tLyIsImF1ZCI6Imh0dHBzOi8vYXBpLmV4YW1wbGUuY29tL2NhbGFuZGFyL3YxLyIsInN1YiI6InVzcl8xMjMiLCJpYXQiOjE0NTg3ODU3OTYsImV4cCI6MTQ1ODg3MjE5Nn0.CA7eaHjIHz5NxeIJoFK9krqaeZrPLwmMmgI_XiQiIkQAuth0のマニュアルから拝借:https://auth0.com/docs/secure/tokens/access-tokens/use-access-tokens
jwt.ioを使うと中身が読める。 右側の値をBase64でエンコードして”.”で繋いだ文字列。
ヘッダーペイロード署名ヘッダー + ペイロード
アクセストークンの検証方法 ● 認可サーバーが公開鍵をホスティングしている。 ○ .well-known/jwks.json ○ JWKS(Json Web Key Sets) ● リソースサーバーがJWKSを使って、アクセストークンの署名を検証する。 クライアント(Reactアプリ)リソースサーバー(BFF)トークン 認可サーバー(Auth0)JWKS検証して不正だったら→401 有効期限が切れていたら→401 権限が足りなかったら→403 401 Unauthorized
認可リクエストを説明 リソースサーバー(BFF)クライアント(Reactアプリ)認可サーバー※(Auth0)/authorize?token_type=code&.../callback?code=ABCDEF認可リクエスト /oauth/tokencodecodetoken/api/graphqltoken※OIDCの文脈だとIdPと呼ばれる
各種クエリパラメータの解説 https://example.auth0.com/authorize?audience=https://audience.example.caddi.jp&client_id=${CLIENT_ID}&redirect_uri=https://example.caddi.jp&scope=openid profile email&response_type=code&response_mode=query&state=XYZWxyzw…&code_challenge=123456789…&code_challenge_method=S256&nonce=ABC…
認可リクエストをアプリに実装する前に ● どのタイプのアプリケーションが実施する? ○ Regular Web Application ○ Single Page Application ○ Native Application ○ それぞれで設定するパラメータや気をつける点が異なるので注意。 ● Auth0の場合、ライブラリが提供している機能を利用すれば最新セキュリティ事情は満たした実装にはなる。
認可リクエストのタイプ ● Authorization Code Flow ○ 基本のフロー。これを使いましょう。Auth0ライブラリはデフォルトこれです。 ○ SPAやネイティブアプリの場合、PKCEもちゃんと使いましょう。 ● Implicit Flow ○ 現在は非推奨になっています。 ● Hybrid Flow ○ 特殊なユースケースで使うフロー。覚えなくても良い。
認可コードのっとり攻撃 リソースサーバーネイティブアプリ 認可サーバー/authorize?response_type=code&response_mode=query&redirect_uri={Custom_URL}/callback?code=ABCDEF認可リクエスト /oauth/tokencodecodetokentoken Custom URL Schemeを競合させたアプリ
PKCEによる対策 リソースサーバーネイティブアプリ 認可サーバー/authorize?response_type=code&response_mode=query&redirect_uri={Custom_URL}&code_challenge={AAA}&code_challenge_method=S256/callback?code=ABCDEF認可リクエスト /oauth/tokencodecode Custom URL Schemeを競合させたアプリcode_verifierがないのでトークンを返却しない正規アプリはcode_verifierの値を知っているので/tokenが成功するcodeverifierPKCE = Proof Key for Code Exchange code_verifier知らない...
Implicit Flowは非推奨 リソースサーバーネイティブアプリ 認可サーバー/authorize?response_mode=token&response_type=fragment/callback #token=${access_token}認可リクエスト ※OIDCの文脈だとIdPと呼ばれる token先程の認可コード乗っ取り攻撃の例と同じで、tokenの返却先が認可リクエスト発行元と同一であることが保証できない。
まとめ ● OAuth 2.0とOpenID Connectの違い ○ OAuth 2.0はトークンを使ったAPIアクセスのフレームワーク ○ OpenID ConnectはOAuth 2.0を拡張したフレームワーク ● アクセストークン ○ JWT ○ サーバー側で検証(JWKS) ● 認可リクエスト ○ クエリパラメーター ○ PKCE