クライアントアプリケーションからユーザー認証を設計する方法は?


14

私は多くのユーザーをサポートするアプリケーションを開発しています。問題は、クライアント/ユーザーを認証する方法がわからないことです。

私はhttp://quickblox.com/のようなアプリを構築しています。そこでユーザーに資格情報を提供し、ユーザーはそれらを使用してユーザー名とパスワードを入れて認証を取得できないNアプリケーションを構築します。

それが次のようになると仮定しましょう。(QuickBloxと同じように)

1.ユーザーが私のWebサイトでアカウントを作成します。
2.ユーザーはN個のAPIキーを作成し、資格情報を秘密にすることができます。(複数のアプリの場合)
3.ユーザーは、アプリケーション(Android、iOS、Javascriptなど)でこれらの資格情報を使用して、REST APIと通信します。
(REST APIには読み取りおよび書き込みアクセスがあります。)

私の懸念?

ユーザーは自分が作成したアプリケーションに資格情報(APIキーと秘密キー)を入れます。誰かがこれらのキーを取得して、ユーザーをまねようとするとどうなりますか?(APKを逆コンパイルするか、JavaScriptコードを直接調べます。

どこか間違ってる?
この3つのレベルのユーザーメカニズムを設計するのは混乱しています。


あなたがやろうとしていることは不可能です。
user253751

同じことを行う多くのアプリケーションがあります。どのようにユーザーを認証するのかわかりません。
アロクパテル

クライアントアプリケーションまたはユーザーを認証しようとしていますか?多くのアプリがユーザーを認証します。それらはいずれも、クライアントアプリケーションを破壊不可能な方法で認証しません。
user253751

ええ、クライアントでは、ユーザーのみを認証したいということです。
アロクパテル

4
ああ、それでは、最も一般的な認証システムでは、ユーザーにユーザー名とパスワードを入力してもらい、それらをサーバーに安全に送信します。サーバーはそれらをチェックし、(安全に)セッショントークンを返します今後のすべてのリクエスト。
user253751

回答:


7

過去数年間、REST APIを設計しています。心配しすぎです。最近、このボードの別のユーザーが質問をしました。そこでは、JavaScriptクライアント側のコードにURIエンドポイントを保存することを心配していました

JavaScript開発者に適用されるルールと同じルールが適用されます。外部からのAPIの統合を許可する場合、APIは通常のWebサイトと同じ可視性を持ち、同じように扱う必要があります。

元の回答からの引用:

Webサイトを作成していて、ユーザーに何かをさせたくない場合、その機能を実装したり、特定のユーザーがそれを使用することを禁止したりしません。パブリックエンドポイントを持つREST APIでもほぼ同じであるため、パブリックWebサイトのように扱う必要があります。

REST APIは、別のユーザーからのデータへのアクセスなどの無効な操作を許可しないほど堅牢でなければなりません。

許可したい操作のみを許可するようにアプリケーションアクセストークンを設計する必要があります。次の2種類のアクセストークンを使用できます。

  • マスタートークン:アプリケーションの作成者が使用でき、APIからより多くの機能を提供できます。
  • アプリケーショントークン:実際にアプリケーション内に格納され、APIへのアクセスを制限し、ユーザーまたはアプリケーションプログラマーのデータを破損できない操作のみにアクセスするトークン。

しかし、誰かがソースコードを分解し、トークンをアプリケーションから取り出し、パブリックエンドポイントが何であるかを見つけ、Webサービスを悪用するのは何でしょうか?

APIを使用するアプリケーションの開発を直接管理している場合を除き、アプリから直接同じ方法でAPIを悪用する人を実際に禁止するものはありません。


これまでのところ良い説明ですが、質問があります。APIの1つが、ユーザーのすべての関連データ(A + B)を取得するためにビルドされているとしますユーザーはアプリでこのAPIを使用して、ユーザーのfiltered data(B)のみを取得します。今、それは可能ですか、または第三者のユーザー私のユーザーのすべてのデータ(A + B)を盗むのを防ぐ回避策があります。それは理にかなっていますか?
アロクパテル

@AlokPatelこの機能を実装しないようにする他の回避策はありません。その場合、誰かが自分のIDハッシュを他の誰かのように見せかけるリスクが常にあります。プログラムで問題を解決することはできません。すでに述べたように、機能を提供したくない場合は実装しないでください。アプリはおそらくアプリ内にログインハッシュを保存するため、アプリがデプロイされるとAPIキーも保存され、公開されなくなります。
アンディ

説明してくれてありがとう。それで、私がこれまでに得たのは、REST APIはWebサイトと同じくらいオープンな、私たちがデプロイするWebサイトと同じであるということです。ユーザーに何かをさせたくない場合は、REST APIに実装しません。だから私ができることは、クライアントライブラリ(Android、iOS、JS)用の個別のキーを持っていることです これがうまくいくことを願っています!
アロクパテル

この点について説明してもらえますか?あなたは直接あなたのAPIを消費するアプリケーションの開発を管理している場合を除き
Alokパテル

@AlokPatel私が言ったのは、あなたが誰かにAPIへのアクセスを与えることを心配しているということです。APIを使用するアプリケーションの開発を制御できない場合は、独自で同じことを行う可能性があります。
アンディ

5

あなたの問題は技術的な問題ではなく、ビジネス上の問題です。

APIがあり、年間100ポンドの定額料金で無制限のアクセスで顧客(アプリ開発者)に販売しているとします。

それで、明らかに、私はあなたのサービスを£100で購入し、それぞれ50ドルで10人に売ることができます。あなたはそれを望んでいません!そのため、アービトラージに開かれることなくAPIを販売できる制限について考えようとします。

  • アプリの数を制限するだけであれば、顧客は他のアプリからの接続を受け入れて渡す単一のアプリを作成できます。

  • 再びユーザーを制限すると、顧客はユーザーを自分の認証の背後に隠して、単一のユーザーのように見せることができます。

必要なのは、各API呼び出しのコストを顧客に渡すことです。つまり、API呼び出しごとに課金するか、年間呼び出しのクォータを設定します。

これは、裁定の同じ問題を顧客に押し付けます。ユーザーがキーを盗むのを防ぐための措置を強制します。この場合、独自のユーザー認証APIの背後にAPIを隠します。


API呼び出しの数に基づいてAPIの使用を制限することを既に計画しているので、ビジネス関連の問題は現時点では心配せず、キーが盗まれるのを心配するだけです。
アロクパテル

ビジネスの観点からは、問題は解決できません。残念ながら、プログラムで解決することもできません。
アンディ

1
ビジネス上の問題は、通話ごとに課金することで解決されます。キーが盗まれた場合、顧客は負けとなります。あなたではない。盗まれたキーをキャンセルする方法を顧客に提供し、不正使用を防ぐための中間APIを用意するように彼らに任せてください
ユアン

2

他の答えはすべて、消費者向けデバイスのアプリに秘密を保存する問題は解決できないことを示唆しているようです。

もちろんそうだ。

2つの原則(実装の詳細が続きます):

  1. 実際の認証エンドポイントは、匿名で公開する必要があります。
  2. サーバーは、何らかの方法でクライアントの認証とAPIキーの提供に関与する必要があります。

そのため、クライアントが資格情報を使用して認証エンドポイントに要求を行い、サーバーがそれを認証した場合、サーバーは動的一時トークン(一時的な意味は時間ベース)を生成できます。このトークンはクライアント内で記憶され、後続のリクエストとともに送信される必要があります。

トークンを定期的に「更新」する、つまり新しいトークンを取得するメカニズムが必要になります。既存のトークンから新しいトークンを生成できるRESTエンドポイントを作成するだけで、資格情報から再認証する必要がなくなります。

エンドユーザーが自分自身を再認証するのを避けようとしている場合、この認証は、インストール時のアプリでの最初の1回限りのセットアップになります。

このソリューションでは、アプリケーションバイナリ内に埋め込まれた静的トークンを保存する必要がなくなります。トークンは、認証の成功に応じてのみサーバーによってオンザフライで生成されます。悪意のあるユーザーがアプリケーションを検査して不正なAPIアクセスを取得しようとする場合、他のユーザーと同じように認証する必要があります。


興味深い解決策ですが、ほとんどの場合、OPのクライアントがアプリをコーディングする方法に依存します。つまり、提案されたアプローチでは、APIキーサーバー側を保存でき、その後、自分のユーザーの認証に成功すると、実際のアプリが使用する一時キーを転送できます。この方法では、アプリ自体には何も保存されません。
ニュートピア16

これはすべてのAPIに当てはまります。APIコンシューマーがそれを適切に消費しない場合、物事が機能しない可能性があります。これは、APIの文書化された部分でなければなりません。
ブランドン

ところで、OAuthのように、これを簡単にするための標準があります。
ブランドン

0

一意のアプリごとのキーがある場合は、クライアントによって開始された初期接続認証中にのみ使用できます。その後、ローリングアプリごとの一意の認証トークンに切り替えます。

サーバーは、各クライアントアプリのトークンを時々変更(ロール)します(たとえば、ランダムなファジー/ランダムな遅延を定期的にプラス/マイナスします)。ローリングトークンは、サーバーと認証済みクライアントの間でのみ認識されます。

新しいトークンは、通常の返信に便乗して返されます。返信に新しいトークンが含まれる場合は常に、受信側アプリは後続のリクエストでトークンを使用するように切り替える必要があります。

クライアントとの交換が同期しなくなると(何らかのプロトコルエラーが発生すると)、サーバーは再認証を要求します(次のクライアント要求へのエラー応答、またはクライアント要求への有効な応答に便乗します)。例)。

