Slide 1

Slide 1 text

基礎からわかろう OAuth2/OpenID Connect Yuki Watanabe (@ukwhatn)

Slide 2

Slide 2 text

SPEAKER ● 渡邉 雄貴 / Yuki Watanabe ○ 近畿大学 理工学部 B3 ■ KINDAI Info-Tech HUB 役員 ■ KC3運営委員会(NPO法人NxTEND) 理事 ○ Webバックエンド・インフラエンジニア ■ 長期インターンシップ・業務委託での開発 ■ 転職型プログラミングスクール メンター

Slide 3

Slide 3 text

SPEAKER ● 渡邉 雄貴 / Yuki Watanabe ○ SKILLS ■ Webバックエンド ● Ruby(Rails) / Python(FastAPI, Flask) / Kotlin / TS ■ Webフロントエンド ● TS(React) / JS / HTML-CSS ■ インフラ・その他 ● Linux / AWS / Docker / DB / 認証・認可

Slide 4

Slide 4 text

SPEAKER ● 渡邉 雄貴 / Yuki Watanabe ○ SKILLS ■ Webバックエンド ● Ruby(Rails) / Python(FastAPI, Flask) / Kotlin / TS ■ Webフロントエンド ● TS(React) / JS / HTML-CSS ■ インフラ・その他 ● Linux / AWS / Docker / DB / 認証・認可

Slide 5

Slide 5 text

もくじ 認証・認可の違い 認証・認可警察に 見つからないための基礎知識 01 OpenID Connect OIDCはどう安全なのか? 04 OAuth2とは? OAuth2の具体的な仕様・フロー 02 OAuth2認証 OAuth2を認証に使うということ 03

Slide 6

Slide 6 text

認証・認可の違い

Slide 7

Slide 7 text

認証ってなに? ● 認証/Authentication(Authn) ○ サービスの利用者が本人であることを確認する ■ What you are ● 生体認証 ■ What you have ● 所有物認証(カギやセキュリティキーなど) ■ What you know ● 知識認証(パスワード・秘密の質問) 認証・認可の違い

Slide 8

Slide 8 text

認証ってなに? ● 認証/Authentication(Authn) ○ サービスの利用者が本人であることを確認する ■ What you are ● 生体認証 ■ What you have ● 所有物認証(カギやセキュリティキーなど) ■ What you know ● 知識認証(パスワード・秘密の質問) 認証・認可の違い

Slide 9

Slide 9 text

認可ってなに? ● 認可/Authorization(Authz) ○ サービスの利用者に適切な権限を与える仕組み ■ リソースへのアクセス権限・操作権限など ■ 外部サービスに対して操作を許可することが多い ● Twitterへの代理投稿 ● メールのRead/Write 認証・認可の違い

Slide 10

Slide 10 text

認可ってなに? ● 認可/Authorization(Authz) ○ サービスの利用者に適切な権限を与える ■ リソースへのアクセス権限・操作権限など ■ 外部サービスに対して操作を許可することが多い ● Twitterへの代理投稿 ● メールのRead/Write 認証・認可の違い

Slide 11

Slide 11 text

OAuth2とは?

Slide 12

Slide 12 text

OAuth2とは? ● OAuth2 ○ 認可(権限委譲)のためのプロトコル ■ ユーザのリソースへのアクセス権限を外部サービスに移譲 ■ 外部サービスはユーザの認証情報を知る必要がない ● べんり! ● 必要なだけ権限を移譲できる!

Slide 13

Slide 13 text

OAuth2のしくみ ● 登場人物(ロール) ○ リソースオーナー(ユーザ) ■ GoogleやTwitterのアカウントオーナーを指す ○ クライアント ■ 権限を移譲された外部サービス ○ リソースサーバー ■ だいたいWebAPIのこと リソースを提供する ○ 認可サーバー ■ OAuthサービスを提供するサーバー OAuth2とは?

Slide 14

Slide 14 text

● 登場人物 ○ アクセストークン ■ 「誰の」「どのリソースに」「いつまで」 アクセスできるかと紐付けられている ■ クライアントからリソースサーバへのアクセスに添付 ● 紐付けられた情報と矛盾がなければアクセスを許可 ■ Bearerトークン(RFC6750) ● アクセストークンさえ持っていれば誰でもアクセスできる OAuth2のしくみ OAuth2とは?

Slide 15

Slide 15 text

