分散システムの認証オプション


9

私は、互いにシンフォニーで機能する3つのコンポーネントを設計しているところです。

  • BasicAuthすべての呼び出しでHTTPS を必要とするRESTful Webサービスであり、これが実際に私のシステムのすべての重労働を実行します(作業を行います)
  • エンドユーザーのアクションを上記のWebサービスへのAPI呼び出しに変換するWeb UI。したがって、UIはWSによって「サポートされます」
  • 開発者がローカルでインストールして実行できるコマンドラインインターフェイス(CLI)ツール。コマンドをWSへのAPI呼び出しに変換します(したがって、これもWSによって「サポートされています」)。

私が乗り越えようとしている最初のハードルの1つは、認証と承認に関するものです。

WSがLDAP /ディレクトリサービス(ADまたはおそらくApache DSなど)を認証レルムとして使用しているとしましょう。つまり、API呼び出しがネットワーク経由で(たとえば、あるHTTPS GETリソースの)BasicAuth受信されると、資格情報が要求から抽出され、LDAPサービスに転送されて、これが有効なユーザーであるかどうかが判断されます。認証されている場合、特定のユーザー HTTPSリクエストで試行していることを実行できるかどうかを判断するために、別の認証レルム(おそらくデータベース)が使用されているとしましょう。ここまでは順調ですね。

CLIツールの場合、ユーザーはコマンドを実行する前に認証を受ける必要があります。したがって、単一のユーザーは常に同じCLIインスタンスを操作するだけなので、このモデルは問題なく機能します。

Webアプリケーション(UI)をWSと統合しようとすると、問題が発生します。なぜなら、多くの人が同時にアプリにログオンする可能性があり、すべて異なるアクセス許可で、許可されている基本的なAPI呼び出しを指示するためです。

私の知る限り、それを見て、それが見えます私はここが、4つのオプションを持っているように:

  • キャッシュされた資格情報:アプリにログインした後、資格情報が何らかの形であり、どこかで(アプリはそれらへのアクセスを持っているように)キャッシュされた、とアプリが認可ポリシー自体の任意の種類を強制しません。ユーザーが内部でAPI呼び出しを生成することをしようとすると、資格情報がキャッシュから検索され、API呼び出しで転送されます。WSが承認されていないと判断した場合、WSはエラーを返します。
  • サービスレベルアカウント:アプリとWSはどちらも同じ認証/承認レルムを使用しますが、Web UIは、ユーザーがアプリ内で実際に表示および実行できるものに承認を適用するようになりました。基盤となるAPI呼び出しを生成する何かを実行することが許可されている場合、アプリmyapp-admin-userはユーザーに代わって各API呼び出しでサービスアカウントの認証情報(など)を送信します。
  • OAuthv2:OAuthが何であるか、またはこのシナリオに適用できるかどうかはわかりませんが、どういうわけかここでの解決策になると思います。
  • トークンサーバー:サービスレベルのアカウントオプションと同様の方法で、CASやKerberos などのトークンサーバーを使用してユーザーを保証します。ここで、ユーザーがアプリに正常にログインすると、トークンサーバーはアプリにセッションUUIDを送り返し、そのUUIDをWSに登録します。アプリがAPI呼び出しを生成するたびに、UUIDをリクエストに付加し、それがWS側で検証されます。

Cached Credentials」オプションは、セキュリティ分野で優れていて健全なすべてのものの逸脱のように感じられます。資格情報をどこにでもキャッシュするのは間違っていると感じるだけです。

Token Server」オプションは、SSOタイプのセットアップでは有効のようですが、この特定のケースで有効でないため、私に不便に感じられます。また、セッションUUIDの概念 BasicAuth / HTTPSを同時に使用する良い方法はないと思います。

したがって、これは私が何も知らないOAuthv2と、残りの唯一のオプションとして「サービスレベルアカウント(SLA)*」を残します。SLAオプションは問題ないようですが、次のようないくつかの欠点があります。

  • サービスアカウントには、基本的にWSに対する「神の特権」が必要です。つまり、ユーザーがボタンをクリックしたり、UIで何かを実行したりできるとアプリが判断すると、UIで使用されているサービスアカウントによる無条件のAPI呼び出しに変換されます。これは気分が悪いですよね?
  • 2つの権限セット(アプリの各ユーザーに設定された権限セット、次にアプリがWSに対して使用するサービスアカウントに設定された権限セット)を維持すると、権限が互いに同期しなくなる可能性があります何とかして

