セッションのアジェンダ

武井宜行氏:こんにちは。SIOS PS Liveの第1回目を始めます。SIOS PS Liveでは、サイオステクノロジーのプロフェッショナルサービスラインのエンジニアたちが、隔週に渡っていろいろな技術情報を提供していきます。

弊社は認証、特にプロフェッショナルサービスラインは認証技術を得意としている部署なので、第1回目は「OAuthの入門」と題して、「世界一わかりみの深いOAuth入門」について説明したいと思います。さっそく始めます。

基本的には、OAuthに初めて触れる人に向けたセッションです。序章はOAuthをざっくり説明、第2章は認可コードフローやImplicitインプリシットフローなどといった、いろいろなフローです。第3章はリフレッシュトークン、第4章はアクセストークンです。第5章はOAuthを認証に使うことの危険性。第6章はstateパラメータによるCSRF対策です。

自己紹介です。私は武井と言います。サイオスプロフェッショナルラインに所属しているエンジニアです。主に認証関連のSI(System Integration)、ほかにAzureやCloudNative上でアプリを作るような仕事もよくやっています。普段からMicrosoft MVPとして、いろいろなマイクロソフトのイベントやコミュニティでの情報発信をしています。

本セッションの概要は、タイトルのとおり「世界のどこよりもわかりみの深いOAuth」をお届けします。難解と言われるOAuthをできるだけわかりやすく説明したいと思うので、OAuthなのにシーケンス図が一切出てこない、漫画だけといった内容ですが、まずはそこから入って理解してもらえたらと思います。

おすすめの書籍として、このセッションを見たあとに、ぜひとも『OAuth徹底入門』という本を読んでもらえるといいと思います。OAuthについてすごくやさしく詳しく書かれてあって、私も最初はこれで(勉強し)、さらに最近もけっこうこれで勉強しています。分厚いのですがわかりみの深い本なので、ぜひともこのセッションが終わったら手に取って読んでもらえれば幸いです。

OAuthとは何か?

ではさっそく、序章の「OAuthをざっくり説明」から入ります。まずはOAuthを本当にざっくり説明します。「よく聞くけどOAuthって何?」と、やはりみんなつまずくと思うんです。私も最初はすごくつまずいたし、今でもよくつまずくんですが、けっこうわかりにくい概念だと思います。

OAuthの特徴は、主に4つあります。1つ目は、従来のID・パスワードベースとは異なるトークンベースの認証。2つ目は、トークンには限られた権限だけを与えられているので、万が一トークンが盗まれても被害が少ない。3つ目は、認可コードフローやImplicitフローによりトークンを安全に取得。最後の4つ目は、トークンには有効期限が設定されており、万が一トークンを盗まれても有効期限が過ぎると使えないので、セキュアです。

これだけ聞いてもわからないと思います。私も最初はぜんぜんわかりませんでした。今回のセッションでは、この4つの謎を1つずつひもとこうと思っています。序章では、1つ目の従来のID・パスワードベースとは異なるトークンベースの認証と、トークンには限られた権限だけを与えられているのでうんぬんという、2つを説明したいと思います。

ID・パスワード認証、OAuth認証の比較

OAuthや仮想化やコンテナなどもそうですが、新しいテクノロジーを理解しようとする時、それに置き換わる従来のテクノロジーと比較すると、私はすごくわかりやすいんです。今回もご多分に漏れず、この方式で説明していこうと思います。

OAuthが登場する前は、ID・パスワード認証が主流だったと思います。従来のID・パスワードによる認証で、長い間GoogleやOffice365など、外部サービスのAPIを呼び出すことに使われてきました。自分のユーザー名とパスワードを入れて認証して、その結果、APIの返答が返ってくる。これが今まで使われていた方式です。

今回説明するのはそれに取って代わるトークンベースの認証方式で、最近はもっぱらこれになっています。このID・パスワード認証と、OAuthの認証を比較して説明したいと思います。

(スライドを指して)まずはID・パスワードベースの認証で考えてみます。これはよくある例ですが、Twitterにつぶやくと、自動的にFacebookに反映されるというユースケースです。

ID・パスワードベース認証の場合、どういう動きになるのかというと、最初にやることはAさん(Twitterを利用する人)です。Twitterのシステムに、FacebookのユーザーIDとパスワードを登録します。これは当然です。Facebookに接続してTwitterの投稿を反映するので、FacebookのユーザーIDとパスワードがTwitterにも必要です。

そしてAさんが「白金なう」とつぶやくと、Twitterのシステムに登録されているFacebookのユーザーIDとパスワードを基に、Facebookに接続しにいきます。

すると、Aさんの代わりにTwitterが「白金なう」とつぶやきます。

でも、これには実はすごく恐ろしい脆弱性があります。仮にTwitterの運営者の中にすごく悪い人がいた場合、このTwitterの運営者はFacebookのユーザーIDとパスワードを知っているわけなので、FacebookのユーザーIDとパスワードを盗んでログインして、投稿を削除したり退会したり、そんなこともできてしまうわけです。やはりユーザーIDをFacebookのユーザーIDやほかのシステムに預けることは、すごく危険な行為です。

これを解決するのがOAuthです。OAuthの場合、(スライドを指して)ここでフローを説明します。まず、Twitterのシステム管理者や運用管理者みたいな人が、FacebookにTwitterと連携する申請をします。

その結果、クライアントIDとクライアントシークレットというものがFacebookから発行されます。同時に利用サービスというものも発行されます。

