web-dev-qa-db-ja.com

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

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

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

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

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

CLIツールの場合、ユーザーはコマンドを実行する前に認証を行う必要があるため、このモデルは正常に機能します。1人のユーザーが常に同じCLIインスタンスを操作するだけだからです。

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

私が見る限り、それはlooksのようですが、ここには4つのオプションがあります。

  • キャッシュされた資格情報:アプリにログインした後、資格情報は何らかの形でsomewhereキャッシュされます(アプリがそれらにアクセスできるようになります) )、アプリはいかなる種類の承認ポリシーも適用しません。ユーザーが内部でAPI呼び出しを生成することを試みると、ユーザーの資格情報がキャッシュから検索され、API呼び出しで転送されます。 WSが承認されていないと判断すると、エラーを返します。
  • サービスレベルのアカウント:アプリとWSはどちらも同じ認証/承認レルムを使用しますが、ユーザーが実際に表示できるものにWeb UIが承認を適用するようになりましたアプリ内で行います。基盤となるAPI呼び出しを生成することを許可されている場合、アプリはサービスアカウントの認証情報を送信します(例:myapp-admin-user)ユーザーの代わりに各API呼び出しを使用します。
  • OAuthv2:OAuthが何であるか、またはこのシナリオに該当するかどうかはわかりませんが、どういうわけかここでソリューション。
  • Token Servers[〜#〜] cas [〜#〜] またはKerberosなどのトークンサーバーを使用して保証するユーザーの場合は、サービスレベルアカウントオプションと同じように動作します。ここで、ユーザーがアプリに正常にログインすると、トークンサーバーはアプリにセッションUUIDを送り返し、そのUUIDをWSに登録します。アプリがAPI呼び出しを生成するたびに、リクエストにUUIDを付加し、それがWS側で検証されます。

"Cached Credentials"オプションはfeelsであり、セキュリティランドで良い健康的なすべての異常のようです。資格情報をどこにでもキャッシュするのは間違っていると感じるだけです。

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

したがって、これは私が何も知らないOAuthv2と、残りのオプションとして「Service-Level Account(SLA)*」のみを残します。 SLAオプションはOKのように見えますが、以下のいくつかの欠点があります:

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

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

9
smeeb

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

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

パスワードの検証は非常に遅く(ブルートフォース攻撃に対抗するため)、サービスのスケーラビリティを妨げる可能性があります。一方、セキュリティトークンの検証は迅速です(デジタル署名の検証)。

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

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

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

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

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

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

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

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

6
MvdD

私は現在、やや類似したシステムに取り組んでいます。私はまだ実験を続けているのでこの作業を行う「正しい」方法を知っていると言ったら嘘をついていますが、多分私が見つけた作業を手助けすると役立つかもしれません。設定はOAuth2 欠点にも関わらず にかなり影響を受けています。

免責事項:私は貿易のセキュリティ担当者ではありません、そして私が構築したもの私はGoogleの助けを借りて構築しました見つけることができた。

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

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

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

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

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

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

少なくとも、この種の戦略を使用したい場合は、OAuthとOAuth2を実装するように設計された多くのライブラリがあります。非常に限定的な要件信頼できるサードパーティのセキュリティライブラリを使用することを強くお勧めします。最初に試したときに正しく動作しない可能性が高いからです。現在の認証システムに代わるサードパーティの代替手段を探してみてください。これは穴だらけであり、想像もできないEdgeケースであることを知っているからです。


脚注

  1. クライアントごとに異なるエントリポイントを使用するなど、システムが異なる方法で構築されている場合、これは必要ありません。または、巧妙にして、ユーザー名の前にテナントIDを付けることも検討しました
  2. 長期的な改善の目標としてI/Oルックアップを実行する代わりに、トークン文字列を純粋に計算で簡単に検証する方法についていくつかのアイデアがありました。少なくとも、トークンにはバージョンバイトが含まれています。これにより、デコードプロセスが変更された場合に、ラインのアップグレードが可能になります。
2
moberemk