● 登場人物 ○ アクセストークン ■ スコープ ● 「何の」リソースにアクセスできるかを規定 ● クライアントから認可サーバへのリクエスト時に指定する OAuth2のしくみ OAuth2とは? https://discord.com/api/oauth2/authorize?client_id=XXXXX &redirect_uri=http%3A%2F%2Fredirect:3000&response_type=code &scope=identify%20guilds

Slide 16

Slide 16 text

● 登場人物 ○ リフレッシュトークン ■ アクセストークンの再発行に利用される ● 必須ではないので、発行されないこともある ● 認可サーバに対して送られる ■ 有効期限が極めて長い ● 30日くらいあることもある OAuth2のしくみ OAuth2とは?

Slide 17

Slide 17 text

● 登場人物 ○ 認可コード ■ リソースオーナーが権限委譲に同意した証 ■ 301リダイレクトによってクライアントへ送られる ● クライアントは、認可コードを認可サーバに再送して アクセストークンを要求する ■ 有効期限が極めて短い ● 仕様では10分以内を推奨 OAuth2のしくみ OAuth2とは?

Slide 18

Slide 18 text

● エンドポイント ○ 認可エンドポイント ■ 認可サーバによって提供 ■ 認可コードの発行を行う ○ トークンエンドポイント ■ 認可サーバによって提供 ■ 認可コードと引き換えにアクセストークンの発行を行う ■ クライアントのIdentityはBasic認証で行う OAuth2のしくみ OAuth2とは?

Slide 19

Slide 19 text

● エンドポイント ○ リダイレクトエンドポイント ■ クライアントが提供する ■ 認可コード発行時に、301リダイレクトが行われる先 OAuth2のしくみ OAuth2とは? HTTP/1.1 301 Found Location: https://ukwhatn.com/callback?code=xxxxxxxxxx

Slide 20

Slide 20 text

● 事前登録 ○ クライアントは、リダイレクトエンドポイントを 各リソース提供サービスに登録する ■ クライアントIDとシークレットが発行される グラントにおける前提 OAuth2におけるグラントタイプ

Slide 21

Slide 21 text

● 事前登録 ○ クライアントは、リダイレクトエンドポイントを 各リソース提供サービスに登録する ■ それに対応したクライアントIDとシークレットが発行 グラントにおける前提 OAuth2におけるグラントタイプ

Slide 22

Slide 22 text

認可コードグラント(認可コードフロー) OAuth2におけるグラントタイプ

Slide 23

Slide 23 text

認可コードグラント(認可コードフロー) OAuth2におけるグラントタイプ

Slide 24

Slide 24 text

認可コードグラント(認可コードフロー) OAuth2におけるグラントタイプ HTTP/1.1 301 Found Location: https://ninka.example.com/authorize ?response_type=code&client_id=123456 &state=xyz&scope=identity &redirect_uri=https://client.user.com/callback

Slide 25

Slide 25 text

認可コードグラント(認可コードフロー) OAuth2におけるグラントタイプ

Slide 26

Slide 26 text

認可コードグラント(認可コードフロー) OAuth2におけるグラントタイプ

Slide 27

Slide 27 text

認可コードグラント(認可コードフロー) OAuth2におけるグラントタイプ HTTP/1.1 301 Found Location: https://client.user.com/callback?code=xxxxxxxxxx&state=xyz

Slide 28

Slide 28 text

認可コードグラント(認可コードフロー) OAuth2におけるグラントタイプ POST /token HTTP/1.1 Host: ninka.example.com Authorization: Basic Content-Type: application/x-www-form-urlencoded grant_type=authorization_code&code=xxx &redirect_uri=https://client.user.com/callback POST /token HTTP/1.1 Host: ninka.example.com Content-Type: application/x-www-form-urlencoded grant_type=authorization_code&code=xxx &redirect_uri=https://client.user.com/callback &client_id=123456&client_secret=

Slide 29

Slide 29 text

認可コードグラント(認可コードフロー) OAuth2におけるグラントタイプ HTTP/1.1 200 OK Content-type: application/json;charset=UTF-8 Cache-Control: no-cache Pragma: no-cache { “access_token”: “abc123”, “refresh_token”: “987zyx”, “expires_in”: 3600, “token_type”: Bearer }

Slide 30

Slide 30 text

認可コードグラント(認可コードフロー) OAuth2におけるグラントタイプ GET /api/user/1 HTTP/1.1 Host: resource.example.com Authorization: Bearer xyz123 Content-Type: application/x-www-form-urlencoded

Slide 31

