oauth2.0によるweb apiの保護

60
OAuth 2.0 による Web API の保護 2016.12.21 Japan Web API Community #1 Naohiro Fujie @phr_eidentity

Upload: naohiro-fujie

Post on 07-Jan-2017

1.136 views

Category:

Technology


1 download

TRANSCRIPT

Page 1: OAuth2.0によるWeb APIの保護

OAuth 2.0 によるWeb API の保護

2016.12.21

Japan Web API Community #1

Naohiro Fujie

@phr_eidentity

Page 2: OAuth2.0によるWeb APIの保護

自己紹介

• 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

Page 3: OAuth2.0によるWeb APIの保護

Agenda

1. WebAPI に求められるセキュリティ• 利用者から見た課題

• API 提供者から見た課題

2. OAuth 2.0 の概要と課題への対応

3. デモ• Azure AD による WebAPI の保護

• ADAL による API クライアントの実装

© 2016 Naohiro Fujie 3

Page 4: OAuth2.0によるWeb APIの保護

WebAPI に求められるセキュリティ

© 2016 Naohiro Fujie 4

Page 5: OAuth2.0によるWeb APIの保護

WebAPI 利用・提供時の課題

• いかにして API クライアントを信頼するか?• 利用者の視点

• API を通して提供される自身のデータを悪用されたくない

• API 提供者の視点• 誰が利用しているのかを明確にしたい(例:課金)

• 人の識別

• API クライアントの識別

• 提供するデータを悪用されたくない

© 2016 Naohiro Fujie 5

http(s)でインターネット上に公開しているので、Firewall 等による分離は難しい

API クライアントは便利だけど、間接的に自身のデータへアクセスされるのは怖い

API の基本は単機能。ユーザ認証・認可機能を API 毎に開

発したくない

適切な API クライアントからだけアクセスさせたい

Page 6: OAuth2.0によるWeb APIの保護

利用者から見た課題

© 2016 Naohiro Fujie 6

Page 7: OAuth2.0によるWeb APIの保護

従来の Web アプリケーションの利用

• ユーザ自身によりコンテキストの使い分けが可能• Facebookの友達からはアプリA、Twitter上のアイデンティティとの紐

づけをされても良いが、反対は嫌

• 情報は二重管理

© 2016 Naohiro Fujie 7

実名、電話番号を登録

ニックネームを登録

Twitterには同僚に知られたくない性癖を投稿しているので、

実名は登録したくない

Facebookの友達は近しい人ばかりなので、実名や電話番

号を登録しておきたい

アプリAニックネームと電話番号を登録

アプリAにはニックネームと電話番号を登録したい・・・

二重管理は面倒

Page 8: OAuth2.0によるWeb APIの保護

上手く API を使って二重管理をやめたい

• アプリにFacebookとTwitterのIDとパスワードを登録する?

© 2016 Naohiro Fujie 8

実名、電話番号を登録

ニックネームを登録

アプリA(APIクライアント)

ニックネームと電話番号を使わせたい

ユーザのID/PWDを使ってFacebookへアクセス

複数のサービスに同じ情報を登録するのは面倒なので便利なマッシュアップ・アプリを

使いたい

ユーザのID/PWDを使ってTwitterへアクセス

Page 9: OAuth2.0によるWeb APIの保護

パスワード?

• アプリ上に個人のパスワードを登録するのは・・・

© 2016 Naohiro Fujie 9

実名、電話番号を登録

ニックネームを登録

アプリA(APIクライアント)

ニックネームと電話番号を使わせたい

ユーザのID/PWDを使ってFacebookへアクセス

ユーザのID/PWDを使ってTwitterへアクセス

パスワードを登録しておくのはかなり嫌・・・

漏えい?変更時の運用?

Page 10: OAuth2.0によるWeb APIの保護

コンテキストが混ざる

• せっかく分けていたコンテキストがアプリで混ざる

© 2016 Naohiro Fujie 10

実名、電話番号を登録

