ファーストパーティーなアプリが使うOAuth/OIDCについてのお話 2019 春

夜分遅くに失礼いたします。ritouです。

こういう記事を読むとうずうずします。おそらく病気です。

terut.hatenablog.com

森羅万象を担当しているわけではないので、OAuth/OIDCが使えんのか?って観点から書いておきます。

ファーストパーティーのOAuth/OIDC利用

単一サービス内でOAuth/OIDC使うことってあるのか?という問いには「条件によっては適用可能」といったふわっとした答えになりそうです。フワッ

Webアプリ

Webアプリでも例えばドメインいっぱいある、別れている系でOAuth/OIDCでつなぐケースはありそうですね。

  • Microsoft : https://www.office.com/ -> https://login.microsoftonline.com/common/oauth2/authorize?client_id=... OAuth 2.0
  • Amazon : https://www.amazon.co.jp/ -> https://www.amazon.co.jp/ap/signin?openid.return_to=https%3A%2F%2Fwww.amazon.co.jp%2F OpenID 2.0!!!

当然、クロスドメインなセッションの確認方法、ログアウト時の処理など色々考慮する点は増えるかと思います。

Nativeアプリ

この辺りはあまり適当なことは書けませんが...要件としては「認証してリソースアクセスしたい」だと思います。 これを3つのステップに分割すると

  • Access Tokenを用いたリソースアクセス : 独自で作ったってどうせBearerっぽいのでやるんでしょう?
  • Access Tokenを払い出す機能
  • ユーザー認証機能

となり、主にユーザー認証とトークン払い出すところどうするんやというあたりでしょう。

  • NativeApp内でログイン画面を実装 : (サーバー側)独自のGrantTypeを作る、もしくは別Endpointとして各種トークンを払い出す機能を作る。WebAppがないNativeAppならこっちで良いかも?
  • 外部ブラウザ(相当のもの)を使う : (サーバー側)OAuth/OIDCのAuthorization Code Grant + PKCEとかで画面スキップ(後述)などUXをキメる。WebAppがあるならこっちの方がメリットあるかも

というあたりの選択になりそうですが、サービスの特性や今後の展開予定などにもよるのではないでしょうか。 サービスとしてNativeAppしかない場合に後者は厳しいでしょう。 例えば、最近のWebAuthnのようにWebAppの認証機能を作り込むといろんな環境でメリットがあるみたいな流れで行くと、後者もアリな気がします。

最近こんなの見かけたんですが、ファーストパーティーならこういう新しい仕組みも使えるかもしれません。

developers-jp.googleblog.com

Trusted Web Activity は、Android アプリ内で Chrome ブラウザを全画面で実行します。アプリ内に URL バーなどのブラウザの UI は表示されません。これは強力な機能なので、アプリとサイトが同じデベロッパーのものであること、すなわち「信頼できる」ことを検証しなければなりません。アプリと TWA で開いたサイトが同じデベロッパーのものであることを検証するために、TWA は Digital Asset Links を使って所有権を確認します。

まさにこれでは?期待ですね。

Resource Owner Password Credentials(ROPC)

ユーザーのCredentialを送ってTokenを取得するこの Grant Type ですが、認証機能付きの Access Token 払い出し機能ではありません。 そう思いたい気持ちはわからんでもないですが、ROPCでログイン機能作ろうと思うと、2段階認証とかどうしたら良いんや〜とかエラー表現〜とか色々思うところあると思います。あとログインだけあっても登録...ってなる。

ROPCは同じくユーザーのCredentialを預かってBasic認証API叩いてた系の仕組みに対して

  1. Basic認証からROPCにより一度Access Tokenに変換してやって保存し、リソースアクセスする仕組みに変える
  2. ユーザーのCredentialを受け取るのではなく、Authorozation Code などでAccess Tokenを取得する仕組みに変える

という手順をとってOAuthを使う仕組みに移行するためのものだと思いましょう。

同意画面のスキップについて

この辺りはコアな仕様の対象外かと思います。特定ユースケースに対するProfile系の仕様なら言及があるかもしれません。

同意画面の目的は "Clientがあなたに代わって(scope相当の)リソースアクセスをしようとしています。"という通知をして同意を得るためのものでしょう。 最近だとClient側のサービスの利用規約、プライバシーポリシーのリンクまで出すようにしてるとこもあると思います。

  • ファーストパーティー、セカンドパーティーならスキップ
  • ユーザーが「次回から表示しない」をチェックしたらスキップ
  • 同じclient,scopeで2回目以降ならスキップ

などなど、仕組みをOAuth/OIDCで作っておいて同意画面を飛ばすというやり方はずっと前からあるのでその辺はユーザーに説明できているかなどで判断すると良いかと思います。

理想としては、ファーストパーティーのアプリだとしてもAndroidのPermissionみたいな感じで例えばセンシティブな機能へのリソースアクセスを個別に拒否でき、拒否した機能を使いたくなったら再認可みたいな世界になってほしい気はします。と言い続けて10年ぐらい経ちました。

そこまでいかなくても、WebベースでやってきたサービスがNative Appを出しても「このアプリを使うとこんなデータが流れる!」みたいなのを気にする人もいるでしょうし、ファーストパーティーでもヘルプなり規約なりでどこかでちゃんと説明しておくってのは必要でしょう。

ザーッと書いてみました。寝かせるほどでもないのですぐに公開(投稿)しちゃいます。 深夜なので書き忘れてることがあったら後から追記します。 気になる点などありましたらコメントや言及してください。

そう言えば、昔のブログ(Y!ブログ)の記事を遡っていったら、自分は当初"ritou"を名乗っていなかったことがわかりました。いつから名乗り始めたのか記憶がない...

ではまた💤