Slide 31 text

クライアントコンフィデンシャルグラント (2-legged OAuth) OAuth2におけるグラントタイプ ● つかえるとき ○ クライアント全体に対してアクセス権限を発行する ○ クライアントがコンフィデンシャルクライアントである ■ client secretなどをセキュアに保存できるクライアント

Slide 32

Slide 32 text

リソースオーナーパスワードクレデンシャルグラント OAuth2におけるグラントタイプ ● つかえるとき ○ 同組織のサービス間での 認可処理

Slide 33

Slide 33 text

インプリシットグラント OAuth2におけるグラントタイプ

Slide 34

Slide 34 text

インプリシットグラント OAuth2におけるグラントタイプ

Slide 35

Slide 35 text

パブリッククライアントにおける認可コードグラント OAuth2におけるグラントタイプ ※ クライアントシークレットを使わないことが許可されている

Slide 36

Slide 36 text

認可コード横取り攻撃 OAuth2におけるグラントタイプ

Slide 37

Slide 37 text

認可コードグラント + PKCE ● PKCE ○ Proof Key of Code Exchange ■ OAuthの拡張仕様(RFC7636)で定義 OAuth2におけるグラントタイプ

Slide 38

Slide 38 text

認可コードグラント + PKCE ● PKCE ○ パラメータ ■ code_verifier ● 43-128文字、英数字+[“-” , ”.” , ”_” , “~”] ■ code_challenge_method ● plain(平文) or S256(SHA256) ■ code_challenge ● plainならcode_challengeそのまま ● S256なら OAuth2におけるグラントタイプ BASE64URL-ENCODE(SHA256(ASCII(code_verifier)))

Slide 39

Slide 39 text

認可コードグラント + PKCE OAuth2におけるグラントタイプ

Slide 40

Slide 40 text

認可コードグラント + PKCE OAuth2におけるグラントタイプ

Slide 41

Slide 41 text

認可コードグラント + PKCE OAuth2におけるグラントタイプ

Slide 42

Slide 42 text

OAuth2を認証に使うということ

Slide 43

Slide 43 text

OAuth2を認証に使うということ OAuth2を認証に使う

Slide 44

Slide 44 text

● 2つの誤解 ○ ① OAuth2は認証のためのものではない ■ OAuth2では、リソースへのアクセス制御のために認証を フローの中に組み込んでいますが、 そのためのものではありません OAuth2を認証に使うということ OAuth2を認証に使う

Slide 45

Slide 45 text

● 2つの誤解 ○ ② OAuth2を認証に使っているからって なんでも危険な訳ではない ■ OAuth2の脆弱性 インプリシットグラントの脆弱性 ● インプリシットグラントでは アクセストークンが直接ブラウザに落ちてくるため ここでの奪取やなりすましが起こりうる OAuth2を認証に使うということ OAuth2を認証に使う

Slide 46

Slide 46 text

● ただし ○ 認証に使うなら、ちゃんと認証用途に標準化された OpenID Connectを使ったほうが良い ■ でもあんまりない ● Google, Microsoft, Yahoo, Paypal, Amazon ……… ● 我らがDiscordも提供していない OAuth2を認証に使うということ OAuth2を認証に使う

Slide 47

Slide 47 text

OpenID Connect

Slide 48

Slide 48 text

OpenID Connectとは? ● OpenID Connect ○ 仕組み ■ OAuth2 + IDトークン + UserInfoエンドポイント ○ 用語の違い ■ リソースオーナー -> エンドユーザー ■ クライアント -> リライング・パーティ(RP) ■ 認可サーバ -> IDプロパイダ ■ リソースサーバ -> UserInfoエンドポイント OpenID Connect

Slide 49

Slide 49 text

認可コードフロー OpenID Connect

Slide 50

Slide 50 text

認可コードフロー OpenID Connect

Slide 51

Slide 51 text

● IDトークン ○ IdPが発行し、RPが受け取る ○ 形式 ■ 署名付きJWT ○ 内容 ■ エンドユーザの識別ID(sub) ■ 有効期限・発行日時 ■ 発行者ID・受領者ID ■ トークンの形式・署名方式・署名 IDトークン OpenID Connect

Slide 52

Slide 52 text

● 中身 ○ ヘッダ ■ typクレーム:”JWT” ● JWTであることを表す ■ algクレーム:”RS256” ● 署名方式を表す ● noneは禁止 ● 公開鍵は特定の場所で公開(RFC7517) IDトークン OpenID Connect