ニックネームを登録

アプリA(APIクライアント)

ニックネームと電話番号を使わせたい

電話番号だけが欲しいのに、実名もとれてしまう?

このアプリ上でコンテキストが混ざってしまう

Page 11: OAuth2.0によるWeb APIの保護

課題:パスワード、コンテキスト

パスワードを使わずに

どうやってユーザの代わりに「望んだ範囲に限定して」アクセスさせるか?

© 2016 Naohiro Fujie 11

実名、電話番号を登録

ニックネームを登録

アプリA(APIクライアント)

ニックネームと電話番号を使わせたい

パスワードを登録しておくのはかなり嫌・・・

漏えい?変更時の運用?

このアプリ上でコンテキストが混ざってしまう

Page 12: OAuth2.0によるWeb APIの保護

API 提供者から見た課題

© 2016 Naohiro Fujie 12

Page 13: OAuth2.0によるWeb APIの保護

従来の Web アプリケーションの利用

• ユーザが直接アプリを利用していたので識別は簡単

• 個々に認証機能や UI 開発が必要

© 2016 Naohiro Fujie 13

直接ログイン

直接ログイン

アプリA直接ログイン

個々に運用・管理。識別は簡単だが、個々に機能

開発が必要

Page 14: OAuth2.0によるWeb APIの保護

API を公開してシンプルにしたい

• ユーザが直接アプリを利用していたので識別は簡単

• 個々に認証機能や UI 開発が必要

© 2016 Naohiro Fujie 14

アプリA(APIクライアント) シンプルな機能・データ提供

だけを API で行いたい

利用

アプリ経由で利用

アプリ経由で利用

Page 15: OAuth2.0によるWeb APIの保護

アクセス元の特定・真贋が難しい

• アクセス元アプリの信頼性の担保が難しい

© 2016 Naohiro Fujie 15

アプリA(APIクライアント) 誰がどのアプリ経由が使って

いるのかわからない?

利用

アプリ経由で利用

アプリ経由で利用このアプリは信頼できるのか?

特定アプリ以外からのアクセスを防げない?

Page 16: OAuth2.0によるWeb APIの保護

課題:利用元の特定と管理

• どうやって「許可された」アプリからのみアクセスを許可するか?

© 2016 Naohiro Fujie 16

アプリA(APIクライアント)

利用

アプリ経由で利用

アプリ経由で利用このアプリは信頼できるのか?

特定アプリ以外からのアクセスを防げない?

誰がどのアプリ経由が使っているのかわからない?

Page 17: OAuth2.0によるWeb APIの保護

OAuth 2.0 の概要と課題への対応

© 2016 Naohiro Fujie 17

Page 18: OAuth2.0によるWeb APIの保護

OAuth の概要と基本的な考え方

• 目的• リソースへのアクセスを安全に認可(委譲)すること

• 基本的な考え方• リソース(API を通して提供される機能やデータ)の持ち主はユーザ

である

• ユーザの同意に基づき API クライアントに対してリソースへのアクセス権限を認可(委譲)する

• 認証(検証)された API クライアントに対してのみリソースを提供する

© 2016 Naohiro Fujie 18

Page 19: OAuth2.0によるWeb APIの保護

構成要素

• 保護対象リソース• API を経由して提供される機能やデータなどのリソース

• リソース・オーナー• 保護対象となるリソースの持ち主(ユーザ)

• クライアント• 保護対象リソースへアクセスする主体(API クライアント)

• 認可サーバ• 保護対象リソースへのアクセスを認可するためのサーバ

© 2016 Naohiro Fujie 19

Page 20: OAuth2.0によるWeb APIの保護

保護対象リソース(API 、データ)

各構成要素の関係性

© 2016 Naohiro Fujie 20

クライアント

認可サーバ

リソース・オーナー

所有

登録

認可 利用

登録

保護利用

Page 21: OAuth2.0によるWeb APIの保護

保護対象リソース(API 、データ)