だから私は本当にここには良い選択肢がないようです。確かに私はこれに遭遇する最初の開発者になることはできませんが、Googleの神々に尋ねることはここではあまり助けになりませんでした。何か案は?

回答:


6

Web APIサービスを保護するために基本認証方式を使用しない理由はたくさんあります。

このサービスを使用するには、クライアントはパスワードを平文でどこかに保持して、各リクエストと共に送信する必要があります。

パスワードの検証は非常に遅くなければならず(ブルートフォース攻撃に対抗するため)、サービスのスケーラビリティを妨げます。一方、セキュリティトークンの検証は迅速に行えます(デジタル署名の検証)。

OAuth2は、ユースケースごとにソリューションを提供します。Webアプリケーションはコードgrantを使用できます。これにより、APIとの通信に使用できるアクセストークンが付与されます。

Webアプリケーションは、ユーザーのブラウザーを認証サーバーにリダイレクトします。ユーザーに資格情報(またはスマートカード、または2要素の認証コード)を要求し、クライアント(Webアプリケーション)が認証サーバーからアクセストークンを取得するために使用できるコードをブラウザーに返します。

アプリケーションは、現在のトークンの有効期限が切れた場合に新しいアクセストークンを取得できる更新トークンも取得します。

CLIアプリケーションは、リソース所有者の資格情報付与を使用できます。ユーザーに資格情報の入力を求め、認証サーバーに送信して、アクセスと更新トークンを取得します。CLIアプリケーションがトークンを取得したら、ユーザーのパスワードをメモリに破棄できます。

両方のクライアント(Webアプリとコマンドラインクライアント)は、事前に承認サーバーに登録する必要があります。

承認サーバーは、実際の認証を行うためにLDAP /ディレクトリサービス(IDプロバイダーまたはIdP)と通信する可能性があります。

Web APIサービスは、着信JWTトークンを検証し、ユーザーが許可されていること(承認)を確立するだけで済みます。

中間者攻撃の被害者であり、アクセストークンを紛失した場合、攻撃者が使用できる時間(トークンの有効期間)は限られています。パスワードは通常、より長い間有効です。更新トークンは、紛失した場合に無効にすることができます。


確かな入力ありがとう@ user18044(+1)。Webサービスの他のHTTPクライアントはどうですか?これはRESTfulなWebサービスなので、誰でもこのクライアントを構築できます。これらは各リクエストを認証するためにどのOAuthv2オプションを使用しますか?Webアプリ(コード付与)と同じですか?再度、感謝します!
smeeb 2015

また、@ user18044は、OAuthv2が認証ではなく承認のみを処理することを確認できますか?もしそうなら、どのようにして各(成功した)認証済みリクエストをクライアントが利用できるロール/パーミッションのセットにマッピングできますか?
smeeb 2015

1
これらのクライアントを信頼する方法に応じて、クライアントの認証は異なります。たとえば、独自のAPIのモバイルアプリケーションを構築する場合、リソース所有者の資格情報付与を使用できます。ただし、モバイルクライアントがサードパーティ(アプリストアの一部のアプリ)によって作成されている場合は、暗黙的な付与を使用します。
MvdD 2015