Slide 53

Slide 53 text

● 中身 ○ ペイロード ■ issクレーム(issuer) ● IDトークン発行者(IdPのURLなど) ○ 正しい発行者であるかを確認 ■ audクレーム(audience) ● IDトークンを受け取るRPのクライアントID ○ 自分のIDトークンであるか(自分宛に発行されたものか)確認 IDトークン OpenID Connect

Slide 54

Slide 54 text

● 中身 ○ ペイロード ■ subクレーム(subject) ● エンドユーザのuuid(識別子) ○ RPがエンドユーザを識別するためのもの ■ iatクレーム(issued at) ● JWTの発行時間(UNIX Time (sec)) ○ 未来の日時を指していないか確認 IDトークン OpenID Connect

Slide 55

Slide 55 text

● 中身 ○ ペイロード ■ expクレーム(expiration time) ● IDトークンの有効期限 ○ RPはこの期限以降にIDトークンを受け入れてはならない ■ nonceクレーム ● 認証リクエスト時に送ったnonceがそのまま入る ○ IdPが認可コードと紐づけて保管 ○ 攻撃者が認可コードをすりかえることを防ぐ IDトークン OpenID Connect

Slide 56

Slide 56 text

● 中身 ○ 署名 ■ f”{ヘッダ}.{ペイロード}”に対して Base64URLエンコード -> 署名 -> Base64URLエンコード ● ここを検証することでJWTの正当性を担保 ○ たいへんなので各自調べてください ● 認証コードフローでは省略しても良い ○ 改ざんの可能性が限りなく低いため IDトークン OpenID Connect

Slide 57

Slide 57 text

● UserInfoエンドポイント ○ ユーザの特定(認証)以外の用途で ユーザ情報を取得したいときに使う ■ ユーザの識別情報はIDトークンのsubクレームで行う ■ emailや住所などはこっちで取得する ● scope: openid, profile, email, address, phone ● レスポンスのsubとIDトークンのsubの一致を必ず確認 UserInfoエンドポイント OpenID Connect

Slide 58

Slide 58 text

● インプリシットフロー ○ パブリッククライアント向けOIDCフロー ■ 認可コードに関する処理が省かれる ● nonceによって OAuth2のインプリシットフロー脆弱性を防止 ● ハイブリッドフロー ○ バックエンドを持つネイティブアプリ向け ■ 認可コードとアクセストークンがアプリに送られ、 トークンは保存、認可コードはバックエンドに送られる その他のフロー OpenID Connect

Slide 59

Slide 59 text

まとめ OAuth認証は標準化されておらず、不便な部分も 01 OIDCは認証のためのプロトコル(標準化済) 02 OIDCの根幹はIDトークンの検証とnonceにある 03 OAuth2は認可のためのプロトコルである 04 インプリシットフロー以外は認証にも(一応)使える 05

Slide 60

Slide 60 text

参考資料 ● The OAuth 2.0 Authorization Framework ○ © 2012 IETF Trust, Dick Hardt ○ https://datatracker.ietf.org/doc/html/rfc6749 ● The OAuth 2.0 Authorization Framework: Bearer Token Usage ○ © 2012 IETF Trust, Michael B. Jones, Dict Hardt ○ https://datatracker.ietf.org/doc/html/rfc6750 ● The OAuth 2.0 Threat Model and Security Considerations ○ © 2013 IETF Trust, Torsten Lodderstedt, Mark McGloin, Phil Hunt ○ https://datatracker.ietf.org/doc/html/rfc6750

Slide 61

Slide 61 text

参考資料 ● OpenID Connect Core 1.0 incorporating errata set 1 ○ © 2014 The OpenID Foundation ○ http://openid-foundation-japan.github.io/openid-connect-core-1_ 0.ja.html ● OpenID Connect Implicit Client Implementer's Guide 1.0 - draft 2 ○ © 2015 The OpenID Foundation ○ http://openid-foundation-japan.github.io/openid-connect-implicit- 1_0.ja.html

Slide 62

Slide 62 text

参考資料 ● 雰囲気でOAuth2.0を使っているエンジニアが OAuth2.0を整理して、手を動かしながら学べる本 ○ © 2019 Auth屋 ● OAuth、OAuth認証、OpenID Connectの違いを整理して、 理解できる本 ○ © 2019 Auth屋 ● OAuth・OIDCへの攻撃と対策を整理して理解できる本 ○ © 2020 Auth屋