ローリングトークンがアクティブに使用されているときにクライアントによって開始された初期認証は、疑わしいと見なされる必要があります。これは非常によく似た試みです。交換が予想よりも長い時間アイドルになった場合にのみ許可します。これは、たとえば、ローリングトークンを持たない新しいインスタンスでのクライアントの停止/再起動が原因である可能性があります。

クライアント側でトークンを保持して、再起動されたクライアントがその前任者が残った場所から続行できるようにすることはさらに良いでしょう-模倣のための開口部を大幅に狭めます。

このようなスキームは、少なくとも非常に模倣を困難にします-承認されたクライアントが、所定のキーを使用して新しいクライアント認証を受け入れることができるとサーバーが判断するのに十分な長さでリクエストの送信を停止すると、模倣クライアントはウィンドウを正確に予測する必要があります。許可されたウィンドウ外のこのような要求は、模倣の試みの検出として使用でき、場合によっては何らかの対策(IPブラックリストなど)を開始できます。


0

私が知っていることから、あなたが言ったことはこれを行う唯一の方法です。キーを保存するアプリケーションは間違いなくリスクですが、それを回避するためのさまざまな方法があります。ハードコーディングよりも常にキーストアを使用してキーを保存できるため、1回限りのログインを強制できます。

また、キーをクライアントにバインドすることを検討する必要があります。したがって、誰かが模倣した場合、クライアント、キー、およびユーザーエージェントをチェックしてセキュリティで保護された要求をすぐにブロックする必要があります。鍵が模倣されていないことを再発行または再保証するユースケースを用意します。