1
@smeeb OAuthは、クライアントが実行できることを示すスコープを定義します。定義済みのスコープは多数ありますが、独自に定義できます(たとえば、特定のAPIを呼び出すために(tools.ietf.org/html/rfc6749#section-3.3を参照)
MvdD

1
大丈夫、大歓迎です。スコープは、実際には、サードパーティがAPIで実行できることを決定するメカニズムです。たとえば、銀行サイトの口座残高のみを読み取ることができる金融アプリケーション。ただし、JWTトークンにはユーザーの名前とオプションでロールさえ含まれているため、ユーザーまたはロールのユーザーが実行できることをデータベースで検索できます。それが私の会社のやり方でもあります。
MvdD 2015

2

私は今ややや類似したシステムに取り組んでいます。まだ実験中なので、この作業を行う「正しい」方法を知っていると言ったら嘘をつくでしょう。セットアップは、その欠点も関わらず OAuth2にかなり影響を受けています。そのいくつかについては後で説明します。

免責事項:私は貿易のセキュリティ担当者ではありません私が作成したものは、Googleの助けを借りて、できる限り多くの例を使用して作成しました。

クライアントアプリケーションをサポートするWeb APIを構築する方法を最初に調査したとき、APIをできるだけステートレスにしてみようと思いました。私の一部はHTTP基本認証に到達し、すべてのリクエストでユーザーを認証するように誘惑されましたが、2つの問題が浮上し、その解決策は実行不可能に思われました。

  1. 資格情報を検証するためのルックアップは、少なくとも各リクエストでのデータベース呼び出しを伴うため、時間を浪費することは重要です。
  2. システムはマルチテナントシステムです。ユーザーがどのテナントに属していたかを特定するには、3番目のパラメーターが必要であり、HTTP基本認証ではサポートされていません(1)

認証に伴う複雑さから、トークンシステムを選択しました。ユーザーは、エンドポイントに認証要求を行い、識別トークンを発行してから、サーバーがそれを使用して要求を検証し、それをリンクできる場所に保存します。必要なユーザーデータ。それは完全にステートレスではなく、私はJSON Webトークンを別のアプローチとして見てきましたが、トークンの検索は非常に高速に行うことができます。(2)

その後、クライアントは、サーバーがトークンを受け入れなくなるまで、そのトークンを使い続けます。次に、クライアントはサーバーで再認証を試み、将来の要求を認証するための新しいトークンを取得します。これは、キャッシュされた資格情報戦略としてあなたの投稿が参照するものであり、アプリケーションへのアクセスをより詳細に制御できるため、この方法を選択しました。クライアントが自身の認証情報を保持することを信頼でき、安全な接続(そのためHTTPSのみのアクセスを強制する)を介してのみ接続している場合、UXの観点から見ても、それは必ずしも適切な方法ではありません。Webサービスの場合、実際にはブラウザーのローカルストレージのトークンを保持します。これは一時的な識別であり、ユーザーの実際のユーザー名とパスワードの組み合わせではないため、これを「

トークンは、Authorizationヘッダーの一部として、またはカスタムHTTPヘッダーが利用できないクライアントのGETパラメーターとして、Web APIに送信されます。これにより、CLIやWebアプリをサポートする必要がある場合と同様に、さまざまな潜在的なクライアントアプリケーションからAPIにアクセスする方法が大幅に柔軟になります。無記名トークンはかなり一般的なものです、完全に完璧というわけではありません。ただし、アプリケーションのセキュリティに関する懸念は、これを改善するために追加の時間を費やすほど重要ではありません。

トークンが検証されると、認証が始まります。必要となる内容はさまざまですが、アプリケーションのその時点ではユーザーのIDがわかっているため、何らかの承認サービスにそのユーザーのIDとチェックするオブジェクト/アクションを与えるだけで済みます。

少なくとも、この種の戦略を使用したい場合は、OAuthとOAuth2を実装するように設計された多くのライブラリがあります。あなたが私たちに似ていて、いくつかの非常に限定的な要件がない限り、信頼できるサードパーティのセキュリティライブラリを使用することを強くお勧めします。現在の認証システムに代わるサードパーティの代替手段を探し続けていますが、想像もできないほどの穴やエッジケースがたくさんあることがわかっています。


脚注

  1. クライアントごとに異なるエントリポイントを使用するなど、システムが異なる方法で構築されている場合、これは必要ありません。または、私は巧妙にして、ユーザー名の前にテナントIDを付けることも検討しました
  2. 改善のための長期的なターゲットとしてI / Oルックアップを行う必要がなく、純粋に計算的にトークン文字列を検証しやすくする方法についていくつかのアイデアがありました。少なくともトークンにはバージョンバイトが含まれているため、デコードプロセスが変更された場合に、ラインのアップグレードが可能になります。
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.