RESTful認証とはどういう意味ですか、またどのように機能しますか?グーグルには概要がよくわかりません。私が唯一理解しているのは、あなたがURLでセッションキー(remeberal)を渡すということですが、これはひどく間違っているかもしれません。
RESTfulクライアントサーバーアーキテクチャで認証を処理する方法は、議論の問題です。
一般的に、HTTP経由のSOAで次の方法で実現できます。
せいぜいソフトウェアアーキテクチャに合わせて、これらの手法を適応させるか、さらにうまく組み合わせる必要があります。
各認証スキームには、セキュリティポリシーとソフトウェアアーキテクチャの目的に応じて、独自のPROとCONがあります。
HTTPS経由のHTTP基本認証
標準のHTTPSプロトコルに基づくこの最初のソリューションは、ほとんどのWebサービスで使用されています。
GET /spec.html HTTP/1.1
Host: www.example.org
Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==
実装は簡単で、デフォルトですべてのブラウザで利用できますが、ブラウザに表示されるひどい認証ウィンドウなど、いくつかの既知の欠点があります。このウィンドウは永続します(ここではLogOutのような機能はありません)。そして、ユーザー名とパスワードが(HTTPSを介して)サーバーに送信されるという事実(パスワードは、キーボード入力中にクライアント側のみに残し、サーバーに安全なハッシュとして保存できるようにする方が安全です) 。
ダイジェスト認証 を使用できますが、 MiM または Replay 攻撃に対して脆弱であり、HTTPに固有であるため、HTTPSも必要です。
Cookie経由のセッション
正直に言うと、サーバー上で管理されるセッションは完全にステートレスではありません。
1つの可能性は、Cookieコンテンツ内のすべてのデータを維持することです。また、設計上、Cookieはサーバー側で処理されます(実際、クライアントは、このCookieデータを解釈しようとさえしません。リクエストが連続するたびにサーバーに返します)。ただし、このCookieデータはアプリケーション状態データであるため、クライアントはサーバーではなく、純粋なステートレスの世界で管理する必要があります。
GET /spec.html HTTP/1.1
Host: www.example.org
Cookie: theme=light; sessionToken=abc123
Cookieの技術自体はHTTPリンクされているため、プロトコルに依存しない、真のRESTfulである必要はありません。 MiM または Replay 攻撃に対して脆弱です。
トークン(OAuth2)を介して付与
別の方法は、HTTPヘッダー内にトークンを入れて、要求が認証されるようにすることです。これは、たとえばOAuth2.0が行うことです。 RFC 6749 を参照してください:
GET /resource/1 HTTP/1.1
Host: example.com
Authorization: Bearer mF_9.B5f-4.1JqM
要するに、これはCookieに非常に似ており、同じ問題を抱えています。ステートレスではなく、HTTP送信の詳細に依存し、 多くのセキュリティの弱点 -MiMおよびReplayを含む- HTTPSでのみ使用されます。通常、 JWT がトークンとして使用されます。
クエリ認証
クエリ認証は、URIの追加パラメーターを介して各RESTfulリクエストに署名することで構成されます。 このリファレンス記事 を参照してください。
この記事では次のように定義されています。
すべてのRESTクエリは、プライベートクレデンシャルを署名トークンとして使用して、アルファベット順に小文字でソートされたクエリパラメータに署名することにより認証する必要があります。クエリ文字列をURLエンコードする前に署名を行う必要があります。
この手法は、おそらくステートレスアーキテクチャとの互換性が高く、軽いセッション管理(DB永続性の代わりにメモリ内セッションを使用)で実装することもできます。
たとえば、上記のリンクからの汎用URIサンプルは次のとおりです。
GET /object?apiKey=Qwerty2010
次のように送信する必要があります。
GET /object?timestamp=1261496500&apiKey=Qwerty2010&signature=abcdef0123456789
署名される文字列は/object?apikey=Qwerty2010×tamp=1261496500
で、署名はAPIキーのプライベートコンポーネントを使用したその文字列のSHA256ハッシュです。
サーバー側のデータキャッシュは常に利用可能です。たとえば、フレームワークでは、URIレベルではなくSQLレベルで応答をキャッシュします。したがって、この余分なパラメーターを追加しても、キャッシュメカニズムは壊れません。
JSONとRESTに基づくクライアントサーバーORM/SOA/MVCフレームワークでのRESTful認証の詳細については、 この記事 を参照してください。 HTTP/1.1だけでなく、名前付きパイプまたはGDIメッセージ(ローカル)による通信も許可するため、HTTPの特異性(ヘッダーやCookieなど)に依存せず、真のRESTful認証パターンを実装しようとしました。 。
後注:署名をURIに追加するのは悪い習慣とみなされる可能性があります(たとえば、httpサーバーのログに表示されるため)、緩和する必要があります。適切なTTLにより、リプレイを回避します。しかし、httpログが危険にさらされると、確かに大きなセキュリティ問題が発生します。
実際には、今後の OAuth 2.0のMACトークン認証 は、「トークンによる許可」の現在のスキームに関して大幅に改善される可能性があります。しかし、これはまだ進行中の作業であり、HTTP送信に関連付けられています。
結論
RESTはHTTPベースであるだけでなく、実際にはほとんどがHTTPを介して実装されている場合でも、結論付ける価値があります。 RESTは、他の通信レイヤーを使用できます。したがって、RESTful認証は、Googleが答えたものが何であれ、HTTP認証の単なる同義語ではありません。 HTTPメカニズムを使用する必要はありませんが、通信層から抽象化されます。そして、HTTP通信を使用する場合、 Let's Encrypt Initiative のおかげで、認証スキームに加えて必要な適切なHTTPSを使用しない理由はありません。
私は熱心に「HTTP認証」を叫んでいる人がRESTを使って(マシン間のWebサービスではなく)ブラウザベースのアプリケーションを作成しようとしたことがあるかどうか疑問に思います。彼らはこれまで複雑さに直面していました。
ブラウザで表示されるHTMLページを生成するRESTfulサービスでHTTP認証を使用することで私が見つけた問題は次のとおりです。
ポイントごとに取り組む非常に洞察力に富んだ記事は here ですが、これはブラウザ固有のjavascriptハッカーの lot になります、回避策の回避策など。このように、それはまた前方互換性がないので、新しいブラウザがリリースされたときに一定のメンテナンスを必要とします。私はその清潔で明確なデザインを考慮していません、それに私は自分のRESTバッジを私の友人に熱心に見せることができるようにそれが余分な仕事と頭痛の種であると感じます。
私はクッキーが解決策だと思います。しかし、ちょっと待って、クッキーは悪ですね。いいえ、そうではありません。クッキーがよく使用される方法は悪です。 Cookie自体は、ブラウザをブラウズしている間追跡するHTTP認証情報とまったく同じように、クライアント側の情報の一部にすぎません。そして、このクライアントサイドの情報は、HTTP認証情報と同じように、リクエストごとにサーバーに送信されます。概念的には、唯一の違いは、このクライアント側の状態の content が、応答の一部として server によって決定されることです。
次の規則に従って、セッションをRESTfulなリソースにすることで、
HTTP認証との唯一の違いは、認証キーがサーバーによって生成され、入力された資格情報からそれを計算するのではなく、それを送り返し続けるクライアントに送信されることです。
コンバーター42は、httpsを使用する場合(これを推奨)、認証情報が安全でない接続を介して送信されないように、Cookieに安全フラグを設定することが重要であることを付け加えます。素晴らしい点は、それを自分で見たことがなかったです。
これは問題なく機能するのに十分なソリューションであると思いますが、このスキームの潜在的なホールを特定するにはセキュリティ専門家では十分ではないことを認めなければなりません。ログインプロトコル(PHPでは$ _SESSION、Java EEではHttpSessionなど)。 Cookieヘッダーの内容は、accept-languageが翻訳リソースへのアクセスに使用されるのと同じように、単にサーバーサイドのリソースをアドレス指定するために使用されます。私はそれが同じであると感じますが、多分他の人は違いますか?どう思いますか?
この話題については、すでに十分な人がここで言っています。しかし、これが私の2セントです。
相互作用には2つのモードがあります。
マシンはREST APIとして表現される共通の分母であり、アクター/クライアントは人間かマシンのどちらかです。
さて、真のRESTfulアーキテクチャーでは、ステートレス性の概念は、すべての関連アプリケーション状態(クライアント側の状態を意味する)がそれぞれの要求ごとに提供される必要があることを意味します。関連性があるということは、REST APIが要求を処理して適切な応答を提供するために必要なものは何でもということです。
Skrebbelが前述したように、「ブラウザベース」のヒューマンツーマシンアプリケーションのコンテキストでこれを考慮すると、ブラウザで実行されている(Web)アプリケーションは、リクエストごとに状態と関連情報を送信する必要があります。それはバックエンドにREST APIを作ります。
これを考慮してください:あなたはRESTAPIのデータ/情報プラットフォーム公開資産を持っています。おそらく、すべてのデータキューブを処理するセルフサービスBIプラットフォームがあります。しかし、あなたはあなたの(人間の)顧客が(1)ウェブアプリ、(2)モバイルアプリ、そして(3)あるサードパーティのアプリケーションを通してこれにアクセスすることを望みます。結局、MTMのチェーンでさえもHTMにつながります。それで、人間のユーザは情報チェーンの頂点にあり続けます。
最初の2つのケースでは、人間とマシンの間のやり取りがあり、その情報は実際には人間のユーザーによって消費されます。最後のケースでは、REST APIを使用するマシンプログラムがあります。
認証の概念は全面的に適用されます。 REST APIが統一された安全な方法でアクセスされるように、これをどのように設計しますか?私がこれを見る方法は、2つの方法があります。
方法1:
方法2:
明らかに、方法2では、REST APIには、トークンを有効であると認識して信頼する方法が必要です。 Login APIは認証検証を実行したため、カタログ内の他のREST APIによって「バレーキー」を信頼する必要があります。
これは、もちろん、認証キー/トークンを格納してREST API間で共有する必要があることを意味します。この共有された信頼されたトークンリポジトリは、ローカル/統合されたもので、他の組織のREST APIが互いに信頼できるようにします。
しかし、私は話します。
要点は、すべてのRESTAPIが信頼の輪を作り出すことができるように、「状態」(クライアントの認証済みの状態について)を維持し共有する必要があるということです。これをしない場合、それは方法1であり、認証の動作が入ってくるすべての要求に対して実行されなければならないことを受け入れなければなりません。
認証の実行は、リソースを大量に消費するプロセスです。ユーザーストアに対して、受信したリクエストごとにuid/pwdの一致を確認するためにSQLクエリを実行するとします。または、ハッシュマッチを暗号化して実行する(AWSスタイル)。そしてアーキテクチャ的には、すべてのREST APIがこれを実行する必要があります。おそらく、一般的なバックエンドログインサービスを使用します。そうでない場合は、認証コードをあちこちにポイ捨てします。大混乱です。
層が多いほど、レイテンシーは長くなります。
さて、方法1を取り、HTMに適用してください。あなたの(人間の)ユーザは、あなたがuid/pwd/hashを送信しなければならないのか、あるいはあらゆる要求で何でもしなければならないのか、本当に気にしますか?いいえ、毎秒auth/loginページを投げて気にしないのであれば。あなたがそうであれば、幸運を祈ります。ですから、あなたがすることは、ログイン情報をクライアントサイドのどこか、ブラウザの始めの方に保存し、リクエストがあるたびにそれを送信することです。 (人間の)ユーザにとっては、彼女はすでにログインしており、そして「セッション」が利用可能である。しかし、実際には、彼女はすべての要求で認証されています。
方法2と同じです。あなたの(人間の)ユーザーは決して気付かないでしょう。害はありませんでした。
MTMにWay-1を適用するとどうなりますか?この場合、そのマシンであるため、リクエストごとに認証情報を送信するように要求することで、この男から地獄に耐えることができます。誰も気にしない! MTMで方法2を実行しても、特別な反応はありません。それはいまいましい機械です。気にする必要はありません。
だから本当に、問題はあなたのニーズに合ったものです。無国籍は支払う代償があります。代金を払って先へ進んでください。もしあなたが純粋主義者になりたいのなら、その分の代金を払って先へ進んでください。
結局、哲学は重要ではありません。本当に重要なのは、情報の発見、提示、そして消費経験です。人々があなたのAPIを愛しているなら、あなたはあなたの仕事をしました。
これは、真に完全にRESTfulな認証ソリューションです。
クライアントが認証するとき:
3.1。以下を含むトークンを発行します。
3.2。トークンを秘密鍵で暗号化します。
3.3。暗号化されたトークンをユーザーに送り返します。
ユーザーがAPIにアクセスするときには、認証トークンも渡す必要があります。
これはステートレス/ RESTful認証です。
パスワードハッシュが含まれている場合、ユーザは認証トークンとともに暗号化されていないパスワードも送信することに注意してください。サーバーは、ハッシュを比較することによって、パスワードが認証トークンの作成に使用されたパスワードと一致したことを確認できます。 HTTPSのようなものを使った安全な接続が必要でしょう。クライアント側のJavascriptは、ユーザーのパスワードを取得し、それをクライアント側でメモリまたはCookieに保存します。おそらくサーバーの public キーで暗号化されています。
あなたと正直に言うと私はここで素晴らしい答えを見ましたが、誰かがそれが独断的になるところで極端に全体のステートレス概念を取る時に私は少し気になるものです。純粋なOOのみを受け入れたいと思っていた古いSmalltalkのファンを思い出させます。何かがオブジェクトではない場合は、間違っています。休憩をください。
RESTfulなアプローチはあなたの人生を楽にし、セッションのオーバーヘッドとコストを減らすことになっています、それはすることが賢いことであるのでそれに従うようにしてください。それが意図されていた利益をもはや提供しません、そしてあなたはそれを間違ってやっています。今日最も優れた言語のいくつかは、関数型プログラミングとオブジェクト指向の両方を持っています。
あなたがあなたの問題を解決するための最も簡単な方法がクッキーに認証キーを保存してHTTPヘッダにそれを送ることであるならば、それをしなさい、ただそれを悪用しないでください。セッションが重くて大きくなると、セッションは良くないことを覚えておいてください。あなたのセッションがすべてキーからなる短い文字列で構成されている場合、大したことは何でしょうか。
私はコメントの訂正を受け入れることに寛容ですが、私たちのサーバーにハッシュの大きな辞書を残さないようにすることを私たちの生活を悲惨なものにすることには意味がありません。
まず第一に、RESTful Webサービスは _ stateless _ (つまり、 _ sessionless _ )です。したがって、RESTfulサービスにはセッションやCookieの概念は含まれておらず、また含まれるべきではありません。 RESTfulサービスで認証または許可を行う方法は、RFC 2616 HTTP仕様で定義されているHTTP Authorizationヘッダーを使用することです。すべてのリクエストにHTTP Authorizationヘッダーが含まれている必要があり、リクエストはHTTP(SSL)接続を介して送信される必要があります。これは、認証を行い、HTTP RESTful Webサービスの要求の承認を確認する正しい方法です。シスコシステムズのCisco PRIME Performance Managerアプリケーション用のRESTful Webサービスを実装しました。そして、そのWebサービスの一部として、認証/承認も実装しました。
ルーベンスゴメス.
RESTのすべての制約の中で実行されるセッションレス認証を指すために一般的に使用されるので、それは確かに「セッションキー」についてではありません。各要求は自己記述的であり、サーバー側のアプリケーション状態がなくても要求を独自に承認するのに十分な情報を持っています。
これに取り組む最も簡単な方法は RFC 2617 のHTTPの組み込み認証メカニズムから始めることです。
@skrebel( http://www.berenddeboer.net/rest/authentication.html )によって言及された '非常に洞察力のある'記事では、複雑ではあるが本当に壊れた認証方法について説明しています。
あなたはそのページにアクセスしようと試みるかもしれません(これは認証されたユーザーだけに見えるはずです) http://www.berenddeboer.net/rest/site/authenticated.html ログイン資格情報なしで/。
(申し訳ありませんが、回答にコメントすることはできません。)
私はRESTと認証が混在しないと言うでしょう。 RESTはステートレスを意味しますが、「認証済み」はステートです。両方を同じレイヤーに配置することはできません。あなたがRESTfulな提唱者であり、州に眉をひそめている場合は、HTTPSを使用する必要があります(つまり、セキュリティの問題を別の層に任せます)。
安らかな認証には、リクエスト内のパラメータとして認証トークンを渡すことが含まれると思います。例はapiのapikeysの使用です。私はクッキーやhttp authの使用が有効であるとは思わない。
下記のアプローチは、本質的に "リソース所有者パスワード認証情報"の付与タイプ OAuth2.0 です。これは簡単に立ち上がるための方法です。ただし、この方法では、組織内のすべてのアプリケーションが独自の認証および承認メカニズムを使用することになります。推奨されるアプローチは、「承認コード」付与タイプです。さらに、以下の私の以前の回答では、認証トークンを保存するためのブラウザlocalStorageをお勧めしました。しかし、私はクッキーがこの目的のための正しい選択肢であると信じるようになりました。私の理由、認証コード付与タイプの実装方法、セキュリティ上の考慮事項などを this StackOverflow answer で詳しく説明しました。
RESTサービス認証には、次のアプローチを使用できると思います。
このアプローチでは、30分ごとにユーザー固有のアクセス権の詳細をキャッシュにロードするという高価な操作を行っています。そのため、アクセスが取り消されたり、新しいアクセスが許可されたりした場合は、反映に30分かかるか、ログアウトしてからログインする必要があります。
OAuthをサポートしている限り、Google以外の認証方法を使用することもできます。
鍵の登録に適切なバインディングが含まれるような公開鍵インフラストラクチャを使用すると、公開鍵は確実に否認防止を保証する方法で割り当てられた個人にバインドされます。
http://en.wikipedia.org/wiki/Public_key_infrastructure を参照してください。適切なPKI標準に従うと、盗まれたキーを不適切に使用した人または代理人が特定され、ロックアウトされる可能性があります。エージェントが証明書を使用する必要がある場合、バインディングはかなり厳しくなります。賢くて動きの速い泥棒は逃げることができますが、彼らはより多くのパン粉を残します。
私の理解からこの質問に答えるには...
システム内のユーザーを実際に追跡または管理する必要がないようにRESTを使用する認証システム。これはHTTPメソッドPOST、GET、PUT、DELETEを使用して行われます。私たちはこれら4つの方法を取り、データベースの相互作用の観点からそれらをCREATE、READ、UPDATE、DELETEと考えています(しかしウェブ上ではPOSTとGETを使っています)。そのため、POSTとGETをCREATE/READ/UPDATE/DELETE(CRUD)として扱うことで、Webアプリケーションでルートを設計して、達成しているCRUDのアクションを推測することができます。
たとえば、Ruby on Railsアプリケーションでは、ログインしているユーザーが http://store.com/account/logout にアクセスした場合、そのページのGETが次のように表示されるようにWebアプリケーションを構築できます。ユーザーがログアウトしようとしています。私たちのRailsコントローラでは、ユーザをログアウトさせてそれらをホームページに送り返すアクションを構築します。
ログインページでGETを実行するとフォームが生成されます。ログインページのPOSTはログイン試行と見なされ、POSTデータを使用してログインに使用します。
私にとっては、データベースの意味にマッピングされたHTTPメソッドを使用してから認証システムを構築するのが習慣です。それを念頭に置いて、セッションIDを見渡したりセッションを追跡したりする必要はありません。
私はまだ学んでいます - あなたが私が間違っていると言った何かを見つけたら私を訂正してください、そしてあなたがもっと学んだらここにそれを投稿してください。ありがとう。
あらゆるWebアプリケーションのセキュリティを保護するために有効なヒント
あなたのアプリケーションを安全にしたいのなら、それで間違いなくHTTPの代わりにHTTPSを使うことから始めるべきです、これはあなたとユーザー間の安全なチャンネルの作成を保証します。ユーザーとやり取りすることで、データ交換の機密性を保つことができます。
RESTful APIを保護するためにJWT(JSON Web Tokens)を使用することができます 、これはサーバーサイドセッションと比較した場合、多くの利点があります。利点は主に以下のとおりです。
1 - あなたのAPIサーバーが各ユーザーのためにセッションを維持する必要がないので、よりスケーラブルです(あなたが多くのセッションを持っているとき、これは大きな負担になる可能性があります)。
2- JWTは自己完結型であり、ユーザーの役割を定義するクレームを持っています。
3-ロードバランサー間での処理が簡単。複数のAPIサーバーがある場合、セッションデータを共有したり、同じサーバーにセッションをルーティングするようにサーバーを設定したりする必要がないため、JWTによるリクエストが認証可能承認済み
4-あなたのDBへのより少ない圧力と同様にあなたは絶えず各要求のためにセッションIDとデータを保存して取り出す必要はありません
5- JWTに署名するために強力な鍵を使用する場合、JWTは改ざんできません。そのため、ユーザーセッションを確認しなくても、要求と共に送信されたJWT内のクレームを信頼できます。 JWTをチェックするだけで、その後、このユーザーが誰に何をできるのかを知ることができます。
多くのライブラリは、ほとんどのプログラミング言語でJWTを簡単に作成および検証する方法を提供します。例えば、node.jsで最も人気のあるものの1つは jsonwebtoken です。
REST APIは通常、サーバーをステートレスに保つことを目的としているため、JWTはその概念との互換性が高くなります 各要求は自己完結型の認可トークンで送信されるため (JWT) ユーザーとその役割を記憶するようにサーバーをステートフルにするセッションと比較してサーバーがユーザーセッションを追跡する必要はありませんが、セッションも広く使用されていますし、長所もあります。 。
注意すべき重要なことの1つは、HTTPSを使用してJWTをクライアントに安全に配信し、安全な場所(ローカルストレージなど)に保存する必要があることです。
あなたはJWTについてもっと知ることができます このリンクから