JavaScriptの回避策は何ですか?そのための設計方法は?
アロクパテル

ハイブリッドアプリケーションの作成について話していると思います。その場合、間違いなくキーを保存するプラグインを作成できるはずです。あなたがアプリケーションをホストするために行くと、モバイルWebソリューションについて話している場合は、コンテナを使用して、ページのレンダリングを考えると、あなたはセッショントークンに依存することができます以前の提案
アルン

いいえ、そうではありません。私は3番目のトップAPIプロバイダーになり、ユーザーはアプリケーションでAPIサービスを使用します。Android、iOS、JavaScriptなどを使用できます。
Alok Patel

0

承認トークンを顧客に提供してアプリを投入することに依存している場合、誰かがアプリをリバースエンジニアリングして抽出することは、理論的には常に可能です。これを防ぐには、クライアントアプリ内でシークレットを必要としないメカニズムが必要です。それはトリッキーです。ただし、考えておくべきいくつかのオプションを提案できます。

資格情報を提供すると問題が発生し、資格情報の保存方法を制御できなくなります。また、ユーザーに資格情報の送信を要求する場合、誰かが接続をMITMし、アプリのリバースエンジニアリングを気にせずにトークンを直接盗むことができます。

認証トークンの抽出をより困難にする1つの方法は、トークンを難読化することです。これは単に水準を上げるだけですが、それを不可能にするわけではありません。そのためには、秘密の制御を保持する必要があります。秘密情報を含み、各顧客に固有のライブラリを実装できます。ライブラリを使用してサーバーと通信することもできますし、ユーザーに秘密情報を伝える必要さえないかもしれません。単にライブラリに埋め込むことができます。これは、誰かがライブラリをリバースエンジニアリングするという問題を解決するものではありませんが、難読化のレベルを制御できるようにします。欠点は、1人の人がライブラリの難読化を破ると、各ライブラリを大きく変えるコードを書かない限り、あなたのライブラリを攻撃できることです。それは独自の一連の問題をもたらします。

これはあなたの質問の範囲からわずかに外れているかもしれませんが、それはあなたのトークンのセキュリティに関連しているので、私はそれについて言及します。ワイヤーを介したトークンの些細な盗難を防ぐために、おそらくトークンを直接送信したくないので、代わりにHMAC関数を使用してトラフィックに署名することができます。サーバー上のメッセージのHMACを計算し、クライアントから送信されたHMACと比較することにより、メッセージの有効性を確認できます。トークンをHMAC機能のキーとして使用して、トークンを知っている人だけがトラフィックに署名できるようにします。これは、トークンをサーバーに直接送信することはないため、トークンを直接傍受したり盗まれたりすることはないため、トークンのセキュリティにとっては優れています。HMACSの詳細については、次の質問を参照してください。 https

難攻不落のセキュリティソリューションはありません。実装にかかる費用と、侵害される可能性とコストを決定する必要があります。


ライブラリを作成して秘密を入れることはできません。それらはユーザーごとに異なります。
アロクパテル

明確にするために、ユーザーごとにカスタムライブラリを作成し、ライブラリ内に個々の秘密を隠すことを提案しました。新しいユーザーごとに必要に応じてライブラリを自動的に生成するシステムを作成する必要があります。これは、やりたいことよりも手間がかかる場合があります。
ThePragmatist

0

自分を引用する:

クライアント/ユーザーを認証する方法を理解することはできません...そこでは、ユーザー名とパスワードを入れて認証を受けることができません。

さて、これは少し矛盾していますよね?;)

他の人が言ったように、できません。アプリがAPIキーを使用する場合、キーを取得して使用するためにあなたが言うようにそれを逆コンパイルできます。

追加の適切なユーザー認証を要求する以外に、損害を制限することしかできません。

  • IPのホワイトリスト/ブラックリスト
  • 絞る
  • 「異常なアクティビティ」の検出とその原因
  • 簡単なキー更新
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.