Slide 1

Slide 1 text

OAuth + Office 365 API ではじめる アプリ開発 篠原敬志 (@karamem0)

Slide 2

Slide 2 text

自己紹介 • 篠原敬志 (Takashi Shinohara) • Microsoft MVP for Office Development (2018-) • Twitter: @karamem0 • Blog: からめもぶろぐ。(http://blog.karamem0.jp) 2

Slide 3

Slide 3 text

Office 365 API • Office 365 のさまざまなサービスにアクセスするための REST ベースの API プラット フォーム • サービス別 • Office 365 Exchange Online • Office 365 SharePoint Online • Skype for Business Online • Office 365 Yammer • Power BI Service • 他いろいろ • Microsoft Graph 3

Slide 4

Slide 4 text

OAuth • リソースへの認可 (Authorization) を行うためのプロトコル • 本来は認証 (Authentication) のためのプロトコルではないが、認証に使っている Web サービスも存在する • リソースを使用するクライアントに対して認証情報を渡す必要がない • 現時点での最新は OAuth 2.0 (RFC 6749) で、単に OAuth というときは OAuth 2.0 を指すことがほとんど • Twitter はまだ OAuth 1.0 (XAuth) • アプリの種類ごとに使用する認可フローが異なる • Office 365 API にアクセスするためは Azure Active Directory (Azure AD) の OAuth を使用する必要がある 4

Slide 5

Slide 5 text

Azure AD の v1.0 エンドポイント • https://login.microsoftonline.c om/oauth2 • アプリケーションは Azure Portal か ら登録する • 個々のサービスの API を呼び出す 場合はこちらが必要 • サービスごとに異なる Access Token を発行する 5

Slide 6

Slide 6 text

Azure AD の v2.0 エンドポイント • https://login.microsoftonline.c om/oauth2/v2.0 • 組織アカウントとマイクロソフト アカ ウントの両方に対応 • 異なるデバイス アプリケーションで共 通の App ID を使用可能 • アプリケーションは https://apps.d ev.microsoft.com から登録する • 動的に異なるアクセス許可の Acc ess Token を発行できる 6

Slide 7

Slide 7 text

リソース URI サービス名 アプリケーション ID リソース URI Office 365 Exchange Online 00000002-0000-0ff1-ce00-000000000000 https://outlook.office365.com Office 365 SharePoint Online 00000003-0000-0ff1-ce00-000000000000 https://{tenant}.sharepoint.com Skype for Business Online 00000004-0000-0ff1-ce00-000000000000 https://webdir.online.lync.com Office 365 Yammer 00000005-0000-0ff1-ce00-000000000000 https://{tenant}.yammer.com Power BI Service 00000009-0000-0000-c000-000000000000 https://analysis.windows.net Windows Azure Active Directory 00000002-0000-0000-c000-000000000000 https://graph.windows.net Microsoft Graph 00000003-0000-0000-c000-000000000000 https://graph.microsoft.com 7 • リソースの一覧は Get-AzureRmADServicePrincipal で確認できる

Slide 8

Slide 8 text

認可フローの種類 種類 説明 Authorization Code Grant 認証後に認可サーバーに Authorization Code を発行してもらう認可フロー。(RFC 6749) Implicit Grant 暗黙的に Access Token を取得する認可フロー。(RFC 6749) Password Credentials Grant 認証情報としてユーザー名とパスワードを使用する認可フロー。(RFC 6749) Client Credentials Grant バックグラウンドで動作するアプリケーション向けの認可フロー。(RFC 6749) OpenID Connect OpenID Connect による認可フロー。 Device Flow ログオン UI を出せないアプリケーション向けの認可フロー。(draft-ietf-oauth-device-flow) On-Behalf-Of Flow 認可されたサービスがさらに別のサービスを呼び出す場合の認可フロー。(draft-ietf-oauth-jwt-bearer-12) 8

Slide 9

Slide 9 text

認可フローの選択 アプリの種類 認可フロー ASP.NET アプリケーション Windows Forms アプリケーション WPF アプリケーション モバイル アプリケーション Authorization Code Grant Office アドイン SharePoint アドイン JavaScript アプリケーション Implicit Grant コンソール アプリケーション PowerShell Password Credentials Grant Client Credentials Grant Device Flow 9

Slide 10

Slide 10 text

Access Token • 認可が正常に行われると Access Token が返される • Access Token は JSON Web Token (JWT) 形式の文字列 • 認証/認可に関するさまざまなデータが含まれる • アプリケーション ID / アプリケーション名 • ユーザー プリンシパル名 / 表示名 • アクセス許可 • トークンの有効期間 • .NET の場合は System.IdentityModel.Tokens.Jwt を使って解析できる 10

Slide 11

Slide 11 text

Access Token の有効期間 • Access Token の有効期間は既定で 1 時間 • マニフェストを編集することで 10 分 から 24 時間まで変更可能 • Access Token の有効期間が切れた場合は Refresh Token を使って新たな Access Token を取得する • Refresh Token を取得できないフローもある • Refresh Token の有効期間も最大 90 日なので、Refresh Token の有効 期間が切れた場合は認証をやり直す必要がある 11

Slide 12

Slide 12 text

Access Token を使ったリクエスト • API を実行するときは HTTP リクエストに Authorization ヘッダーを付与する • Authorization: Bearer • Bearer = 持参人 • トークンを所有することを利用の証明とする 12

Slide 13

Slide 13 text

Azure AD 認証ライブラリ • v1.0 • ADAL (Azure Active Directory Authentication Library) • NuGet: Microsoft.IdentityModel.Clients.ActiveDirectory • v2.0 • MSAL (Microsoft Authentication Library) • NuGet: Microsoft.Identity.Client • .NET, JavaScript, iOS (macOS), Android などをサポート 13

Slide 14

Slide 14 text

Authorization Code Grant 14

Slide 15

Slide 15 text

Authorization Code Grant 15 User-Agent Client Authorization Server Web ブラウザーで https://login.microsoftonline.com/{t enant}/oauth2/v2.0/authorize にアクセスする ネイティブ アプリの場合は Web ブラウザー コントロールを使 用する ユーザーによる認証後、redirect_uri にリダイレクトするので、 クエリ文字列の code を取得する https://login.microsoftonline.com/{tenant}/oauth2/v 2.0/token に POST リクエストを発行する レスポンス本文 (JSON) の access_token, refresh_token, expires_in を取得する

Slide 16

Slide 16 text

Authorization Code Grant • ユーザーによるサインインが発生するため Web ブラウザーを経由する必要がある • サインイン後は redirect_uri で指定した URL にリダイレクトする 16 • ネイティブ アプリの場合は redirect_uri に https://login.microsoftonline.com /common/oauth2/nativeclient を 指定し、Web ブラウザーコントロールの Navigation イベントでリダイレクトを検 知する

Slide 17

Slide 17 text

Authorization Request (v1.0) GET https://login.microsoftonline.com/{tenant}/oauth2/authorize? client_id=c7727a05-6428-45ff-b572-affc4fca64b7& response_type=code& redirect_uri=http%3A%2F%2Flocalhost%2FAuth%2FGetToken& resource=https%3A%2F%2Fgraph.microsoft.com 17 • resource は複数指定できない

Slide 18

Slide 18 text

Authorization Response (v1.0) HTTP/1.1 302 Found Location: http://localhost/Auth/GetToken? code=OAQABAAI...& session_state=96be781a-eaaa-4845-9d2a-b3da4b248d32 18

Slide 19

Slide 19 text

Access Token Request (v1.0) POST {tenant}/oauth2/token HTTP/1.1 Host: https://login.microsoftonline.com Content-Type: application/x-www-form-urlencoded client_id=c7727a05-6428-45ff-b572-affc4fca64b7& grant_type=authorization_code& resource=https%3A%2F%2Fgraph.microsoft.com& code=OAQABAAI...& redirect_uri=http%3A%2F%2Flocalhost%2FAuth%2FGetToken& client_secret=NZ8gkb7Q... 19

Slide 20

Slide 20 text

Access Token Response (v1.0) HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 { "token_type":"Bearer", "scope":"Files.Read Files.Read.All User.Read", "expires_in":"3599", "ext_expires_in":"0", "expires_on":"1503394903", "not_before":"1503391003", "resource":"https://graph.microsoft.com", "access_token":"eyJ0eXAi...", "refresh_token":"AQABAAAA...", "id_token":"eyJ0eXAi..." } 20

Slide 21

Slide 21 text

Authorization Request (v2.0) GET https://login.microsoftonline.com/{tenant}/oauth2/v2.0/authorize? client_id=c7727a05-6428-45ff-b572-affc4fca64b7& response_type=code& redirect_uri=http%3A%2F%2Flocalhost%2FAuth%2FGetToken& scope=offline_access%20https%3A%2F%2Fgraph.microsoft.com%2Fuser.read 21 • scope は {リソース URI}/{アクセス許可} の形式 • scope を複数指定する場合はスペース区切り • refresh_token を受け取りたい場合は offline_access を指定する

Slide 22

Slide 22 text

Authorization Response (v2.0) HTTP/1.1 302 Found Location: http://localhost/Auth/GetToken? code=OAQABAAI...& session_state=96be781a-eaaa-4845-9d2a-b3da4b248d32 22

Slide 23

Slide 23 text

Access Token Request (v2.0) POST {tenant}/oauth2/v2.0/token HTTP/1.1 Host: https://login.microsoftonline.com Content-Type: application/x-www-form-urlencoded client_id=c7727a05-6428-45ff-b572-affc4fca64b7& grant_type=authorization_code& scope=offline_access%20https%3A%2F%2Fgraph.microsoft.com%2Fuser.read& code=OAQABAAI...& redirect_uri=http%3A%2F%2Flocalhost%2FAuth%2FGetToken& client_secret=NZ8gkb7Q... 23

Slide 24

Slide 24 text

Access Token Response (v2.0) HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 { "token_type":"Bearer", "scope":"https://graph.microsoft.com/Files.Read https://...", "expires_in":3600, "ext_expires_in":0, "access_token":"eyJ0eXAi...", "refresh_token":"AQABAAAA..." } 24

Slide 25

Slide 25 text

Implicit Grant 25

Slide 26

Slide 26 text

Implicit Grant 26 User-Agent Client Authorization Server Web ブラウザーで https://login.microsoftonline.com/{t enant}/oauth2/v2.0/authorize にアクセスする ユーザーによる認証後、redirect_uri にリダイレクトするので、 クエリ文字列の access_token, expires_in を取得する

Slide 27

Slide 27 text

Implicit Grant • 特定の URI からリダイレクトされることを前提にフローを簡略化する • JavaScript アプリケーション向け 27 • v1.0 の既定では無効化されているので、 マニフェストを編集する必要がある • フローが簡略化される反面セキュリティ を考慮する必要がある

Slide 28

Slide 28 text

Authorization Request (v1.0) GET https://login.microsoftonline.com/{tenant}/oauth2/v2.0/authorize? client_id=c7727a05-6428-45ff-b572-affc4fca64b7& response_type=token& redirect_uri=http%3A%2F%2Flocalhost%2FAuth%2FCallback& resource=https%3A%2F%2Fgraph.microsoft.com 28

Slide 29

Slide 29 text

Authorization Response (v1.0) HTTP/1.1 302 Found Location: http://localhost/Auth/Callback# access_token=eyJ0eXAi...& token_type=Bearer& expires_in=3599& session_state=d4992ff3-9979-4fbe-a278-a3bb3bcd822b 29

Slide 30

Slide 30 text

Authorization Request (v2.0) GET https://login.microsoftonline.com/{tenant}/oauth2/v2.0/authorize? client_id=c7727a05-6428-45ff-b572-affc4fca64b7& response_type=token& redirect_uri=http%3A%2F%2Flocalhost%2FAuth%2FCallback& scope=https%3A%2F%2Fgraph.microsoft.com%2Fuser.read%20https%3A%2F%2F... 30

Slide 31

Slide 31 text

Authorization Response (v2.0) HTTP/1.1 302 Found Location: http://localhost/Auth/Callback# access_token=eyJ0eXAi...& token_type=Bearer& expires_in=3599& scope=https%3a%2f%2fgraph.microsoft.com%2fFiles.Read+https%3a%2f%2f... session_state=d4992ff3-9979-4fbe-a278-a3bb3bcd822b 31

Slide 32

Slide 32 text

Client Credentials Grant 32

Slide 33

Slide 33 text

Client Credentials Grant 33 User-Agent Client Authorization Server https://login.microsoftonline.com/{tenant}/oauth2/v 2.0/token にアクセスする 共有シークレットまたは証明書による認証後、レスポンス本 文 (JSON) の access_token, expires_in を取得する Web ブラウザーで https://login.microsoftonline.com/co mmon/adminconsent にアクセスし、アプリケーションを承 認する

Slide 34

Slide 34 text

Client Credentials Grant • ユーザーではなくアプリケーションを認証する • 資格情報として共有シークレットまたは証明書を使用する 34 • 管理操作を必要とするアプリケーション 向け • https://login.microsoftonline.com /common/adminconsent に接続し て管理者が承認する必要がある • アクセス許可はアプリケーションのアクセ ス許可で指定する

Slide 35

Slide 35 text

Access Token Request (v1.0) POST {tenant}/oauth2/token HTTP/1.1 Host: https://login.microsoftonline.com Content-Type: application/x-www-form-urlencoded client_id=c7727a05-6428-45ff-b572-affc4fca64b7& resource=https%3A%2F%2Fgraph.microsoft.com& client_secret=NZ8gkb7Q...& grant_type=client_credentials 35

Slide 36

Slide 36 text

Access Token Response (v1.0) HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 { "token_type":"Bearer", "expires_in":3599, "ext_expires_in":0, "access_token":"eyJ0eXAi..."} 36

Slide 37

Slide 37 text

Access Token Request (v2.0) POST {tenant}/oauth2/v2.0/token HTTP/1.1 Host: https://login.microsoftonline.com Content-Type: application/x-www-form-urlencoded client_id=c7727a05-6428-45ff-b572-affc4fca64b7& scope=https%3A%2F%2Fgraph.microsoft.com%2F.default& client_secret=NZ8gkb7Q...& grant_type=client_credentials 37 • scope は .default 固定

Slide 38

Slide 38 text

Access Token Response (v2.0) HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 { "token_type":"Bearer", "expires_in":3599, "ext_expires_in":0, "access_token":"eyJ0eXAi..."} 38

Slide 39

Slide 39 text

Device Flow 39

Slide 40

Slide 40 text

Device Flow 40 End-user at Browser Device Client Authorization Server https://login.microsoftonline.com/{tenant}/oauth2/d evicecode に GET リクエストを発行する device_code を表示する Web ブラウザーで https://login.microsoftonline.com/{t enant}/oauth2/deviceauth にアクセスする レスポンス本文 (JSON) の device_code を取得する ユーザーによる認証後、 https://login.microsoftonline.co m/{tenant}/oauth2/token に POST リクエストを発行する レスポンス本文 (JSON) の access_token, refresh_token, expires_in を取得する

Slide 41

Slide 41 text

Device Flow • 任意のデバイスからの認証が可能になる • redirect_uri は存在しない 41 • Server Core や Linux 上の アプリケー ションのような GUI が出せないアプリ ケーション向け • v2.0 では未サポート

Slide 42

Slide 42 text

Device Authorization Request (v1.0) GET https://login.microsoftonline.com/{tenant}/oauth2/devicecode? client_id=c7727a05-6428-45ff-b572-affc4fca64b7& resource=https%3A%2F%2Fgraph.microsoft.com 42

Slide 43

Slide 43 text

Device Authorization Response (v1.0) HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 { "user_code":"GYNMJH2SR", "device_code":"GAQABAAE...", "verification_url":"https://aka.ms/devicelogin", "expires_in":"900", "interval":"5", "message":"To sign in, use a web browser to open the page..." } 43

Slide 44

Slide 44 text

Device Access Token Request (v1.0) POST {tenant}/oauth2/token HTTP/1.1 Host: https://login.microsoftonline.com Content-Type: application/x-www-form-urlencoded client_id=c7727a05-6428-45ff-b572-affc4fca64b7& grant_type=device_code& resource=https%3A%2F%2Fgraph.microsoft.com& code=GAQABAAE... 44

Slide 45

Slide 45 text

Device Access Token Response (v1.0) HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 { "token_type":"Bearer", "scope":"Files.Read Files.Read.All User.Read", "expires_in":"3599", "ext_expires_in":"0", "expires_on":"1503482394", "not_before":"1503478494", "resource":"https://graph.microsoft.com", "access_token":"eyJ0eXAi...", "refresh_token":"AQABAAAA...", "id_token":"eyJ0eXAi..." } 45

Slide 46

Slide 46 text

Appendix 46

Slide 47

Slide 47 text

Error Code Analyzer • https://apps.dev.microsoft.com/portal/tools/errors • 認可フローのエラー コードから原因を追跡できる 47

Slide 48

Slide 48 text

Graph Explorer • https://developer.microsoft.com/ja-jp/graph/graph-explorer • Microsoft Graph を Web から実行できる 48

Slide 49

Slide 49 text

参考リンク • The OAuth 2.0 Authorization Framework https://datatracker.ietf.org/doc/rfc6749 • OAuth 2.0 Device Flow for Browserless and Input Constrained Devices https://datatracker.ietf.org/doc/draft-ietf-oauth-device-flow 49

Slide 50

Slide 50 text

参考リンク • v2.0 エンドポイントの変更点 https://docs.microsoft.com/ja-jp/azure/active-directory/develop/activ e-directory-v2-compare • v2.0 エンドポイントの使用が適しているかどうかを判断するには https://docs.microsoft.com/ja-jp/azure/active-directory/develop/activ e-directory-v2-limitations 50

Slide 51

Slide 51 text

参考リンク • Azure AD のトークン リファレンス https://docs.microsoft.com/ja-jp/azure/active-directory/develop/activ e-directory-token-and-claims • Azure Active Directory 認証ライブラリ https://docs.microsoft.com/ja-jp/azure/active-directory/develop/activ e-directory-authentication-libraries 51