実際の動き(認可コードグラント)

© 2016 Naohiro Fujie 21

クライアント

認可サーバ

リソース・オーナー

所有

登録

認可 利用

登録

保護利用

1.利用したい

2.認可要求

3.認可要求(同意)

4.認可コードの発行

5.認可コードの提供

6.認可コードとアクセストークン

の交換

8.アクセストークンの検証

7.アクセストークンの提示

9.リソースの提供

Page 22: OAuth2.0によるWeb APIの保護

シーケンス(認可コードグラント)

© 2016 Naohiro Fujie 22

リソース・オーナー(利用者/UserAgent)

クライアント(アプリケーション)

認可サーバ(OAuthサーバ)

保護対象リソース(API・データ)

フロー開始

ユーザ認証・同意

認可エンドポイントへリダイレクト

(クライアントID、スコープを含む)

クライアントへリダイレクト

(認可コードを含む)アクセストークンを要求(認可コード、クライアントID、Secretを含む)

アクセストークンを発行

リソース要求(アクセストークンを含む)

アクセストークンの検証

リソースの提供

クライアントに許可する範囲(スコープ)指定が可能

オーナー(ユーザ)の同意に基づくアクセスが可能

許可されたクライアントのみからアクセスする為の認証

パスワードではなく、アクセストークンでリソース利用

アクセストークンから利用者を確認(JWTの場合)

Page 23: OAuth2.0によるWeb APIの保護

ポイント

• スコープの指定とオーナーによる同意• スコープが変わると再同意とアクセス・トークンの再取得が必要

• 登録されたクライアントだけにトークンを発行• クライアントIDとクライアントSecretによる認証

• 期限付きのコード・トークンを利用(パスワードの保存なし)• 認可コード

• アクセス・トークンとの交換用(ごく短時間有効)• アクセス・トークン

• リソースへのアクセスに利用(短時間有効)• リフレッシュ・トークン

• アクセス・トークンとの交換用(それなりの期間有効)• アクセス・トークンの期限切れが発生した際に再度オーナーのインタラクションが無しにアク

セス・トークンを再取得

• アクセス・トークンの使い方により利用ユーザの特定も可能• JWT(JSON Web Token)を利用する場合(Azure AD はこれ)

© 2016 Naohiro Fujie 23

Page 24: OAuth2.0によるWeb APIの保護

デモAzure Active Directory による WebAPI の保護

Active Directory Authentication Library による API クライアントの実装

© 2016 Naohiro Fujie 24

Page 25: OAuth2.0によるWeb APIの保護

保護対象リソース(ASP.NET WebAPI)

デモ構成

© 2016 Naohiro Fujie 25

クライアント(ASP.NET MVC

+ADAL)

認可サーバ(Azure AD)

リソース・オーナー(Azure AD 利用者)

所有

登録

認可 利用

登録

保護利用

Page 26: OAuth2.0によるWeb APIの保護

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

Page 27: OAuth2.0によるWeb APIの保護

WebAPI の作成

© 2016 Naohiro Fujie 27

Page 28: OAuth2.0によるWeb APIの保護

プロジェクトの作成

© 2016 Naohiro Fujie 28

Page 29: OAuth2.0によるWeb APIの保護

Web API を選択

© 2016 Naohiro Fujie 29

Page 30: OAuth2.0によるWeb APIの保護

Azure ADドメインを指定

© 2016 Naohiro Fujie 30

Page 31: OAuth2.0によるWeb APIの保護

完成

© 2016 Naohiro Fujie 31

Page 32: OAuth2.0によるWeb APIの保護

Azure ADに自動で登録される

© 2016 Naohiro Fujie 32

Page 33: OAuth2.0によるWeb APIの保護

※テスト用)非HTTPS化しておく

© 2016 Naohiro Fujie 33

Page 34: OAuth2.0によるWeb APIの保護

API Client の作成

© 2016 Naohiro Fujie 34

