Upgrade to Pro — share decks privately, control downloads, hide ads and more …

30分でOpenID Connect完全に理解したと言えるようになる勉強会

30分でOpenID Connect完全に理解したと言えるようになる勉強会

社内向け勉強会で発表した内容です。
30分でと書いてありますが、実際には50分かかりました。
また時間の関係で結構省いたりしている箇所があります。

2020/07/19追記
ご指摘をいただいた箇所を多々修正いたしました。
特にOIDCとSPAの章が初版とは大幅に変更されていますのでご注意ください。

Twitter: @DddEndow

akkino/D-En

July 16, 2020
Tweet

More Decks by akkino/D-En

Other Decks in Technology

Transcript

  1. 30分で
    OpenID Connect
    完全に理解したと言える
    ようになる勉強会

    View Slide

  2. OAuthとOAuth認証とOpenID Connect
    » OAuthは権限移譲のプロトコル
    » 「OAuth認証」はプロフィールAPIによる認証
    » OpenID ConnectはIDトークンによる認証
    2

    View Slide

  3. いきなり言われてもわからん…
    認証・認可 権限委譲
    IDトークン
    3

    View Slide

  4. OAuthとOpenID Connectの関係
    OAuth
    OpenID
    Connect
    拡張仕様
    基礎となるOAuthを理解していないと
    OpenID Connectを理解するのは難しい
    4

    View Slide

  5. お品書き
    » そもそもOAuthってなに?
    » OAuth認証ってなにが問題なの?
    » OpenID ConnectはOAuthとなにが違うの?
    » ネイティブアプリやSPAではどう使うべき?
    5

    View Slide

  6. 今日しない話
    » OAuthの歴史
    » OAuth2.0の詳細
    » IDトークンの具体的な検証方法
    6

    View Slide

  7. ※注意点
    わかりやすさを優先しているため、一部説明や前提を省
    略しています。
    あらかじめご了承ください。
    7

    View Slide

  8. 0.
    認証・認可
    8

    View Slide

  9. そもそも認証・認可って?
    認可(AuthZ)
    ● リソースアクセス権限をサードパーティのアプリに移譲すること
    ● 誰かに許可を与えること
    認証(AuthN)
    ● 通信の相手が誰であるかを確認すること
    ● 個人の身元の確認
    9

    View Slide

  10. 1.
    OAuth
    10

    View Slide

  11. OAuthとは?
    » 権限委譲のプロトコル
    » 認可のプロトコル
    11

    View Slide

  12. OAuthのメリット
    安全性
    サードパーティアプリにはリソースオー
    ナーのID・パスワードを教える必要がない
    権限委譲
    ユーザのリソースへのアクセス権限を
    サードパーティのアプリに移譲することが
    できる
    12

    View Slide

  13. OAuthのメリット
    安全性
    サードパーティアプリにはリソースオー
    ナーのID・パスワードを教える必要がない
    権限委譲
    ユーザのリソースへのアクセス権限を
    サードパーティのアプリに移譲することが
    できる
    正直なに言ってるかわからん…
    13

    View Slide

  14. OAuthの流れを追ってみる
    14

    View Slide

  15. リソースオーナー
    (ユーザー)
    クライアント
    (自分の作ったアプリ)
    認可サーバー
    (Google OAuth)
    リソースサーバー
    (Google Photo)
    OAuthの登場人物
    15

    View Slide


  16. アプリ上で「Google Photoから画像を
    ダウンロードする」をクリック

    リソースオーナー
    (ユーザー)
    クライアント
    (自分の作ったアプリ)
    認可サーバー
    (Google OAuth)
    リソースサーバー
    (Google Photo)
    16

    View Slide




  17. Google OAuthに対してGoogle Photoの
    アクセス権を要求
    リソースオーナー
    (ユーザー)
    クライアント
    (自分の作ったアプリ)
    認可サーバー
    (Google OAuth)
    リソースサーバー
    (Google Photo)
    17

    View Slide





  18. 「Google Photoへのアクセス権をクライアント
    に委譲すること」についてユーザーの意思を
    確認
    リソースオーナー
    (ユーザー)
    クライアント
    (自分の作ったアプリ)
    認可サーバー
    (Google OAuth)
    リソースサーバー
    (Google Photo)
    18

    View Slide






  19. 権限委譲に同意する
    リソースオーナー
    (ユーザー)
    クライアント
    (自分の作ったアプリ)
    認可サーバー
    (Google OAuth)
    リソースサーバー
    (Google Photo)
    19

    View Slide







  20. 権限が委譲された証としてアクセストークンを
    発行して、クライアントに渡す
    リソースオーナー
    (ユーザー)
    クライアント
    (自分の作ったアプリ)
    認可サーバー
    (Google OAuth)
    リソースサーバー
    (Google Photo)
    20

    View Slide








  21. クライアントはアクセストークンをもってGoogle
    PhotoのAPIにアクセスし、ユーザーの画像を要求
    リソースオーナー
    (ユーザー)
    クライアント
    (自分の作ったアプリ)
    認可サーバー
    (Google OAuth)
    リソースサーバー
    (Google Photo)
    21

    View Slide









  22. Google Photoはアクセストークンの有効性と紐づく権限を確認
    問題がなければユーザーの画像をクライアントに渡す
    リソースオーナー
    (ユーザー)
    クライアント
    (自分の作ったアプリ)
    認可サーバー
    (Google OAuth)
    リソースサーバー
    (Google Photo)
    22

    View Slide








  23. リソースオーナー
    (ユーザー)
    クライアント
    (自分の作ったアプリ)
    認可サーバー
    (Google OAuth)
    リソースサーバー
    (Google Photo)
    こんな大変なことをやる
    メリットってなに?
    23

    View Slide








  24. リソースオーナー
    (ユーザー)
    クライアント
    (自分の作ったアプリ)
    認可サーバー
    (Google OAuth)
    リソースサーバー
    (Google Photo)
    Point 1
    ユーザーのID・パスワードがクライアントに伝わっていない
    →ID・パスワード入力に起因する脆弱性を防げる
    24

    View Slide








  25. リソースオーナー
    (ユーザー)
    クライアント
    (自分の作ったアプリ)
    認可サーバー
    (Google OAuth)
    リソースサーバー
    (Google Photo)
    Point 2
    ユーザーが許可してはじめて権限が委譲される
    ● 勝手にユーザー情報へのアクセスが許可されることはない
    ● 必要最小限の権限のみ委譲
    25

    View Slide








  26. リソースオーナー
    (ユーザー)
    クライアント
    (自分の作ったアプリ)
    認可サーバー
    (Google OAuth)
    リソースサーバー
    (Google Photo)
    Point 3
    アクセストークンで管理している
    ● 誰のリソースのどのような権限に紐づいているのか
    ● クライアントのリソースへのアクセス許可
    26

    View Slide








  27. リソースオーナー
    (ユーザー)
    クライアント
    (自分の作ったアプリ)
    認可サーバー
    (Google OAuth)
    リソースサーバー
    (Google Photo)
    Point 3
    アクセストークンで管理している
    ● 誰のリソースのどのような権限に紐づいているのか
    ● クライアントのリソースへのアクセス許可
    OAuthはアクセストークンを発行するためのルール
    27

    View Slide

  28. クライアント
    (自分の作ったアプリ)
    リソースサーバー
    (Google Photo)
    OAuthのまとめ
    が への限定的なアクセスを
    アクセストークンの発行方法
    (あるユーザーへの必要最小限の範囲の)
    可能にするための
    28

    View Slide

  29. 2.
    OAuth認証
    29

    View Slide

  30. 認証のためのプロトコルという勘違い
    OAuth
    » 権限委譲のためのプロトコル
    » アプリのユーザー認証の話は出てこない
    リソースオーナー
    (ユーザー)
    クライアント
    (自分の作ったアプリ)
    認可サーバー
    (Google OAuth)
    ①権限の委譲依頼 ②許可の確認
    ③委譲許可
    ④アクセストークン発

    30

    View Slide

  31. リソースオーナー
    (ユーザー)
    ③委譲許可
    認証のためのプロトコルという勘違い
    OAuth
    » 権限委譲のためのプロトコル
    » アプリのユーザー認証の話は出てこない
    クライアント
    (自分の作ったアプリ)
    認可サーバー
    (Google OAuth)
    ①権限の委譲依頼 ②許可の確認
    ④アクセストークン発

    じゃあなんでOAuth認証なんて言葉があるの?
    31

    View Slide

  32. プロフィールAPI
    (リソースサーバー)
    OAuth + プロフィールAPI
    だいたいこいつのせい
    32

    View Slide

  33. プロフィールAPI
    (リソースサーバー)
    OAuth + プロフィールAPI
    プロフィールAPI
    » プロフィール情報を提供するAPI
    クライアント
    (自分の作ったアプリ)
    ①アクセストークン
    ②プロフィール情報を
    提供
    33

    View Slide



  34. アクセストークンに紐づくプロフィール情報を要求
    →返されたプロフィール情報のデータで認証
    リソースオーナー
    (ユーザー)
    クライアント
    (自分の作ったアプリ)
    認可サーバー
    (Google OAuth)
    プロフィールAPI
    (リソースサーバー)
    OAuth認証の仕組み
    34

    View Slide

  35. OAuth認証の
    脆弱性
    35

    View Slide

  36. Step 1
    悪意あるアプリが他人のアクセストークンを取得
    →見た目上は普通に動作
    Aさん
    (ユーザー)
    悪意のある
    アプリ
    認可サーバー
    (Google OAuth)
    OAuth認証の脆弱性
    リソースサーバー
    (Google Photo)
    普通に動作
    Aさんのアクセストークン
    36

    View Slide

  37. Step 2
    盗んだアクセストークンに差し替え
    →別のユーザーとしてログインできてしまう!
    悪意のあるユーザー クライアント
    認可サーバー
    (Google OAuth)
    プロフィールAPI
    (リソースサーバー)
    OAuth認証の脆弱性
    盗んだAさんのアクセス
    トークンに差し替え
    Aさんのプロフィール情報
    37

    View Slide

  38. Step 2
    盗んだアクセストークンに差し替え
    →別のユーザーとしてログインできてしまう!
    悪意のあるユーザー クライアント
    認可サーバー
    (Google OAuth)
    プロフィールAPI
    (リソースサーバー)
    OAuth認証の脆弱性
    盗んだAさんのアクセス
    トークンに差し替え
    Aさんのプロフィール情報
    Aさんとしてログイン
    38

    View Slide

  39. 補足:OAuth認証
    39
    FacebookのOAuth認証
    » アクセストークン検証用エンドポイント
    ⋄ /debug_token
    ⋄ 検証用データを取得
    » アクセストークンを検証
    ⋄ すり替えられていないことを担保

    View Slide

  40. プロフィールAPI
    OAuth認証のまとめ
    から取得したプロフィールの情報を
    使用して認証&ログインする方法
    悪意あるアプリによってアクセストークンを盗まれた場合、
    別のユーザーになりすましができる脆弱性がある
    40

    View Slide

  41. 3.
    OpenID Connect
    41

    View Slide

  42. OpenID Connectとは?
    OpenID Connect(OIDC)
    » クライアントが認証できるプロトコル
    » リソースアクセス(認可)も可能
    » OAuthの拡張仕様
    OpenID Connect (OIDC)
    = OAuth + IDトークン + UserInfoエンドポイント
    42

    View Slide

  43. OpenID Connectとは?
    OpenID Connect(OIDC)
    » クライアントが認証できるプロトコル
    » リソースアクセス(認可)も可能
    » OAuthの拡張仕様
    OpenID Connect (OIDC)
    = OAuth + IDトークン + UserInfoエンドポイント
    Point! 43

    View Slide

  44. OpenID Connectとは?
    三種類のフロー
    » 認可フロー
    ⋄ 安全にclient secretを保存できるクライアント用(サーバー)
    » インプリシットフロー
    ⋄ 安全にclient secretを保存できないクライアント用(アプリ)
    » ハイブリットフロー
    ⋄ 安全にアクセストークンや IDトークンを保存できない
    クライアント用(SPA)
    44

    View Slide

  45. OpenID Connectとは?
    三種類のフロー
    » 認可フロー
    ⋄ 安全にclient secretを保存できるクライアント用(サーバー)
    » インプリシットフロー
    ⋄ 安全にclient secretを保存できないクライアント用(アプリ)
    » ハイブリットフロー
    ⋄ 安全にアクセストークンや IDトークンを保存できない
    クライアント用(SPA)
    あとで説明
    45

    View Slide

  46. OpenID Connectとは?
    OAuthのグラントとOIDCのフロー
    46
    OAuth OIDC
    認可コードグラント
    インプリシットグラント
    リソースオーナパスワード
    クレデンシャルグラント
    クライアント クレデンシャルグラント
    ハイブリッドグラント
    認可コードフロー
    インプリシットフロー
    -
    -
    ハイブリッドフロー

    View Slide

  47. OpenID Connectの流れを追ってみる
    47

    View Slide

  48. エンドユーザー リライング・パーティ
    IDプロバイダ
    UserInfoエンド
    OIDCの登場人物
    48

    View Slide

  49. エンドユーザー リライング・パーティ
    IDプロバイダ
    UserInfoエンド
    OIDCの登場人物
    なんか見たことあるような
    …?
    49

    View Slide

  50. OAuth:リソースオーナー
    OIDC:エンドユーザー
    OAuth:クライアント
    OIDC:リライング・パーティ
    OAuth:認可サーバー
    OIDC:IDプロバイダ
    OAuth:リソースサーバー
    OIDC:UserInfoエンド
    OIDCの登場人物
    Point
    ロールの呼び方が違うだけで、役割はOAuthと同じ!
    50

    View Slide





  51. ①〜④
    OAuthと全く同じ
    エンドユーザー リライング・パーティ
    IDプロバイダ
    UserInfoエンド
    51

    View Slide







  52. アクセストークンと一緒にIDトークンを渡す
    エンドユーザー リライング・パーティ
    IDプロバイダ
    UserInfoエンド
    アクセストークン
    IDトークン
    52

    View Slide







  53. IDトークンを検証し、ユーザーを認証する
    エンドユーザー リライング・パーティ
    IDプロバイダ
    UserInfoエンド
    IDトークンを検証

    53

    View Slide







  54. IDトークンを検証し、ユーザーを認証する
    →ログイン完了!
    エンドユーザー リライング・パーティ
    IDプロバイダ
    UserInfoエンド
    IDトークンを検証

    54

    View Slide








  55. ⑦〜⑧(必要があれば)
    アクセストークンを使用してプロフィール情報を取得
    例:名前、アイコン画像、その他個人情報
    エンドユーザー リライング・パーティ
    IDプロバイダ
    UserInfoエンド

    アクセストークン
    55

    View Slide

  56. IDトークンが
    なぜ必要なのか?
    56

    View Slide

  57. IDトークンとは?
    IDトークン
    » リライング・パーティがエンドユーザを認証するために使用
    » 署名付きのJSON Web Token(JWT)
    » ユーザーIDや検証に必要な情報、署名などが含まれる
    57

    View Slide

  58. IDトークンとは?
    IDトークンの中身
    » 誰が、いつ、どの範囲で、と言った(IdPから見た)一連の認証イベ
    ントしての情報が含まれている
    ⋄ ユーザーIDや検証に必要な情報、署名
    ⋄ 発行日時、有効期限
    ⋄ 許可された権限
    58
    適切に検証することで意図するやりとりが行われたことを確認
    できる

    View Slide

  59. IDトークンとは?
    IDトークンの中身
    » 誰が、いつ、どの範囲で、と言った(IdPから見た)一連の認証イベ
    ントしての情報が含まれている
    ⋄ ユーザーIDや検証に必要な情報、署名
    ⋄ 発行日時、有効期限
    ⋄ 許可された権限
    59
    適切に検証することで意図するやりとりが行われたことを確認
    できる
    Point!

    View Slide

  60. 不正ログイン
    を防ぐ仕組み
    60

    View Slide

  61. 注意!
    IDトークン自体の具体的な検
    証方法については触れません
    61

    View Slide

  62. nonceパラメータ
    » リプレイアタックを防ぐためのパラメータ
    » IDトークンに含まれる
    » 毎回異なるランダムな文字列を使用する
    62

    View Slide








  63. エンドユーザー リライング・パーティ
    IDプロバイダ
    UserInfoエンド

    OpenID Connect
    63

    View Slide

  64. OpenID Connectのシーケンス図
    ユーザ リライング・パーティ IDプロバイダ UserInfo
    ①ログイン
    ③〜④認証
    認可コード
    リダイレクト
    トークンリクエスト
    ⑤アクセストークン ・IDトークン
    ⑥IDトークン検証
    リダイレクト
    ②認証リクエスト
    64

    View Slide

  65. OpenID Connectのシーケンス図
    ユーザ リライング・パーティ IDプロバイダ
    ①ログイン
    ③〜④認証
    認可コード
    リダイレクト
    トークンリクエスト
    ⑤アクセストークン ・IDトークン
    ⑥IDトークン検証





    エンドユーザー
    リライング・パーティ
    IDプロバイダ

    リダイレクト
    ②認証リクエスト
    65

    View Slide

  66. OpenID Connectのシーケンス図
    ユーザ リライング・パーティ IDプロバイダ
    ①ログイン
    ③〜④認証
    認可コード
    リダイレクト
    トークンリクエスト
    ⑤アクセストークン ・IDトークン
    ⑥IDトークン検証





    エンドユーザー
    リライング・パーティ
    IDプロバイダ

    リダイレクト
    ②認証リクエスト
    66
    なんか違くない?

    View Slide

  67. OpenID Connectのシーケンス図
    ユーザ リライング・パーティ IDプロバイダ
    ①ログイン
    ③〜④認証
    認可コード
    リダイレクト
    トークンリクエスト
    ⑤アクセストークン ・IDトークン
    ⑥IDトークン検証





    エンドユーザー
    リライング・パーティ
    IDプロバイダ

    リダイレクト
    ②認証リクエスト
    わかりやすくするために簡略化してました
    67
    なんか違くない?

    View Slide

  68. nonceの使い方
    68

    View Slide

  69. OpenID Connectのシーケンス図
    ユーザ リライング・パーティ IDプロバイダ
    ①ログイン
    ③〜④認証
    認可コード
    リダイレクト
    トークンリクエスト
    ⑤アクセストークン ・IDトークン
    ⑥IDトークン検証





    エンドユーザー
    リライング・パーティ
    IDプロバイダ

    リダイレクト
    ②認証リクエスト

    セッションに紐付けてnonce=xyzを発行
    nonce=xyz
    69

    View Slide

  70. OpenID Connectのシーケンス図
    ユーザ リライング・パーティ IDプロバイダ
    ①ログイン
    ③〜④認証
    認可コード
    リダイレクト
    トークンリクエスト
    ⑤アクセストークン ・IDトークン
    ⑥IDトークン検証





    エンドユーザー
    リライング・パーティ
    IDプロバイダ

    リダイレクト
    ②認証リクエスト
    {



    リダイレクトで認証リクエスト
    nonce=xyz
    70

    View Slide

  71. OpenID Connectのシーケンス図
    ユーザ リライング・パーティ IDプロバイダ
    ①ログイン
    ③〜④認証
    認可コード
    リダイレクト
    トークンリクエスト
    ⑤アクセストークン ・IDトークン
    ⑥IDトークン検証





    エンドユーザー
    リライング・パーティ
    IDプロバイダ

    リダイレクト
    ②認証リクエスト
    {



    nonceを認証リクエストに含める
    nonce=xyz
    nonce=xyz
    71

    View Slide

  72. OpenID Connectのシーケンス図
    ユーザ リライング・パーティ IDプロバイダ
    ①ログイン
    ③〜④認証
    認可コード
    リダイレクト
    トークンリクエスト
    ⑤アクセストークン ・IDトークン
    ⑥IDトークン検証





    エンドユーザー
    リライング・パーティ
    IDプロバイダ

    リダイレクト
    ②認証リクエスト
    {
    ③〜④
    ③〜④
    ● ID・パスワードの入力
    ● ユーザ情報提供についての同意確認
    nonce=xyz
    nonce=xyz
    72

    View Slide

  73. OpenID Connectのシーケンス図
    ユーザ リライング・パーティ IDプロバイダ
    ①ログイン
    ③〜④認証
    認可コード
    リダイレクト
    トークンリクエスト
    ⑤アクセストークン ・IDトークン
    ⑥IDトークン検証





    エンドユーザー
    リライング・パーティ
    IDプロバイダ

    リダイレクト
    ②認証リクエスト
    {



    認証レスポンス(認可コード)を返す
    →認可コードはワンタイム(一度使用したら無効化)
    nonce=xyz
    73

    View Slide

  74. OpenID Connectのシーケンス図
    ユーザ リライング・パーティ IDプロバイダ
    ①ログイン
    ③〜④認証
    認可コード
    リダイレクト
    トークンリクエスト
    ⑤アクセストークン ・IDトークン
    ⑥IDトークン検証





    エンドユーザー
    リライング・パーティ
    IDプロバイダ

    リダイレクト
    ②認証リクエスト
    {


    = nonce=xyz
    IDプロバイダ上では認可コードとnonce=xyz
    は紐付けられている
    nonce=xyz
    74

    View Slide

  75. OpenID Connectのシーケンス図
    ユーザ リライング・パーティ IDプロバイダ
    ①ログイン
    ③〜④認証
    認可コード
    リダイレクト
    トークンリクエスト
    ⑤アクセストークン ・IDトークン
    ⑥IDトークン検証





    エンドユーザー
    リライング・パーティ
    IDプロバイダ

    リダイレクト
    ②認証リクエスト
    {


    ● 認可コードを使用してトークンをリクエスト
    ● アクセストークンやIDトークンを取得
    nonce=xyz
    75

    View Slide

  76. OpenID Connectのシーケンス図
    ユーザ リライング・パーティ IDプロバイダ
    ①ログイン
    ③〜④認証
    認可コード
    リダイレクト
    トークンリクエスト
    ⑤アクセストークン ・IDトークン
    ⑥IDトークン検証





    エンドユーザー
    リライング・パーティ
    IDプロバイダ

    リダイレクト
    ②認証リクエスト
    {

    = nonce=xyz
    nonce=xyzが設定されたIDトークンを返す
    nonce=xyz
    nonce=xyz
    76

    View Slide

  77. OpenID Connectのシーケンス図
    ユーザ リライング・パーティ IDプロバイダ
    ①ログイン
    ③〜④認証
    認可コード
    リダイレクト
    トークンリクエスト
    ⑤アクセストークン ・IDトークン
    ⑥IDトークン検証





    エンドユーザー
    リライング・パーティ
    IDプロバイダ

    リダイレクト
    ②認証リクエスト
    {


    nonceの値が一致するか検証
    nonce=xyz
    nonce=xyz
    77

    View Slide

  78. OIDCで
    入れ替えを
    受けた場合
    78

    View Slide

  79. ユーザ リライング・パーティ IDプロバイダ
    ①ログイン
    ③〜④認証
    認可コード
    リダイレクト
    トークンリクエスト
    ⑤アクセストークン ・IDトークン
    ⑥IDトークン検証





    リライング・パーティ
    IDプロバイダ

    リダイレクト
    ②認証リクエスト
    {


    nonce=xyz
    認可コードを入れ替える場合
    悪意あるユーザー
    認可コードを入れ替え
    ちゃえ!
    79

    View Slide

  80. ユーザ リライング・パーティ IDプロバイダ
    ①ログイン
    ③〜④認証
    認可コード
    リダイレクト
    トークンリクエスト
    ⑤アクセストークン ・IDトークン
    ⑥IDトークン検証





    リライング・パーティ
    IDプロバイダ

    リダイレクト
    ②認証リクエスト
    {


    認可コードを入れ替える場合
    悪意あるユーザー
    認可コードを入れ替え
    ちゃえ!
    nonce=abc
    nonce=xyz
    別のリライング・パーティで発行した認可コード
    →nonceが異なる
    80

    View Slide

  81. ユーザ リライング・パーティ IDプロバイダ
    ①ログイン
    ③〜④認証
    認可コード
    リダイレクト
    トークンリクエスト
    ⑤アクセストークン ・IDトークン
    ⑥IDトークン検証





    リライング・パーティ
    IDプロバイダ

    リダイレクト
    ②認証リクエスト
    {

    = nonce=abc
    認可コードに紐づくnonceが含まれるIDトーク
    ンを返す
    nonce=abc
    nonce=xyz
    悪意あるユーザー
    認可コードを入れ替える場合
    81

    View Slide

  82. ユーザ リライング・パーティ IDプロバイダ
    ①ログイン
    ③〜④認証
    認可コード
    リダイレクト
    トークンリクエスト
    ⑤アクセストークン ・IDトークン
    ⑥IDトークン検証





    リライング・パーティ
    IDプロバイダ

    リダイレクト
    ②認証リクエスト
    {

    セッションに紐づくnonceと
    IDトークンのnonceが異なる!
    nonce=abc
    nonce=xyz
    悪意あるユーザー
    認可コードを入れ替える場合
    82

    View Slide

  83. ユーザ リライング・パーティ IDプロバイダ
    ①ログイン
    ③〜④認証
    認可コード
    リダイレクト
    トークンリクエスト
    ⑤アクセストークン ・IDトークン
    ⑥IDトークン検証





    リライング・パーティ
    IDプロバイダ

    リダイレクト
    ②認証リクエスト
    {

    セッションに紐づくnonceと
    IDトークンのnonceが異なる!
    nonce=abc
    nonce=xyz
    悪意あるユーザー
    ログイン失敗!
    認可コードを入れ替える場合
    83

    View Slide





  84. リライング・パーティ
    IDプロバイダ

    補足:リプレイアタック対策
    84

    エンドユーザー
    一度使用した認可コードは無効化される
    (ワンタイム)

    View Slide





  85. リライング・パーティ
    IDプロバイダ

    補足:リプレイアタック対策
    85

    エンドユーザー
    通信が傍受され、使用済みの認可コードが盗
    まれた場合
    悪意あるユーザー

    View Slide





  86. リライング・パーティ
    IDプロバイダ

    補足:リプレイアタック対策
    86

    使用済みの認可コードの場合
    既に無効化されているのでトークンは発行
    されない
    悪意あるユーザー

    View Slide

  87. “アンチパターン”
    nonceを固定値にした場合
    87

    View Slide

  88. ユーザ リライング・パーティ IDプロバイダ
    ①ログイン
    ③〜④認証
    認可コード
    リダイレクト
    トークンリクエスト
    ⑤アクセストークン ・IDトークン
    ⑥IDトークン検証





    リライング・パーティ
    IDプロバイダ

    リダイレクト
    ②認証リクエスト
    {


    認可コードを入れ替える場合
    悪意あるユーザー
    認可コードを入れ替え
    ちゃえ!
    nonce=xyz
    nonce=xyz
    異なるリライング・パーティでもnonceの値が固定
    88

    View Slide

  89. ユーザ リライング・パーティ IDプロバイダ
    ①ログイン
    ③〜④認証
    認可コード
    リダイレクト
    トークンリクエスト
    ⑤アクセストークン ・IDトークン
    ⑥IDトークン検証





    リライング・パーティ
    IDプロバイダ

    リダイレクト
    ②認証リクエスト
    {

    セッションに紐づくnonceと
    IDトークンのnonceが一致!
    nonce=xyz
    nonce=xyz
    悪意あるユーザー
    認可コードを入れ替える場合
    89

    View Slide

  90. ユーザ リライング・パーティ IDプロバイダ
    ①ログイン
    ③〜④認証
    認可コード
    リダイレクト
    トークンリクエスト
    ⑤アクセストークン ・IDトークン
    ⑥IDトークン検証





    リライング・パーティ
    IDプロバイダ

    リダイレクト
    ②認証リクエスト
    {

    セッションに紐づくnonceと
    IDトークンのnonceが一致!
    nonce=xyz
    nonce=xyz
    悪意あるユーザー
    認可コードを入れ替える場合
    不正ログイン成功!
    ぐへへ
    90

    View Slide

  91. OpenID Connectまとめ
    » クライアントが認証できるプロトコル
    » IDトークンを使用して安全に認証する
    » Nonceはランダムな文字列にし、必ず検証する
    » 認可コードをワンタイムにすることでリプレイアタックを防

    91

    View Slide

  92. 4.
    OIDCとネイティブアプリ
    92

    View Slide

  93. ネイティブアプリでのOIDC
    » client secretを秘匿に保てない
    ⋄ 認可コードフローだとトークン取得時に漏洩する
    ⋄ 自由に認可コードやトークンが発行可能に!
    » 長期間有効なAPIアクセスを必要とする
    リライング・パーティ IDプロバイダ
    認証リクエスト
    (client_id, client_secret)
    認証レスポンス
    (認可コード)
    93

    View Slide

  94. インプリシットフロー
    ClientSecretを安全に保存できないため、それを使用せず認可
    コードフローを簡略化したフロー
    » クライアントの認証がIDプロバイダで行われない
    ⋄ client secretを使用せずにトークンの発行が可能
    » リフレッシュトークンの発行が禁止
    ⋄ 再取得時にはインプリシットフローを再度行う必要がある
    94

    View Slide

  95. インプリシットフローのシーケンス図
    ユーザ リライング・パーティ IDプロバイダ UserInfo
    ログイン
    認証
    アクセストークン・IDトークン
    リダイレクト
    IDトークン検証
    リダイレクト
    認証リクエスト
    95

    View Slide

  96. シーケンス図の比較
    ユーザ リライング・パーティ IDプロバイダ
    ログイン
    認証
    認可コード
    リダイレクト
    トークンリクエスト
    アクセストークン ・IDトークン
    IDトークン検証
    リダイレクト
    認証リクエスト
    ユーザ リライング・パーティ IDプロバイダ
    ログイン
    認証
    アクセストークン・IDトークン
    リダイレクト
    IDトークン検証
    リダイレクト
    認証リクエスト
    インプリシットフロー 認可コードフロー
    96

    View Slide

  97. シーケンス図の比較
    ユーザ リライング・パーティ IDプロバイダ
    ログイン
    認証
    認可コード
    リダイレクト
    トークンリクエスト
    アクセストークン ・IDトークン
    IDトークン検証
    リダイレクト
    認証リクエスト
    ユーザ リライング・パーティ IDプロバイダ
    ログイン
    認証
    アクセストークン・IDトークン
    リダイレクト
    IDトークン検証
    リダイレクト
    認証リクエスト
    インプリシットフロー 認可コードフロー
    かなりシンプルに!
    直接受け取るのが特徴
    97

    View Slide

  98. インプリシットフローの問題点
    リソースアクセスと併用する場合
    » IdPによってはアクセストークンの有効期限が切れるたびに再認証
    が必要
    ⋄ 数分〜数時間に一度ログイン画面が表示されてしまう
    →どうしてもユーザー体験が下がってしまう
    98

    View Slide

  99. インプリシットフローの問題点
    リソースアクセスと併用する場合
    » IdPによってはアクセストークンの有効期限が切れるたびに再認証
    が必要
    ⋄ 数分〜数時間に一度ログイン画面が表示されてしまう
    →どうしてもユーザー体験が下がってしまう
    99
    安全にリフレッシュトークンが
    発行できればなー・・・

    View Slide

  100. PKCE(ピクシー)
    » OAuthの拡張仕様
    » パブリッククライアントで認可コードフローを安全に行
    う仕組み
    ⋄ ClientSecretを安全に保存できないことへの対策
    ⋄ 認可コードの横取り攻撃を防ぐ
    ⋄ 認可コードフローなので Refresh Tokenが取得可能
    安全にリフレッシュトークンが取得できる!
    100

    View Slide

  101. パブリックとコンフィデンシャル
    » パブリッククライアント
    ⋄ クライアントの認証情報( ClientID, ClientSecret)をセキュアに保
    存できないクライアント
    ⋄ ネイティブアプリやブラウザベースのアプリ
    » コンフィデンシャルクライアント
    ⋄ クライアントの認証情報をセキュアに保存できるクライアント
    ⋄ サーバーなど
    101

    View Slide

  102. 認可コード横取り攻撃
    » 以下のような場合、開発者が入れ替わりを防ぐのは困難
    ⋄ 悪意のあるアプリが同時にインストールされている
    ⋄ 悪意あるアプリで同じカスタムスキームが設定されている
    ⋄ 悪意あるアプリがクライアント IDを知っている
    102

    View Slide

  103. 認可コード横取り攻撃
    » 以下のような場合、開発者が入れ替わりを防ぐのは困難
    ⋄ 悪意のあるアプリが同時にインストールされている
    ⋄ 悪意あるアプリで同じカスタムスキームが設定されている
    ⋄ 悪意あるアプリがクライアント IDを知っている
    PKCEでの対策
    入れ替わりが発生した場合、アクセストークンを発行させない
    103

    View Slide

  104. PKCE(ピクシー)での対策
    以下の三つの値を使用して対策
    » code_verifier
    ⋄ ランダムな文字列
    » code_challenge
    ⋄ code_verifierにcode_challenge_methodを適応して算出した値
    » code_challenge_method
    ⋄ plainまたはS256
    104

    View Slide

  105. 認可コードフロー+PKCEのシーケンス図
    ユーザ ネイティブアプリ
    ログイン
    認証
    カスタムスキームによるアプリ起動
    (認可コード)
    IDトークン検証
    認可リクエスト
    code_challenge
    code_challenge_method
    ブラウザ
    code_challenge
    code_challenge_method
    を保存
    認可レスポンス
    (認可コード)
    アクセストークン ・IDトークン
    code_verifier検証
    認可リクエスト
    code_challenge
    code_challenge_method
    IDプロバイダ(認可サーバー)
    トークンリクエスト
    認可コード、code_verifier
    105

    View Slide

  106. 認可コードフロー+PKCEのシーケンス図
    ユーザ ネイティブアプリ IDプロバイダ(認可サーバー)
    ログイン
    認証
    カスタムスキームによるアプリ起動
    (認可コード)
    IDトークン検証
    認可リクエスト
    code_challenge
    code_challenge_method
    ブラウザ
    code_challenge
    code_challenge_method
    を保存
    認可レスポンス
    (認可コード)
    アクセストークン ・IDトークン
    code_verifier検証
    認可リクエスト
    code_challenge
    code_challenge_method
    トークンリクエスト
    認可コード、code_verifier
    Step 1
    code_challengeとcode_challenge_methodをIDプロバイダに保存
    106

    View Slide

  107. 認可コードフロー+PKCEのシーケンス図
    ユーザ ネイティブアプリ IDプロバイダ(認可サーバー)
    ログイン
    認証
    カスタムスキームによるアプリ起動
    (認可コード)
    IDトークン検証
    認可リクエスト
    code_challenge
    code_challenge_method
    ブラウザ
    code_challenge
    code_challenge_method
    を保存
    認可レスポンス
    (認可コード)
    トークンリクエスト
    認可コード、code_verifier
    アクセストークン ・IDトークン
    code_verifier検証
    認可リクエスト
    code_challenge
    code_challenge_method
    Step 2
    code_verifierをトークンリクエストに含める
    107

    View Slide

  108. 認可コードフロー+PKCEのシーケンス図
    ユーザ ネイティブアプリ IDプロバイダ(認可サーバー)
    ログイン
    認証
    カスタムスキームによるアプリ起動
    (認可コード)
    IDトークン検証
    認可リクエスト
    code_challenge
    code_challenge_method
    ブラウザ
    code_challenge
    code_challenge_method
    を保存
    認可レスポンス
    (認可コード)
    トークンリクエスト
    認可コード、code_verifier
    アクセストークン ・IDトークン
    code_verifier検証
    認可リクエスト
    code_challenge
    code_challenge_method
    Step 3
    事前に保存したcode_challengeと
    code_challenge_methodでcode_verifierを検証
    108

    View Slide

  109. 認可コード
    横取り攻撃を
    受けた場合
    109

    View Slide

  110. 認可コード横取り攻撃を受けた場合
    ユーザ ネイティブアプリ
    ログイン
    認証
    カスタムスキームによるアプリ起動
    (認可コード)
    IDトークン検証
    認可リクエスト
    code_challenge
    code_challenge_method
    ブラウザ
    code_challenge
    code_challenge_method
    を保存
    認可レスポンス
    (認可コード)
    アクセストークン ・IDトークン
    code_verifier検証
    認可リクエスト
    code_challenge
    code_challenge_method
    IDプロバイダ(認可サーバー)
    トークンリクエスト
    認可コード、code_verifier
    悪意あるアプリ
    横取りしたぜ!
    110

    View Slide

  111. 認可コード横取り攻撃を受けた場合
    ユーザ ネイティブアプリ
    ログイン
    認証
    カスタムスキームによるアプリ起動
    (認可コード)
    IDトークン検証
    認可リクエスト
    code_challenge
    code_challenge_method
    ブラウザ
    code_challenge
    code_challenge_method
    を保存
    認可レスポンス
    (認可コード)
    アクセストークン ・IDトークン
    code_verifier検証
    認可リクエスト
    code_challenge
    code_challenge_method
    IDプロバイダ(認可サーバー)
    トークンリクエスト
    認可コード、code_verifier
    悪意あるアプリ
    code_verifierがわか
    らない…ぐぬぬ
    検証失敗!
    トークンレスポンスは無し
    111

    View Slide

  112. OIDCとネイティブアプリのまとめ
    » client secretを保存するのは厳禁
    » 認証だけでいいならインプリシットフロー(非推奨)
    » UXを考えるなら認証コードフロー+PKCE(推奨)
    112
    Tips
    OAuth2.1ではインプリシットフローはなくなるので注意

    View Slide

  113. 5.
    OIDCとSPA
    113

    View Slide

  114. SPAでのOIDC
    SPA(ブラウザ)では安全にアクセストークンやIDトークンが保存
    できない
    » Web Storage(localStorageやsessionStorage)に保存
    ⋄ 自分のアプリでXSS対策をしても他のJSが悪さをすると台無し
    » iFrameでIdPとのセッションをメモリ上に格納
    ⋄ サードパーティCookieを保持するのはNGな流れになってきた
    →今のところベストプラクティスはない
    114

    View Slide

  115. SPAでのOIDC
    二つの対策
    » 認可コードフロー+独自のセッション
    » RefreshTokenをローテーションする(Auth0など)
    115

    View Slide

  116. 認可コードフロー+独自セッション
    116

    View Slide

  117. 認可コードフロー+独自セッション
    » OIDCをログイン管理に使用しない
    ⋄ 認証のみに使用する
    ⋄ 独自のセッション(cookieなど)でログイン管理を行う
    フロント
    ネイティブアプリ
    IDプロバイダ
    バックエンド
    認可コード トークンリクエスト
    アクセストークン
    IDトークン
    独自セッション
    117

    View Slide

  118. ユーザ
    リライング・パーティ
    フロント IDプロバイダ UserInfo
    リライング・パーティ
    バックエンド
    ログイン
    認証
    認証レスポンス(認可コード )
    リダイレクト
    認可コード
    トークンリクエスト
    アクセストークン ・IDトークン
    IDトークン検証
    独自セッション
    nonceやcode_challengeを生成
    118

    View Slide

  119. ユーザ
    リライング・パーティ
    フロント IDプロバイダ UserInfo
    リライング・パーティ
    バックエンド
    ログイン
    認証
    認証レスポンス(認可コード )
    リダイレクト
    認可コード
    トークンリクエスト
    アクセストークン ・IDトークン
    IDトークン検証
    独自セッション
    Point 1
    フロントとバックエンドであらかじめセッションを構築
    →バックエンドでnonceやPKCEに必要な値を生成し、セッションに紐づ
    ける
    nonceやcode_challengeを生成
    119

    View Slide

  120. ユーザ
    リライング・パーティ
    フロント IDプロバイダ UserInfo
    リライング・パーティ
    バックエンド
    ログイン
    認証
    認証レスポンス(認可コード )
    リダイレクト
    認可コード
    トークンリクエスト
    アクセストークン ・IDトークン
    IDトークン検証
    独自セッション
    Point 2
    認可コードをバックエンドにリクエストする
    nonceやcode_challengeを生成
    120

    View Slide

  121. ユーザ
    リライング・パーティ
    フロント IDプロバイダ UserInfo
    リライング・パーティ
    バックエンド
    ログイン
    認証
    認証レスポンス(認可コード )
    リダイレクト
    認可コード
    トークンリクエスト
    アクセストークン ・IDトークン
    IDトークン検証
    独自セッション
    Point 3
    バックエンドでトークンを取得
    nonceやcode_challengeを生成
    121

    View Slide

  122. ユーザ
    リライング・パーティ
    フロント IDプロバイダ UserInfo
    リライング・パーティ
    バックエンド
    ログイン
    認証
    認証レスポンス(認可コード )
    リダイレクト
    認可コード
    トークンリクエスト
    アクセストークン ・IDトークン
    IDトークン検証
    独自セッション
    Point 4
    セッションに紐づくnonceやcode_verifierで検証する
    必要であればこのタイミングでUserInfoからプロフィール情報を取得の
    する
    nonceやcode_challengeを生成
    122

    View Slide

  123. ユーザ
    リライング・パーティ
    フロント IDプロバイダ UserInfo
    リライング・パーティ
    バックエンド
    ログイン
    認証
    認証レスポンス(認可コード )
    リダイレクト
    認可コード
    トークンリクエスト
    アクセストークン ・IDトークン
    IDトークン検証
    独自セッション
    Point 5
    以後全てセッションで管理する
    アクセストークンやIDトークンはフロントに一切渡らない
    nonceやcode_challengeを生成
    123

    View Slide

  124. 認可コードフロー+独自セッション
    まとめ
    » フロントにトークン類を保持しないのでセキュア
    ⋄ セッションにユーザー IDなどの識別子を含めないように注意
    ⋄ CSRF対策も忘れずに
    » SPAとネイティブアプリを同時に使用する場合はバックエン
    ドの実装を分ける必要がある
    » 実装が割と手間
    124

    View Slide

  125. RefreshTokenのローテーション
    125

    View Slide

  126. RefreshTokenをローテーションする
    » RefreshTokenを使用して新しいトークンを発行する時
    ⋄ →古いRefreshTokenは無効化&新しいRefreshTokenを発行
    ⋄ OAuthの仕様だと自動では無効化されない
    » 古いRefreshTokenでアクセスされた場合、全てのRefreshTokenを無
    効化
    » IdP側に仕組みが必要(Auth0などがサポート)
    126

    View Slide

  127. クライアント
    (SPA)
    認可サーバー
    (Google OAuth)
    RefreshTokenのローテーション
    リフレッシュトークン
    新しいアクセストークン
    新しいIDトークン
    新しいリフレッシュトークン
    通常のトークンリフレッシュ
    127

    View Slide

  128. クライアント
    (SPA)
    認可サーバー
    (Google OAuth)
    RefreshTokenのローテーション
    リフレッシュトークン
    新しいアクセストークン
    新しいIDトークン
    新しいリフレッシュトークン
    通常のトークンリフレッシュ
    悪意あるユーザー
    使用済みのリフレッシュトークン
    横取りしたぜ!
    128

    View Slide

  129. クライアント
    (SPA)
    認可サーバー
    (Google OAuth)
    RefreshTokenのローテーション
    リフレッシュトークン
    新しいアクセストークン
    新しいIDトークン
    新しいリフレッシュトークン
    通常のトークンリフレッシュ
    悪意あるユーザー
    無効化されてないからア
    クセスし放題!
    2回目以降は新しいリフレッ
    シュトークンを使用する
    129

    View Slide

  130. クライアント
    (SPA)
    認可サーバー
    (Google OAuth)
    RefreshTokenのローテーション
    リフレッシュトークン
    新しいアクセストークン
    新しいIDトークン
    新しいリフレッシュトークン
    Auth0のトークンリフレッシュ 古いリフレッシュトークン
    を無効化
    130

    View Slide

  131. クライアント
    (SPA)
    認可サーバー
    (Google OAuth)
    RefreshTokenのローテーション
    リフレッシュトークン
    新しいアクセストークン
    新しいIDトークン
    新しいリフレッシュトークン
    Auth0のトークンリフレッシュ
    悪意あるユーザー
    使用済みのリフレッシュトークン
    横取りしたぜ!
    131

    View Slide

  132. クライアント
    (SPA)
    認可サーバー
    (Google OAuth)
    RefreshTokenのローテーション
    リフレッシュトークン
    新しいアクセストークン
    新しいIDトークン
    新しいリフレッシュトークン
    Auth0のトークンリフレッシュ
    悪意あるユーザー
    無効化されてるからトーク
    ンを更新できない…
    既に無効化されてるリフレッ
    シュトークンが使用された!
    132

    View Slide

  133. クライアント
    (SPA)
    認可サーバー
    (Google OAuth)
    RefreshTokenのローテーション
    リフレッシュトークン
    新しいアクセストークン
    新しいIDトークン
    新しいリフレッシュトークン
    Auth0のトークンリフレッシュ
    悪意あるユーザー
    無効化されてるからトーク
    ンを更新できない…
    既に無効化されてるリフレッ
    シュトークンが使用された!
    トークンが漏洩している可能性あり!
    未使用のリフレッシュトークンも無効化!
    133

    View Slide

  134. RefreshTokenのローテーション
    まとめ
    » リフレッシュトークンを盗難されても被害を最小限にとどめ

    » IdP側での実装が必要
    » トークンを盗まれるの自体は防げない
    ⋄ トークンの有効期限を短くすることで対策
    134

    View Slide

  135. OIDCとSPAのまとめ
    » SPAでトークンを安全に保管する方法は今のところ存在し
    ない
    » OIDCを認証として使用し、独自のセッションでログイン管理
    を行う(推奨)
    » RefreshTokenをローテーションする(Auth0など)
    135

    View Slide

  136. 6.
    おまけ
    ハイブリッドフロー
    136

    View Slide

  137. ハイブリッドフロー
    » ハイブリッドフロー
    ⋄ 認可コードフローとインプリシットフローを合わせたもの
    ⋄ 認可レスポンスとトークンレスポンスの両方があるのが特徴
    フロント
    ネイティブアプリ
    IDプロバイダ
    バックエンド
    認可コード トークンリクエスト
    アクセストークン
    IDトークン
    認証完了
    137
    認証リクエスト
    認可コード・アクセストークン

    View Slide

  138. ユーザ
    リライング・パーティ
    ネイティブアプリ IDプロバイダ UserInfo
    リライング・パーティ
    バックエンド
    ログイン
    認証
    認証レスポンス(認可コード ・アクセストークン)
    リダイレクト
    認可コード
    トークンリクエスト
    アクセストークン ・IDトークン
    IDトークン検証
    認証完了
    138

    View Slide

  139. ユーザ
    リライング・パーティ
    ネイティブアプリ IDプロバイダ UserInfo
    リライング・パーティ
    バックエンド
    ログイン
    認証
    認証レスポンス(認可コード ・アクセストークン)
    リダイレクト
    認可コード
    トークンリクエスト
    アクセストークン ・IDトークン
    IDトークン検証
    認証完了
    139
    Point 1
    認可コードとアクセストークンを受け取る。
    アクセストークンはネイティブアプリ側に保存

    View Slide

  140. ユーザ
    リライング・パーティ
    ネイティブアプリ IDプロバイダ UserInfo
    リライング・パーティ
    バックエンド
    ログイン
    認証
    認証レスポンス(認可コード ・アクセストークン)
    リダイレクト
    認可コード
    トークンリクエスト
    アクセストークン ・IDトークン
    IDトークン検証
    認証完了
    140
    Point 2
    認可コードをバックエンドにリクエストする

    View Slide

  141. ユーザ
    リライング・パーティ
    ネイティブアプリ IDプロバイダ UserInfo
    リライング・パーティ
    バックエンド
    ログイン
    認証
    認証レスポンス(認可コード ・アクセストークン)
    リダイレクト
    認可コード
    トークンリクエスト
    アクセストークン ・IDトークン
    IDトークン検証
    認証完了
    141
    Point 3
    バックエンドでセキュアにトークンを取得可能

    View Slide

  142. ユーザ
    リライング・パーティ
    ネイティブアプリ IDプロバイダ UserInfo
    リライング・パーティ
    バックエンド
    ログイン
    認証
    認証レスポンス(認可コード ・アクセストークン)
    リダイレクト
    認可コード
    トークンリクエスト
    アクセストークン ・IDトークン
    IDトークン検証
    認証完了
    142
    Point 4
    IDトークンを検証する

    View Slide

  143. ユーザ
    リライング・パーティ
    ネイティブアプリ IDプロバイダ UserInfo
    リライング・パーティ
    バックエンド
    ログイン
    認証
    認証レスポンス(認可コード ・アクセストークン)
    リダイレクト
    認可コード
    トークンリクエスト
    アクセストークン ・IDトークン
    IDトークン検証
    認証完了
    143
    Point 5
    アクセストークンを保存しているため、
    ネイティブ側からもリソースにアクセスが可能となる

    View Slide

  144. ハイブリッドフローのまとめ
    » 認可コードフローとインプリシットフローを合わせたもの
    ⋄ 認可レスポンスとトークンレスポンスの両方があるのが特徴
    » バックエンド側でセキュアに認証が可能
    » パブリック(ネイティブアプリ)側からリソースにアクセスすることが
    可能
    144

    View Slide

  145. Last.
    まとめ
    145

    View Slide

  146. 今日の話
    まとめ
    » OAuthの概要
    » OAuth認証はNG
    » OpenID Connectの検証はしっかりと行う
    » ネイティブアプリとSPAでのOIDCの注意点
    146

    View Slide

  147. “IDトークンを検証したからといって
    安全になるわけではありません。”
    “OpenID Connectを正しく理解して使用しましょう。”
    147

    View Slide

  148. Special Thanks!
    Auth屋
    ● 書籍:雰囲気でOAuth2.0を使っているエンジニアが
    OAuth2.0
    を整理して、手を動かしながら学べる本
    ● 書籍:OAuth、OAuth認証、OpenID Connectの違いを整理して
    理解できる本
    ritou
    ● ブログ:r-weblife
    148

    View Slide

  149. Thank you
    watching!
    遠藤 大輔
    Twitter: @DddEndow
    149

    View Slide