Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

OAuth2.0によるWeb APIの保護

7,320 views

Published on

Japan Web API Community #01 で使った資料です。
OAuth 2.0 の概要と Azure AD を使った API 保護の紹介をしています。

Published in: Technology
  • Be the first to comment

OAuth2.0によるWeb APIの保護

  1. 1. OAuth 2.0 による Web API の保護 2016.12.21 Japan Web API Community #1 Naohiro Fujie @phr_eidentity
  2. 2. 自己紹介 • Blog • IdM実験室:http://idmlab.eidentity.jp • Modules(codeplex) • Generic REST MA for FIM/MIM:https://restmafim.codeplex.com/ • 記事 / 書籍 • 記事 : @IT/企業のID管理/シングルサインオンの新しい選択肢「IDaaS」の活用 他 • 監訳 : クラウド時代の認証基盤 Azure Active Directory 完全解説 • 共著 : クラウド環境におけるアイデンティティ管理ガイドライン • その他 • JNSA アイデンティティ管理WG • OpenID Foundation Japan 教育・翻訳WG、エンタープライズ・アイデンティティWG • Microsoft MVP for Enterprise Mobility(Jan 2010 -) © 2016 Naohiro Fujie 2
  3. 3. Agenda 1. WebAPI に求められるセキュリティ • 利用者から見た課題 • API 提供者から見た課題 2. OAuth 2.0 の概要と課題への対応 3. デモ • Azure AD による WebAPI の保護 • ADAL による API クライアントの実装 © 2016 Naohiro Fujie 3
  4. 4. WebAPI に求められる セキュリティ © 2016 Naohiro Fujie 4
  5. 5. WebAPI 利用・提供時の課題 • いかにして API クライアントを信頼するか? • 利用者の視点 • API を通して提供される自身のデータを悪用されたくない • API 提供者の視点 • 誰が利用しているのかを明確にしたい(例:課金) • 人の識別 • API クライアントの識別 • 提供するデータを悪用されたくない © 2016 Naohiro Fujie 5 http(s)でインターネット上に 公開しているので、Firewall 等による分離は難しい API クライアントは便利だけ ど、間接的に自身のデータへ アクセスされるのは怖い API の基本は単機能。ユーザ 認証・認可機能を API 毎に開 発したくない 適切な API クライアントから だけアクセスさせたい
  6. 6. 利用者から見た課題 © 2016 Naohiro Fujie 6
  7. 7. 従来の Web アプリケーションの利用 • ユーザ自身によりコンテキストの使い分けが可能 • Facebookの友達からはアプリA、Twitter上のアイデンティティとの紐 づけをされても良いが、反対は嫌 • 情報は二重管理 © 2016 Naohiro Fujie 7 実名、電話番号を登録 ニックネームを登録 Twitterには同僚に知られたく ない性癖を投稿しているので、 実名は登録したくない Facebookの友達は近しい人 ばかりなので、実名や電話番 号を登録しておきたい アプリA ニックネームと電話番号を登録 アプリAにはニックネームと 電話番号を登録したい・・・ 二重管理は面倒
  8. 8. 上手く API を使って二重管理をやめたい • アプリにFacebookとTwitterのIDとパスワードを登録する? © 2016 Naohiro Fujie 8 実名、電話番号を登録 ニックネームを登録 アプリA (APIクラ イアント) ニックネームと 電話番号を使わせたい ユーザのID/PWDを使って Facebookへアクセス 複数のサービスに同じ情報を 登録するのは面倒なので便利 なマッシュアップ・アプリを 使いたい ユーザのID/PWDを使って Twitterへアクセス
  9. 9. パスワード? • アプリ上に個人のパスワードを登録するのは・・・ © 2016 Naohiro Fujie 9 実名、電話番号を登録 ニックネームを登録 アプリA (APIクラ イアント) ニックネームと 電話番号を使わせたい ユーザのID/PWDを使って Facebookへアクセス ユーザのID/PWDを使って Twitterへアクセス パスワードを登録しておくの はかなり嫌・・・ 漏えい?変更時の運用?
  10. 10. コンテキストが混ざる • せっかく分けていたコンテキストがアプリで混ざる © 2016 Naohiro Fujie 10 実名、電話番号を登録 ニックネームを登録 アプリA (APIクラ イアント) ニックネームと 電話番号を使わせたい 電話番号だけが欲しいのに、 実名もとれてしまう? このアプリ上でコンテキスト が混ざってしまう
  11. 11. 課題:パスワード、コンテキスト パスワードを使わずに どうやってユーザの代わりに 「望んだ範囲に限定して」 アクセスさせるか? © 2016 Naohiro Fujie 11 実名、電話番号を登録 ニックネームを登録 アプリA (APIクラ イアント) ニックネームと 電話番号を使わせたい パスワードを登録しておくの はかなり嫌・・・ 漏えい?変更時の運用? このアプリ上でコンテキスト が混ざってしまう
  12. 12. API 提供者から見た課題 © 2016 Naohiro Fujie 12
  13. 13. 従来の Web アプリケーションの利用 • ユーザが直接アプリを利用していたので識別は簡単 • 個々に認証機能や UI 開発が必要 © 2016 Naohiro Fujie 13 直接ログイン 直接ログイン アプリA 直接ログイン 個々に運用・管理。 識別は簡単だが、個々に機能 開発が必要
  14. 14. API を公開してシンプルにしたい • ユーザが直接アプリを利用していたので識別は簡単 • 個々に認証機能や UI 開発が必要 © 2016 Naohiro Fujie 14 アプリA (APIクラ イアント) シンプルな機能・データ提供 だけを API で行いたい 利用 アプリ経由で利用 アプリ経由で利用
  15. 15. アクセス元の特定・真贋が難しい • アクセス元アプリの信頼性の担保が難しい © 2016 Naohiro Fujie 15 アプリA (APIクラ イアント) 誰がどのアプリ経由が使って いるのかわからない? 利用 アプリ経由で利用 アプリ経由で利用このアプリは信頼できるの か? 特定アプリ以外からの アクセスを防げない?
  16. 16. 課題:利用元の特定と管理 • どうやって「許可された」 アプリからのみ アクセスを許可 するか? © 2016 Naohiro Fujie 16 アプリA (APIクラ イアント) 利用 アプリ経由で利用 アプリ経由で利用このアプリは信頼できるの か? 特定アプリ以外からの アクセスを防げない? 誰がどのアプリ経由が使って いるのかわからない?
  17. 17. OAuth 2.0 の概要と 課題への対応 © 2016 Naohiro Fujie 17
  18. 18. OAuth の概要と基本的な考え方 • 目的 • リソースへのアクセスを安全に認可(委譲)すること • 基本的な考え方 • リソース(API を通して提供される機能やデータ)の持ち主はユーザ である • ユーザの同意に基づき API クライアントに対してリソースへのアクセ ス権限を認可(委譲)する • 認証(検証)された API クライアントに対してのみリソースを提供す る © 2016 Naohiro Fujie 18
  19. 19. 構成要素 • 保護対象リソース • API を経由して提供される機能やデータなどのリソース • リソース・オーナー • 保護対象となるリソースの持ち主(ユーザ) • クライアント • 保護対象リソースへアクセスする主体(API クライアント) • 認可サーバ • 保護対象リソースへのアクセスを認可するためのサーバ © 2016 Naohiro Fujie 19
  20. 20. 保護対象リソース (API 、データ) 各構成要素の関係性 © 2016 Naohiro Fujie 20 クライアント 認可サーバ リソース・オーナー 所有 登録 認可 利用 登録 保護 利用
  21. 21. 保護対象リソース (API 、データ) 実際の動き(認可コードグラント) © 2016 Naohiro Fujie 21 クライアント 認可サーバ リソース・オーナー 所有 登録 認可 利用 登録 保護 利用 1.利用したい 2.認可要求 3.認可要求 (同意) 4.認可コードの 発行 5.認可コードの 提供 6.認可コードと アクセストークン の交換 8.アクセストー クンの検証 7.アクセストー クンの提示 9.リソースの 提供
  22. 22. シーケンス(認可コードグラント) © 2016 Naohiro Fujie 22 リソース・オーナー (利用者/UserAgent) クライアント (アプリケーション) 認可サーバ (OAuthサーバ) 保護対象リソース (API・データ) フロー開始 ユーザ認証・同意 認可エンドポイントへリダイレクト (クライアントID、スコープを含む) クライアントへリダイレクト (認可コードを含む) アクセストークンを要求 (認可コード、クライアントID、Secretを含む) アクセストークンを発行 リソース要求(アクセストークンを含む) アクセストークンの検証 リソースの提供 クライアントに許可する範囲 (スコープ)指定が可能 オーナー(ユーザ)の同意に 基づくアクセスが可能 許可されたクライアントのみ からアクセスする為の認証 パスワードではなく、アクセ ストークンでリソース利用 アクセストークンから利用 者を確認(JWTの場合)
  23. 23. ポイント • スコープの指定とオーナーによる同意 • スコープが変わると再同意とアクセス・トークンの再取得が必要 • 登録されたクライアントだけにトークンを発行 • クライアントIDとクライアントSecretによる認証 • 期限付きのコード・トークンを利用(パスワードの保存なし) • 認可コード • アクセス・トークンとの交換用(ごく短時間有効) • アクセス・トークン • リソースへのアクセスに利用(短時間有効) • リフレッシュ・トークン • アクセス・トークンとの交換用(それなりの期間有効) • アクセス・トークンの期限切れが発生した際に再度オーナーのインタラクションが無しにアク セス・トークンを再取得 • アクセス・トークンの使い方により利用ユーザの特定も可能 • JWT(JSON Web Token)を利用する場合(Azure AD はこれ) © 2016 Naohiro Fujie 23
  24. 24. デモ Azure Active Directory による WebAPI の保護 Active Directory Authentication Library による API クライアントの実装 © 2016 Naohiro Fujie 24
  25. 25. 保護対象リソース (ASP.NET WebAPI) デモ構成 © 2016 Naohiro Fujie 25 クライアント (ASP.NET MVC +ADAL) 認可サーバ (Azure AD) リソース・オーナー (Azure AD 利用者) 所有 登録 認可 利用 登録 保護 利用
  26. 26. Azure AD の OAuth と ADAL • Azure AD(Azure Active Directory)の OAuth • Facebook などコンシューマの OAuth 実装との差は「Azure AD 以 外のリソース」へのアクセスを認可する点 ※Facebook などは自身が OAuth サーバでありリソースサーバ • そのため、Resource パラメータが必須となっている • ADAL(Active Directory Authentication Library) • Azure AD、AD FS 向けの認証ライブラリ • .NET 以外にも Java や JavaScript、Ruby、objective-C などに対応 • OAuth、OpenID Connect、ws-federation への対応 • トークンのキャッシュの自動管理(必要に応じてリフレッシュ・トー クンでアクセス・トークンを再取得)など、超便利 © 2016 Naohiro Fujie 26
  27. 27. WebAPI の作成 © 2016 Naohiro Fujie 27
  28. 28. プロジェクトの作成 © 2016 Naohiro Fujie 28
  29. 29. Web API を選択 © 2016 Naohiro Fujie 29
  30. 30. Azure ADドメインを指定 © 2016 Naohiro Fujie 30
  31. 31. 完成 © 2016 Naohiro Fujie 31
  32. 32. Azure ADに自動で登録される © 2016 Naohiro Fujie 32
  33. 33. ※テスト用)非HTTPS化しておく © 2016 Naohiro Fujie 33
  34. 34. API Client の作成 © 2016 Naohiro Fujie 34
  35. 35. プロジェクトの作成 © 2016 Naohiro Fujie 35
  36. 36. MVC を選択 © 2016 Naohiro Fujie 36
  37. 37. Azure ADドメインを指定 © 2016 Naohiro Fujie 37
  38. 38. 完成 © 2016 Naohiro Fujie 38
  39. 39. Azure ADに自動で登録される © 2016 Naohiro Fujie 39
  40. 40. 取り敢えず実行するとユーザ認証 © 2016 Naohiro Fujie 40
  41. 41. プロファイル取得に関する同意 (Azure AD リソースへのアクセス) © 2016 Naohiro Fujie 41
  42. 42. サインイン完了 © 2016 Naohiro Fujie 42
  43. 43. API アクセス © 2016 Naohiro Fujie 43
  44. 44. API Client ⇒ WebAPI へアクセス許可 © 2016 Naohiro Fujie 44
  45. 45. 登録された WebAPI を選択 © 2016 Naohiro Fujie 45
  46. 46. スコープを選択 © 2016 Naohiro Fujie 46
  47. 47. 許可設定 © 2016 Naohiro Fujie 47
  48. 48. API Client のキーを生成(client_secret) © 2016 Naohiro Fujie 48
  49. 49. 保存するとキーが表示される © 2016 Naohiro Fujie 49
  50. 50. nuget で ADAL をインストール © 2016 Naohiro Fujie 50
  51. 51. Web.config に必要な情報を入れる © 2016 Naohiro Fujie 51
  52. 52. Web.config に設定する情報 • appSetting に以下を追加 • Azure AD ポータルで取得したAPI Client のキー • <add key="ida:ClientSecret" value="WrVNTezVxZBjXPQBEMQ6VhKuJ9Ell1+An1cLCHZGmAo=" /> • アクセス先の API の識別子(リソースID) • <add key="ida:ResourceId" value="https://pharaoh.onmicrosoft.com/testWebAPI" /> © 2016 Naohiro Fujie 52
  53. 53. Startup.Auth へのコード追加 • Using ディレクティブ • using Microsoft.IdentityModel.Clients.ActiveDirectory; • OpenIdConnectAuthenticationOptions // WebAPIリソースへのアクセスを要求 Resource = ConfigurationManager.AppSettings["ida:ResourceId"], Notifications = new OpenIdConnectAuthenticationNotifications { // ADALのトークンキャッシュにアクセストークンを乗せるため、認可コードでアクセストークンを取得 AuthorizationCodeReceived = async (context) => { string code = context.Code; AuthenticationContext authContext = new AuthenticationContext(authority); AuthenticationResult result = await authContext.AcquireTokenByAuthorizationCodeAsync( code, new Uri(postLogoutRedirectUri), new ClientCredential( clientId, ConfigurationManager.AppSettings["ida:ClientSecret"])); } } © 2016 Naohiro Fujie 53
  54. 54. HomeController へのコード追加 • Using ディレクティブ • using System.Configuration; • using Microsoft.IdentityModel.Clients.ActiveDirectory; • using System.Net.Http; • using System.Net.Http.Headers; © 2016 Naohiro Fujie 54
  55. 55. HttpClient httpClient = new HttpClient(); httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", result.AccessToken); HttpResponseMessage response = httpClient.GetAsync("http://localhost:1867/api/values").Result; if (response.IsSuccessStatusCode){ ViewBag.Message = response.Content.ReadAsStringAsync().Result; } } catch (AdalException ex) { ViewBag.Message = ex.Message; } return View(); } public async System.Threading.Tasks.Task<ActionResult> About() { string clientId = ConfigurationManager.AppSettings["ida:ClientId"]; string clientSecret = ConfigurationManager.AppSettings["ida:ClientSecret"]; string aadInstance = ConfigurationManager.AppSettings["ida:AADInstance"]; string tenantId = ConfigurationManager.AppSettings["ida:TenantId"]; string authority = aadInstance + tenantId; var resourceId = ConfigurationManager.AppSettings["ida:ResourceId"]; try { ClientCredential credential = new ClientCredential(clientId, clientSecret); AuthenticationContext authContext = new AuthenticationContext(authority); AuthenticationResult result = await authContext.AcquireTokenSilentAsync( resourceId, credential, UserIdentifier.AnyUser); © 2016 Naohiro Fujie 55
  56. 56. API Client を起動すると WebAPI への アクセスについて同意を求められる © 2016 Naohiro Fujie 56
  57. 57. サインイン完了 © 2016 Naohiro Fujie 57
  58. 58. WebAPI を実行 © 2016 Naohiro Fujie 58
  59. 59. 参考資料 • 脱オンプレミス! クラウド時代の認証基盤 Azure Active Directory 完全解説 • 著 : Vittorio Bertocci • 監訳 : 安納 順一、富士榮 尚寛 • ¥3,996 • Kindle 版もあり〼 • http://amzn.to/2h01o2h © 2016 Naohiro Fujie 59
  60. 60. まとめ • OAuth を使って安全に API を使いましょう • 利用者にとって • パスワードの氾濫を防ぐ • 権限の絞り込みを適切に行う • API 提供者にとって • 適切な API クライアントへ提供する • Azure AD、ADAL を使うと結構簡単に実装できます。 • 本買ってね © 2016 Naohiro Fujie 60

×