web-dev-qa-db-ja.com

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

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

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

次のようになっていると仮定します。(QuickBloxと同じように)

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

私の懸念?

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

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

14
Alok Patel

私はREST APIを過去数年間設計しています。あなたはあまりにも心配しています。最近、このボードの別のユーザーが質問しました、彼は心配していました RIエンドポイントの保管彼のJavaScriptクライアント側コードで

JavaScript開発者に適用されるのと同じ規則が適用されます。外部からのAPIの統合を許可する場合、APIは通常のWebサイトと同じように表示されるため、同じように扱う必要があります。

元の答えからの引用:

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

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

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

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

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

APIを使用するアプリケーションの開発を直接管理しているのでない限り、アプリからAPIを直接同じ方法で悪用することを禁止するものは何もありません。

7
Andy

あなたの問題は、ビジネスの問題ほど技術的な問題ではありません。

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

それから、明らかに、私はあなたのサービスを100ポンドで購入して、それぞれ50ドルで10人に売ることができます。あなたはそれを望まない!したがって、裁定取引を開かずにAPIを販売できるようにする制限について考えてみてください。

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

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

あなたがする必要があるのは、顧客に各API呼び出しのコストを渡すことです。つまり、API呼び出しごとに課金するか、年間の呼び出しの割り当てを設定します。

これは、裁定取引という同じ問題を顧客に押し付けます。これにより、ユーザーがキーを盗むのを防ぐための対策を講じる必要があります。この場合、独自のユーザー認証済みAPIの背後にAPIを隠します。

5
Ewan

他のすべての回答は、コンシューマデバイスのアプリにシークレットを保存する問題は解決できないことを示唆しているようです。

もちろんそうだ。

2つの原則(実装の詳細は次のとおりです):

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

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

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

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

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

2
Brandon

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

また、キーをクライアントにバインドすることを検討する必要があります。したがって、誰かが模倣した場合、セキュリティレイヤーを使用してクライアント、キー、およびユーザーエージェントをチェックし、リクエストをすぐにブロックする必要があります。キーが模倣されていないことを再発行または再確認するための使用例を用意してください。

0
Arun

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

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

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

クライアントとのやり取りが同期しない場合(何らかのプロトコルエラー)、サーバーは再認証を要求します(次のクライアント要求へのエラー応答を通じて、またはクライアント要求への有効な応答に便乗します)。例)。

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

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

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

0
Dan Cornilescu

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

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

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

これはあなたの質問の範囲から少し逸脱するかもしれませんが、それはあなたのトークンのセキュリティに関連しているので、それについて言及します。トークンがネットワーク上で簡単に盗まれるのを防ぐために、トークンを直接送信するのではなく、HMAC関数を使用してトラフィックに署名することをお勧めします。サーバーでメッセージのHMACを計算し、クライアントから送信されたHMACと比較することで、メッセージの有効性を確認できます。トークンをHMAC関数のキーとして使用すると、トークンを知っている人だけがトラフィックに署名できます。トークンをサーバーに直接送信することはないため、傍受して直接盗むことはできないため、これはトークンのセキュリティに優れています。 HMACSの詳細については、次の質問を参照してください。 https://security.stackexchange.com/questions/20129/how-and-when-do-i-use-hmac/20301

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

0
ThePragmatist

自分を引用:

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

今では少し矛盾していますね;)

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

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

  • iPのホワイトリスト/ブラックリスト
  • throttling
  • 「異常な活動」の検出とその原因
  • 簡単な鍵更新
0
dagnelies