RESTful認証とは何を意味し、どのように機能しますか?Googleで適切な概要を見つけることができません。私の唯一の理解は、URLでセッションキー(メモ)を渡すことですが、これはひどく間違っている可能性があります。
RESTful認証とは何を意味し、どのように機能しますか?Googleで適切な概要を見つけることができません。私の唯一の理解は、URLでセッションキー(メモ)を渡すことですが、これはひどく間違っている可能性があります。
回答:
RESTfulクライアント/サーバーアーキテクチャで認証を処理する方法は、議論の余地があります。
一般的に、SOA over HTTPの世界では、次の方法で実現できます。
ソフトウェアアーキテクチャを最大限に一致させるには、これらの手法を適応させるか、さらにうまく組み合わせる必要があります。
各認証スキームには、セキュリティポリシーとソフトウェアアーキテクチャの目的に応じて、独自のPROとCONがあります。
HTTPS経由のHTTP基本認証
標準のHTTPSプロトコルに基づくこの最初のソリューションは、ほとんどのWebサービスで使用されています。
GET /spec.html HTTP/1.1
Host: www.example.org
Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==
実装は簡単で、すべてのブラウザでデフォルトで使用できますが、ブラウザに表示されるひどい認証ウィンドウが存続する(ここではLogOutのような機能はありません)、サーバー側の追加のCPU消費など、いくつかの既知の欠点があります。ユーザー名とパスワードが(HTTPS経由で)サーバーに送信されるという事実(キーボード入力時にクライアント側にのみパスワードを保持し、サーバーに安全なハッシュとして保存する方が安全です) 。
ダイジェスト認証を使用する場合もありますが、MiM攻撃またはリプレイ攻撃に対して脆弱であり、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にリンクされているため、プロトコルに依存しないIMHOであるRESTfulなものではありません。MiMまたはリプレイ攻撃に対して脆弱です。
トークン経由で付与(OAuth2)
別の方法として、HTTPヘッダー内にトークンを配置して、リクエストが認証されるようにすることもできます。これは、たとえばOAuth 2.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トークン認証は、「Granted by Token」の現在のスキームに関して大幅な改善になる可能性があります。しかし、これはまだ進行中の作業であり、HTTP送信に関連付けられています。
結論
RESTは、実際にはほとんどがHTTPを介して実装されている場合でも、HTTPベースだけではないという結論に値します。RESTは他の通信レイヤーを使用できます。したがって、RESTful認証は、Googleが回答するものを問わず、HTTP認証の同義語ではありません。HTTPメカニズムをまったく使用しないでください。ただし、通信層から抽象化する必要があります。そして、HTTP通信を使用する場合、Let's Encryptイニシアチブのおかげで、認証スキームに加えて必要な適切なHTTPSを使用しない理由はありません。
Cookie
より優れた代替として使用する場合はHTTP Basic Auth
、認証を期限切れにする方法とログアウト機能を使用して、本当にステートレスな認証を行うことができます。実装例ではEmulated-HTTP-Basic-Auth
、実際のHTTP基本認証と同様の値で呼び出されるCookieを使用し、さらに有効期限を設定できます。ログアウトは、そのCookieを削除して実装できます。HTTP Basic Authをサポートできるクライアントであれば、この方法で行われるCookie認証もサポートできると思います。
Cookie
代わりに、別のヘッダー()内の同じものに対してエミュレーションを提供するサーバーを使用できます。
「HTTP認証」と熱狂的に叫んでいる人々が、RESTを使用して(マシンツーマシンのWebサービスではなく)ブラウザベースのアプリケーションを作成しようとしたことがあるかどうかは疑問です(問題はありません。 。
ブラウザで表示するHTMLページを生成するRESTfulサービスでHTTP認証を使用するときに私が見つけた問題は次のとおりです。
これらのポイントごとに取り組む非常に洞察に富んだ記事がここにありますが、これにより、ブラウザ固有の多くのJavaScriptハッキング、回避策の回避策などが発生します。そのため、これは前方互換性もないため、新しいブラウザがリリースされるたびに定期的なメンテナンスが必要になります。私はそのすっきりとしたデザインを考慮していません。さらに、RESTバッジを友達に熱心に見せるために、余計な手間と頭痛がたくさんあると感じています。
クッキーが解決策だと思います。しかし、待ってください、クッキーは悪ですよね?いいえ、そうではありません。Cookieがよく使用される方法は悪です。Cookie自体は、ブラウザが閲覧中に追跡するHTTP認証情報と同様に、クライアント側の情報の一部です。また、このクライアント側の情報は、HTTP認証情報と同様に、リクエストごとにサーバーに送信されます。概念的には、唯一の違いは、このクライアント側の状態の内容は、サーバーがその応答の一部として決定できることです。
以下のルールのみを使用して、セッションをRESTfulリソースにします。
HTTP認証との唯一の違いは、認証キーがサーバーによって生成され、クライアントに送信されることです。クライアントは、入力された資格情報からそれを計算するのではなく、それを送り返します。
converter42は、httpsを使用する場合(必要です)、認証情報が非セキュア接続を介して送信されないように、Cookieにセキュアフラグを設定することが重要であることを追加しています。素晴らしい点、私自身はそれを見ていない。
これは十分に機能する十分なソリューションだと思いますが、私はこのスキームの潜在的な穴を特定するのに十分なセキュリティの専門家ではないことを認めなければなりません。ログインプロトコル(PHPでは$ _SESSION、Java EEではHttpSessionなど)。cookieヘッダーのコンテンツは、accept-languageを使用して翻訳リソースなどにアクセスするのと同じように、サーバー側のリソースをアドレス指定するために使用されます。同じだと思いますが、他の人は違うのでは?皆さんどう思いますか?
このトピックに関しては、すでに十分な知識がここにいる人々によって十分に述べられています。しかし、これは私の2セントです。
相互作用には2つのモードがあります。
マシンは一般的な分母であり、REST APIとして表現され、アクター/クライアントは人間またはマシンのいずれかです。
さて、真にRESTfulなアーキテクチャでは、ステートレスの概念は、関連するすべてのアプリケーション状態(クライアント側の状態を意味する)がすべてのリクエストで提供される必要があることを意味します。関連するとは、REST APIが要求を処理し、適切な応答を提供するために必要なものを意味します。
Human-to-Machineアプリケーションのコンテキストでこれを考慮すると、Skrebbelが上記で指摘したように「ブラウザーベース」です。これは、ブラウザーで実行されている(Web)アプリケーションが、各リクエストでその状態と関連情報を送信する必要があることを意味しますバックエンドのREST APIになります。
これを検討してください。RESTAPIのデータ/情報プラットフォーム公開アセットがあります。おそらく、すべてのデータキューブを処理するセルフサービスのBIプラットフォームがあるでしょう。しかし、(人間の)顧客が(1)Webアプリ、(2)モバイルアプリ、(3)いくつかのサードパーティアプリケーションを介してこれにアクセスすることを望みます。結局、MTMのチェーンでさえHTMにつながります-そうです。したがって、人間のユーザーは情報チェーンの頂点にとどまっています。
最初の2つのケースでは、人間と機械の相互作用のケースがあり、情報は実際に人間のユーザーによって消費されます。最後のケースでは、REST APIを使用するマシンプログラムがあります。
認証の概念は全面的に適用されます。REST APIが統一された安全な方法でアクセスされるように、これをどのように設計しますか?これを見る方法には、2つの方法があります。
方法1:
方法-2:
明らかに、Way-2では、REST APIがトークンを有効であると認識して信頼する方法が必要になります。ログインAPIが認証検証を実行したため、その「バレットキー」はカタログ内の他のREST APIによって信頼される必要があります。
もちろん、これは認証キー/トークンを保存してREST API間で共有する必要があることを意味します。この共有の信頼できるトークンリポジトリは、ローカルまたはフェデレーションにすることができ、他の組織のREST APIが相互に信頼できるようにします。
しかし、私は余談です。
重要なのは、すべてのREST APIが信頼の輪を作成できるように、「状態」(クライアントの認証済みステータスについて)を維持および共有する必要があるということです。これを行わない場合、つまりWay-1は、入ってくるすべての要求に対して認証動作を実行する必要があることを受け入れる必要があります。
認証の実行は、リソースを大量に消費するプロセスです。すべての受信リクエストに対して、ユーザーストアに対してSQLクエリを実行して、uid / pwdの一致を確認するとします。または、ハッシュ照合を暗号化して実行する(AWSスタイル)。そして、アーキテクチャ上、すべてのREST APIは、共通のバックエンドログインサービスを使用してこれを実行する必要があると思います。なぜなら、そうしないと、認証コードがどこにでも散らかされるからです。大きな混乱。
より多くの層、より多くの待ち時間。
次に、Way-1を使用してHTMに適用します。すべてのリクエストでuid / pwd / hashなどを送信する必要があるかどうか、(人間の)ユーザーは本当に気にしていますか?いいえ、毎秒auth / loginページをスローすることによって彼女を気にしない限り。あなたがそうするならば、顧客を持っている幸運。したがって、あなたがすることは、ログイン情報をクライアント側のどこかに、ブラウザの最初に保存し、すべてのリクエストに対して送信することです。(人間の)ユーザーの場合、彼女はすでにログインしており、「セッション」を利用できます。しかし、実際には、彼女はすべてのリクエストで認証されます。
Way-2と同じです。あなたの(人間の)ユーザーは気付かないでしょう。したがって、害はありませんでした。
Way-1をMTMに適用するとどうなりますか?この場合、マシンなので、すべてのリクエストで認証情報を送信するように要求することで、この人にひどい思いをさせることができます。誰も気にしない!MTMでWay-2を実行しても、特別な反応はありません。そのいまいましいマシン。気になりませんでした!
だから本当に、問題はあなたのニーズに何が合っているかです。無国籍には代償があります。代金を支払い、次に進みます。あなたが純粋主義者になりたいのなら、それもその代価を払って先に進んでください。
結局、哲学は重要ではありません。本当に重要なのは、情報の発見、提示、消費体験です。人々があなたのAPIを愛しているなら、あなたはあなたの仕事をしました。
Way-3
ハイブリッドアプローチが欠けています。クライアントはと同様にログインしますWay-2
が、と同様にWay-1
、資格情報はサーバー側の状態に対してチェックされません。いずれにしても、のように認証トークンが作成され、クライアントに送り返されますWay-2
。このトークンは、クライアント固有の状態を調べることなく、非対称暗号を使用して信頼性が後でチェックされます。
これが、真に完全にRESTfulな認証ソリューションです。
クライアントが認証するとき:
3.1。以下を含むトークンを発行します。
3.2。秘密鍵でトークンを暗号化します。
3.3。暗号化されたトークンをユーザーに送り返します。
ユーザーがAPIにアクセスするときは、認証トークンも渡す必要があります。
これは、ステートレス/ RESTful認証です。
パスワードハッシュが含まれている場合、ユーザーは認証トークンとともに暗号化されていないパスワードも送信することに注意してください。サーバーは、ハッシュを比較することにより、パスワードが認証トークンの作成に使用されたパスワードと一致したことを確認できます。HTTPSなどを使用した安全な接続が必要になります。クライアント側のJavascriptは、ユーザーのパスワードを取得し、それをクライアント側にメモリまたはCookieに格納し、サーバーの公開鍵で暗号化することもできます。
正直なところ、私はここで素晴らしい答えを見てきましたが、少し気になるのは、誰かがステートレスの概念全体を極端にして、それが独断的になるときです。それは、純粋なOOだけを採用したいと思っていた古いSmalltalkファンを思い出させます。何かがオブジェクトでない場合、それは間違っています。休憩してください。
RESTfulなアプローチは、あなたの人生をより簡単にし、オーバーヘッドとセッションのコストを削減することになっています、それは賢明なことなので、それに従ってください、しかしあなたがその分野(極端な分野/ガイドライン)を極限までフォローすることそれが意図されていた利点をもはや提供しない場合、あなたはそれを間違っています。今日の最高の言語のいくつかは、関数型プログラミングとオブジェクト指向の両方を備えています。
問題を解決する最も簡単な方法が、認証キーをCookieに保存してHTTPヘッダーで送信することである場合は、それを実行してください。悪用しないでください。セッションが重くて大きくなるとセッションが悪くなることに注意してください。すべてのセッションがキーを含む短い文字列で構成されている場合、何が問題なのでしょうか。
私はコメントの修正を受け入れる用意がありますが、サーバーにハッシュの大きな辞書を保持することを単に回避するために私たちの生活を悲惨なものにすることのポイント(今のところ)がわかりません。
何よりもまず、RESTful WebサービスはSTATELESS(つまり、SESSIONLESS)です。)。したがって、RESTfulサービスには、セッションまたはCookieの概念が含まれていないはずです。RESTfulサービスで認証または許可を行う方法は、RFC 2616 HTTP仕様で定義されているHTTP Authorizationヘッダーを使用することです。すべてのリクエストにはHTTP Authorizationヘッダーが含まれている必要があり、リクエストはHTTP(SSL)接続を介して送信される必要があります。これは、HTTP RESTful Webサービスで認証を行い、リクエストの承認を確認する正しい方法です。Cisco Systemsで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を使用する必要があります(つまり、セキュリティの問題を別のレイヤーに任せます)。
RESTful認証には、リクエストのパラメーターとして認証トークンを渡すことが含まれると思います。例としては、apiによるapikeysの使用があります。私はcookieやhttp authの使用が適切であるとは思いません。
以下で前述したアプローチは、本質的にOAuth2.0の「リソース所有者パスワード資格情報」付与タイプです。これは、起動して実行する簡単な方法です。ただし、このアプローチでは、組織内のすべてのアプリケーションが独自の認証および承認メカニズムを使用することになります。推奨されるアプローチは、「承認コード」付与タイプです。さらに、以下の私の以前の回答では、認証トークンを格納するためにブラウザーのlocalStorageを推奨しました。しかし、私はcookieがこの目的のための正しいオプションであると信じるようになりました。このStackOverflowの回答には、私の理由、認証コード付与タイプの実装方法、セキュリティに関する考慮事項などが詳しく記載されています。
RESTサービスの認証には次のアプローチを使用できると思います。
このアプローチでは、30分ごとにユーザー固有のアクセス権の詳細をキャッシュにロードするというコストのかかる操作を行っています。したがって、アクセスが取り消されるか、新しいアクセスが許可された場合、反映されるまでに30分かかるか、ログアウトしてからログインする必要があります。
それがその方法です:ログインにOAuth 2.0を使用するます。
OAuthをサポートしている限り、Google以外の認証方法を使用できます。
鍵の登録に適切なバインディングが含まれる公開鍵インフラストラクチャを使用すると、公開鍵が、否認防止を保証する方法で割り当てられた個人に確実にバインドされます。
http://en.wikipedia.org/wiki/Public_key_infrastructureを参照してください。適切なPKI標準に従うと、盗まれたキーを不正に使用した人物またはエージェントを特定してロックアウトできます。エージェントが証明書を使用する必要がある場合、バインディングはかなり厳しくなります。巧妙で動きの速い泥棒は逃げることができますが、より多くのパンくずを残します。
私の理解からこの質問に答えるために...
システム内のユーザーを実際に追跡または管理する必要がないように、RESTを使用する認証システム。これは、HTTPメソッドPOST、GET、PUT、DELETEを使用して行われます。これらの4つの方法を採用し、データベースの相互作用の観点からCREATE、READ、UPDATE、DELETEと見なします(ただし、Webではアンカータグが現在サポートしているため、POSTとGETを使用します)。したがって、POSTとGETを作成/読み取り/更新/削除(CRUD)として扱うと、達成しているCRUDのアクションを推測できるように、Webアプリケーションでルートを設計できます。
たとえば、Ruby on Railsアプリケーションでは、ログインしているユーザーがhttp://store.com/account/logoutにアクセスした場合にWebアプリケーションを構築できます。アクセスすると、そのページのGETがログアウトしようとしているユーザーとして表示されるできます。 。Railsコントローラーで、ユーザーをログアウトさせてホームページに送り返すアクションを作成します。
ログインページでGETを実行すると、フォームが生成されます。ログインページのPOSTはログイン試行として表示され、POSTデータを取得してログインに使用します。
私にとっては、データベースの意味にマップされたHTTPメソッドを使用し、セッションIDを渡したりセッションを追跡したりする必要がないことを念頭に置いて認証システムを構築する習慣です。
私はまだ学習中です-私が間違っていると言った何かを見つけたら私を修正してください、そしてあなたがもっと学ぶならここに投稿してください。ありがとう。
Webアプリケーションを保護するために有効なヒント
アプリケーションを保護したい場合は、HTTPではなくHTTPSを使用することから始めてください。これにより、ユーザーとユーザーの間で送受信されるデータを盗聴することを防ぎ、データを保持するのに役立つ安全なチャネルが作成されます。機密情報を交換しました。
JWT(JSON Webトークン)を使用してRESTful APIを保護できます。これには、サーバー側のセッションと比較して多くの利点があります。主な利点は次のとおりです。
1- APIサーバーが各ユーザーのセッションを維持する必要がないため、よりスケーラブルです(多くのセッションがある場合、これは大きな負担になる可能性があります)。
2- JWTは自己完結型であり、たとえばユーザーロールを定義するクレームを持ちます&アクセスできるもの&日付と有効期限日に発行されます(それ以降はJWTは無効になります)
3- JWTを使用したリクエストが認証されたサーバーにヒットするたびに、セッションデータを共有したり、セッションを同じサーバーにルーティングするようにサーバーを構成したりする必要がないため、ロードバランサー全体での処理がより簡単になります。 &承認済み
4- DBへの負担が軽減され、リクエストごとにセッションIDとデータを常に保存および取得する必要がなくなります。
5- JWTに署名するために強力な鍵を使用する場合、JWTを改ざんできないため、ユーザーセッションを確認する必要なく、リクエストが送信されたJWTのクレームを信頼でき、承認されているかどうかを確認できます、JWTを確認するだけで、このユーザーが誰が何をできるかを知る準備が整います。
多くのライブラリは、ほとんどのプログラミング言語でJWTを簡単に作成および検証する方法を提供します。たとえば、node.jsで最も人気のあるものの 1つはjsonwebtokenです。
REST APIは通常、サーバーをステートレスに保つことを目的としているため、各リクエストは自己完結型の承認トークン(JWT)で送信されるため、JWTはその概念とより互換性がありますがユーザーセッションを追跡する必要がなく、で送信されるため、あります。サーバーはステートフルなので、ユーザーとその役割を記憶しますが、セッションも広く使用されており、必要に応じて検索できるプロがいます。
注意すべき重要な点の1つは、HTTPSを使用してJWTをクライアントに安全に配信し、安全な場所(ローカルストレージなど)に保存する必要があることです。
このリンクから JWTの詳細を学ぶことができます