利用サービスとは、Facebookに対してできるアクションです。postとviewです。例えば、投稿と閲覧しかできないというものを独自の文字列にして、Facebookのデータベースに格納します。これを受け取ったTwitterシステム管理者は、Twitterのシステムの中のクライアントIDと、クライアントシークレットと、利用サービスを格納します。ここまでで、Twitterのシステム管理者の仕事は終わりです。

次に、先ほどのAさんがTwitterにつぶやいてFacebookに反映させる流れを説明します。まずAさんは、TwitterにFacebook連携を要求します。

そうすると、AさんはFacebookに1回リダイレクトされます。この時、クエリパラメータにクライアントIDを指定しますが、Facebookは「このクライアントIDを指定したからこれはTwitterからの連携なんだ」と理解できます。それによって、Facebookのログイン画面を出します。

そうすると「Twitterと連携してもいいですか?」みたいな画面が出て、先ほどの画面で「OK」をクリックすると、またTwitterにリダイレクトされます。この時、リダイレクトされるURLのクエリのパラメータに認可コードが発行されます。

認可コードが発行されると同時に、Facebookのデータベースの中にも認可コードと有効期限が登録されます。認可コードが発行され、リダイレクトなのでTwitterに認可コードが渡ります。

認可コードを受け取ったTwitterは、今度は認可コードをFacebookに渡します。受け取ったFacebookは認可コードの有効期限が過ぎていないか、有効期限内かを確認をしています。

認可コードが一致しているとわかったら、OAuthのアクセストークンというものを発行します。アクセストークンを発行したら、当然「このアクセストークンは〇〇さんに発行しました」とFacebookの中で保存して、これを受け取ったTwitterも当然このアクセストークンをTwitterの中に保存します。

AさんはTwitterでつぶやきます。ここからOAuthの連携が始まります。

Twitterには、まずAさんのつぶやきが表示されます。それと同時に、バックグラウンドでは、先ほどTwitterの中で取得したアクセストークンをFacebookに渡します。

アクセストークンを受け取ったFacebookは、データベースからアクセストークンを検索します。もらったアクセストークンが自分のデータベースの中にあるかを検索して、「このアクセストークンはAさんのアクセストークンだ」となったら、AさんのFacebookのIDに、同じ「白金なう」という投稿を反映する。このような流れで連携が行われます。

ここで再び悪い人が登場します。Twitterの運営の中の悪い人です。仮にIDとパスワードを盗んでFacebookの退会処理をしてやろうなどと思ったとしても、(この場合は)できません。

なぜかというと、アクセストークンにはpostとview(投稿と閲覧)くらいの権限しかないからです。そのようにFacebookで制御をかけています。「このアクセストークンをFacebookに要求されたとしても、投稿と閲覧しかできません」といった制御をかけているので、Twitter運営の中の悪い人ができるのは、せいぜい「ほげ」などと、変なことをつぶやくくらいです。IDとパスワードを渡していないので、退会処理や削除処理ができない。

IDとパスワードをこのままほかのシステムに渡すのではなく、トークンを渡すことで、万が一トークンを盗まれた場合にも、被害を最小限に済ませられる。これがOAuthの最大のメリットです。

なぜ直接アクセストークンを渡さないのか?

ここでやや疑問ですが、今は認可コードというものを使うと思います。「認可コードを使うと手順が複雑になるし、直接アクセストークンを渡してくれればいいんじゃないのかな」と思うかもしれません。ただ、認可コードを渡すというフローを思い出してほしいんですが、認証が終わるとリダイレクト経由で認可コードが渡ります。これはさっきの認可コードを渡したところのおさらいです。

認可コードを要求して、アクセストークンをもらいます。

ここで認可コードを経由するのではなく、直接アクセストークンをリダイレクトで渡したらどうなるか。どういう被害が生じるかというと、ハッカーが登場した時に、このアクセストークンはネットワーク上に流れているので、盗む機会が多くなるんです。

アクセストークンはなるべくネットワーク上に流さない。大事な情報はネットワーク上に流さないという、絶対的な条件があります。当然、重要な情報がネットワーク上に流れる頻度が多ければ、それだけ盗まれる機会も多くなるので、できるだけアクセストークンのようなものはネットワーク上に流さないのがOAuthのポリシーなのです。今度説明するImplicitフローは流れてしまうケースもあったりしますが、できるだけ流さない。

でも、認可コードだって取得したらそれを持ってアクセストークンを要求できるので「認可コードだって同じじゃん」と思うかもしれません。ただ、認可コードはアクセストークンに比べて、すごく有効期限が短いんです。OAuthの仕様では10分。

仮に認可コードがハッカーに盗まれたとしても、10分はすごく短い有効期限なので、それを使おうとする時には時間切れになっているかもしれない。そうすることによって、「たとえネットワークに流れても有効期限が短いので、セキュアでしょう」ということで認可コードを使っています。

OAuthの一番のメリットはトークンベースの認証で被害が少ないこと

今回の章では、2つについて説明しました。従来のID・パスワードベースとは異なるトークンベースの認証、トークンには限られた権限だけを与えているので、万が一、トークンが盗まれても被害が少ない。

繰り返しになりますが、IDやパスワードをそのまま渡すと、どのように使われるかわかりません。先ほど言ったように、TwitterがFacebookのIDとパスワードを受け取ったらどう使われるかわかりませんが、トークンだけ渡しておけば、トークンにはぜんぜん権限がないので盗まれたとしても大したことはできません。これがOAuthの一番のメリットで、これさえ押さえておけばOAuthはもうぜんぜん怖くないんです。

私も、最初は知らないことばかりでしたが、この概念を披露されたら、ほかの細かい部分は仕様を見て調べればいいやとなって苦手意識が消えたので、このポイントを押さえてもらえたらと思います。

(次回に続く)