Skip to content

MS_OAuthForNativeApps

nishi_74322014 edited this page Aug 12, 2026 · 1 revision

OAuth 2.0 for Native Apps

  • 戻る(UserAgentでOAuth2のTokenを取得するベスト・プラクティス(MS_UserAgentOAuthBestPractice.md))
    • OAuth 2.0 for Native Apps
    • OAuth PKCE
    • AppAuth(MS_AppAuth.md

概要

Native アプリ(スマホ)からの OAuth 2.0 は、

  • 認可リクエストを、外部 Web ブラウザを経由してのみ行う。
  • 外部 Web ブラウザとの連携には基本的に
    Private-Use URI Scheme Redirection」を使用する。
  • 外部 Web ブラウザ以外は、諸事情により使用しない。
  • 外部 Web ブラウザ以外には、以下のようなモノが存在しうる。
    • 埋め込まれた UserAgent(WebView / InAppBrowser)
    • ブラウザ以外の外部 UserAgent

※ なお、Hybrid アプリは、この仕様の目的では Native アプリ(スマホ)と同等に扱う。

移行メモ(RFC 番号): RFC 8252(2017年)。
BCP 212 としても採番されており、
「Best Current Practice(現時点の最良慣行)」に位置づけられている。

詳細

外部Webブラウザを使用した方が良い理由

外部 Web ブラウザを使用すると、

  • ブラウザに備わっている通常のアドレスバーや証明書の検証機能を利用できる。
  • 他のアプリケーションやブラウザと認証状態を共有するため優れた UX を提供できる。
  • パスワード・マネージャーの機能を使用できるため、UX が向上する。

外部Webブラウザ以外を使用してはいけない理由

偽造 Client の可能性があり、偽造 Client によって、

IdPのアカウントを盗むことができる。

IdP のアカウントを Client が盗む事ができる。

IdPのSessionを盗むことができる。

IdP の Session cookie を Client が盗む事ができ、
Session が有効な間、SSO 可能な状態が持続する。

偽造Clientは拒否されることがある。

Google などが提供する OAuth2 / OIDC の Authorization Server (IdP & STS) には、
コレらの偽造 Client からの認可リクエストを拒否する実装が加えられている。

補足(核心はこの一点): 「WebView を使うな」という主張の根拠は、
WebView はアプリが完全に制御できてしまうという一点に尽きる。

攻撃 WebView で可能か 外部ブラウザで可能か
入力内容の盗聴(JS 注入) 可能 不可
Cookie の窃取 可能 不可
アドレスバーの偽装 可能(そもそも無い) 不可
証明書警告の隠蔽 可能 不可

つまり ユーザーは「本物の IdP に入力している」ことを確認できない
これはフィッシングと構造的に同じである。

Google は 2021年にWebView からの OAuth 認証をブロックしており、
「推奨」ではなく実質的な必須要件になっている。

Nativeアプリ(スマホ)と外部Webブラウザの連携方法

Private-Use URI Scheme Redirection

  • アプリケーションが受け取る独自の URL Scheme を事前にシステムに登録する方式。
  • 複数のアプリが通常同じ URL Scheme を登録できるため、
    Private-Use URI Scheme 上書き攻撃が可能。

Claimed Https Scheme URI Redirection

  • 上記を改良した方式。
    • ドメイン名などから、アプリを特定可能
    • 事前登録されていない場合は、自サイトに HTTPS で飛ぶため安全。
  • URI 権限の存在により URI 傍受の影響を受けにくいが、
    • アプリはまだ Public クライアントであり、
    • 仕様が不明瞭な OS の URI ディスパッチハンドラを使用し
      URI が送信される可能性がある。

Loopback Interface Redirection

  • http://localhost:{port}/{path} などと、
    ローカル・ループバックで HTTP リクエストを受け取る方式。
  • デスクトップ OS などでの利用を想定している。
  • 一部の OS で同じローカル・ループバックにアクセスする、
    他のアプリの傍受の影響を受ける可能性がある。
  • 例えば Windows では hosts ファイルを編集される可能性があるので、
    localhost より、127.0.0.1 を使用することが推奨される。

補足(3 方式の選び分け): 実務では次のように選ぶ。

方式 対象 安全性
Claimed Https Scheme(Universal Links / App Links) スマホ 最も安全(OS がドメイン所有を検証)
Private-Use URI Scheme(myapp:// スマホ 中(上書き攻撃あり。PKCE 必須
Loopback Interface デスクトップ / CLI 可(ポートは動的に確保

Azure CLIgh などの CLI ツールが
ブラウザを開いて localhost に戻ってくるのは、3 番目の方式である。

結論

使用するフロー

Implicitは使用できない。

Private-Use URI Scheme 上書き攻撃などの傍受攻撃から token を保護できないため NG。

Authorization Codeは、より実用的。

Native に token を渡せないが、Implicit より実用的なオプション。

サポートがあれば、OAuth PKCEを使う。

  • Private-Use URI Scheme 上書き攻撃からの保護が可能。
  • Native に token を渡す場合は、OAuth PKCEを使う。

補足(現在は PKCE が必須): 本ページ執筆時は
「サポートがあれば PKCE」だったが、
OAuth 2.1では PKCE が全クライアントで必須になった。

RFC 8252 当時 現在(OAuth 2.1 / RFC 9700)
Implicit 非推奨 廃止
PKCE Public クライアントに推奨 全クライアントで必須
Password Grant 非推奨 廃止

つまり Native アプリの正解は
「外部ブラウザ + Authorization Code + PKCE(S256)」の一択である。

Client認証について。

  • Public クライアントに client_idclient_secret を持たせてはダメ。

Client認証できない。

client_idclient_secret を持たないため。

自動再認証は抑止する。

Client 認証できないので、Resource Owner の自動再認証は抑止する。

偽造Clientの可能性を考慮する。

  • Client 認証できないので、偽造 Client の可能性を考慮する必要がある。
  • ここでの偽造 Client とは、外部 Web ブラウザ以外を指す。

補足(client_secret を埋め込んではならない理由): アプリのバイナリは
逆コンパイルできる(逆コンパイル・難読化(MS_DecompileAndObfuscation.md)を参照)。
難読化しても、実行時にメモリ上には平文で存在するため、
秘密を保持できない。これが「Public クライアント」の定義そのものである。

代わりに、PKCE が「そのリクエストを出したのと同じアプリか」を
動的に検証する
ことで、client_secret の役割を部分的に代替している。

動的RP登録(RFC 7591)について。

Native アプリ(スマホ)は Public クライアントであるため、
Dynamic Client Registration を行う場合は、

  • Client Type を登録させ、
  • 合わせて、URI をチェックする
    (OAuth 2.0 で推奨される URI の完全一致 + 連携方式に合わせた +α のチェック)。

プラットフォーム独自の有用な機能

OS 認可リクエスト送信 認可レスポンス受信
iOS SFSafariViewController / ASWebAuthenticationSession Custom URL Scheme / Universal Links
Android Chrome Custom TabsCustomTabsService Implicit Intents / Android App Links
Windows (UWP) URI Activation / WebAuthenticationBroker / Loopback
macOS platform API CFBundleURLSchemes / Loopback
Linux xdg-open など Loopback(SO_REUSEPORT / SO_REUSEADDR を設定してはならない)

移行メモ(最新化): iOS の SFAuthenticationSession(iOS 11)は
iOS 12 で ASWebAuthenticationSession に置き換えられ、非推奨である。
現在の iOS 実装は ASWebAuthenticationSessionAuthenticationServices)を使う。

なお ASWebAuthenticationSession / Chrome Custom Tabs は
**「アプリ内に見えるが、実体は外部ブラウザ(Safari / Chrome)」**という
位置づけで、

  • Cookie / 認証状態をブラウザと共有する
  • アプリからは中身を触れない

ため、本仕様の要件を満たしつつ UX を損なわない。
WebView とは根本的に別物である点が重要。

WebView代替

OAuth2/OIDC の認証に WebView はダメっぽい。

  • Android 向け: Chrome Custom Tabs
  • iOS 向け: ASWebAuthenticationSession(旧 SFAuthenticationSession)/
    SFSafariViewController

参考

関連

  • OAuth PKCE
  • OAuth 2.0 for Browser-Based Apps(MS_OAuthForBrowserBasedApps.md
  • AppAuth(MS_AppAuth.md
    当該ベストプラクティスの採用を助ける OpenID Foundation が後援する一連のライブラリ。

Tags: 移行, IT国際標準, 認証基盤, クレームベース認証, OAuth

NetDevInfraWiki

マイクロソフト系技術情報 Wiki
Open 棟梁 Wiki

(未着手)

開発基盤部会 Wiki

移行管理: DONETODO

Clone this wiki locally