Page 35: OAuth2.0によるWeb APIの保護

プロジェクトの作成

© 2016 Naohiro Fujie 35

Page 36: OAuth2.0によるWeb APIの保護

MVC を選択

© 2016 Naohiro Fujie 36

Page 37: OAuth2.0によるWeb APIの保護

Azure ADドメインを指定

© 2016 Naohiro Fujie 37

Page 38: OAuth2.0によるWeb APIの保護

完成

© 2016 Naohiro Fujie 38

Page 39: OAuth2.0によるWeb APIの保護

Azure ADに自動で登録される

© 2016 Naohiro Fujie 39

Page 40: OAuth2.0によるWeb APIの保護

取り敢えず実行するとユーザ認証

© 2016 Naohiro Fujie 40

Page 41: OAuth2.0によるWeb APIの保護

プロファイル取得に関する同意(Azure AD リソースへのアクセス)

© 2016 Naohiro Fujie 41

Page 42: OAuth2.0によるWeb APIの保護

サインイン完了

© 2016 Naohiro Fujie 42

Page 43: OAuth2.0によるWeb APIの保護

API アクセス

© 2016 Naohiro Fujie 43

Page 44: OAuth2.0によるWeb APIの保護

API Client ⇒ WebAPI へアクセス許可

© 2016 Naohiro Fujie 44

Page 45: OAuth2.0によるWeb APIの保護

登録された WebAPI を選択

© 2016 Naohiro Fujie 45

Page 46: OAuth2.0によるWeb APIの保護

スコープを選択

© 2016 Naohiro Fujie 46

Page 47: OAuth2.0によるWeb APIの保護

許可設定

© 2016 Naohiro Fujie 47

Page 48: OAuth2.0によるWeb APIの保護

API Client のキーを生成(client_secret)

© 2016 Naohiro Fujie 48

Page 49: OAuth2.0によるWeb APIの保護

保存するとキーが表示される

© 2016 Naohiro Fujie 49

Page 50: OAuth2.0によるWeb APIの保護

nuget で ADAL をインストール

© 2016 Naohiro Fujie 50

Page 51: OAuth2.0によるWeb APIの保護

Web.config に必要な情報を入れる

© 2016 Naohiro Fujie 51

Page 52: OAuth2.0によるWeb APIの保護

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

Page 53: OAuth2.0によるWeb APIの保護

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

Page 54: OAuth2.0によるWeb APIの保護

HomeController へのコード追加

• Using ディレクティブ• using System.Configuration;

• using Microsoft.IdentityModel.Clients.ActiveDirectory;

• using System.Net.Http;

• using System.Net.Http.Headers;

© 2016 Naohiro Fujie 54

Page 55: OAuth2.0によるWeb APIの保護

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

Page 56: OAuth2.0によるWeb APIの保護

API Client を起動すると WebAPI へのアクセスについて同意を求められる

© 2016 Naohiro Fujie 56

Page 57: OAuth2.0によるWeb APIの保護

サインイン完了

© 2016 Naohiro Fujie 57

Page 58: OAuth2.0によるWeb APIの保護

WebAPI を実行

© 2016 Naohiro Fujie 58

Page 59: OAuth2.0によるWeb APIの保護

参考資料

• 脱オンプレミス! クラウド時代の認証基盤 Azure Active Directory 完全解説• 著 : Vittorio Bertocci

• 監訳 : 安納 順一、富士榮 尚寛

• ¥3,996

• Kindle 版もあり〼

• http://amzn.to/2h01o2h

© 2016 Naohiro Fujie 59

Page 60: OAuth2.0によるWeb APIの保護

まとめ

• OAuth を使って安全に API を使いましょう• 利用者にとって

• パスワードの氾濫を防ぐ

• 権限の絞り込みを適切に行う

• API 提供者にとって• 適切な API クライアントへ提供する

• Azure AD、ADAL を使うと結構簡単に実装できます。• 本買ってね

© 2016 Naohiro Fujie 60