web-dev-qa-db-ja.com

REST WebアプリとモバイルアプリのAPI認証

Webアプリとモバイルアプリの両方で安全に使用できるRESTful APIの認証を実装する方法を決定するのに苦労しています。

まず、オプションとしてHTTPS経由のHTTP基本認証を調査することを考えました。ユーザー名とパスワードがOSキーチェーンに安全に保存され、リクエストがHTTPS経由であるため、送信中に傍受されないモバイルアプリではうまく機能します。また、完全にステートレスになるため、APIにとってもエレガントです。これに伴う問題は、Webアプリにあります。ユーザー名とパスワードを保存するためのこのようなキーチェーンにはアクセスできないため、CookieまたはlocalStorageを使用する必要がありますが、ユーザーの個人情報はすぐにアクセスできる場所に保存します。

さらに調査した結果、HMAC認証について多くの話を見つけました。このアプローチで見られる問題は、クライアントとサーバーのみが知っている共有秘密が必要だということです。ユーザー名/パスワードを取得し、Cookieに保存するためにシークレットを返すapi/loginエンドポイントがない限り、Webアプリで特定のユーザーにこのユーザーごとのシークレットを取得するにはどうすればよいですか?将来のリクエストで使用します。ただし、これはAPIに状態を導入しています。

別のスパナを作業に投入するには、APIを特定のアプリケーションに制限できるようにしたい(または、特定のアプリがAPIを使用するのをブロックできるようにしたい)。完全に公開されているWebアプリでこれがどのように可能になるかわかりません。

OAuthを実装したくありません。おそらく私のニーズには行き過ぎです。

HMACを完全に理解していないように思えるので、説明と、Webアプリとモバイルアプリで安全に実装する方法を歓迎します。

更新

最終的にはHTTP基本認証を使用することになりましたが、実際のユーザー名とパスワードをリクエストごとに提供する代わりに、エンドポイントが実装され、認証されたすべてのリクエストに提供されるアクセスキーのユーザー名とパスワードを交換しました。ブラウザにユーザー名とパスワードを保存する問題を解消しますが、マシンにアクセスして使用する場合は、もちろんトークンをフィッシングアウトできます。後知恵では、おそらくOAuthをさらに見ていたでしょうが、初心者にとってはかなり複雑です。

51
maknz

OAuth2を使用する必要があります。方法は次のとおりです。

1)モバイルアプリ

モバイルアプリは、自分が述べたとおりにクライアントの資格情報を保存します。次に、「リソース所有者パスワード資格情報付与」( http://tools.ietf.org/html/rfc6749#section-4. を参照)を使用してこれらの資格情報を送信します。次に、次のリクエストで使用できる(ベアラー)トークンを取得します。

2)Webサイト

Webサイトは「Authorization Code Grant」を使用しています( http://tools.ietf.org/html/rfc6749#section-4.1 を参照):

  1. Webサイトは、REST api。

  2. ユーザーはRESTサービスで認証します

  3. RESTサイトは、URLにアクセストークンを使用してユーザーをWebサイトにリダイレクトします。

  4. WebサイトはRESTサイトを呼び出し、アクセストークンを認証トークンにスワップします。

ここでは、WebサイトがRESTサービス(エンドユーザーに代わって))にアクセスするために認証トークンを使用します。通常は、HTTP認証ヘッダーに「ベアラー」トークンとしてトークンを含めます。

ロケット科学ではありませんが、完全に理解するには時間がかかります。

3)特定のアプリケーションのAPIアクセスを制限する

OAuth2では、各クライアントにクライアントIDとクライアントシークレットが発行されます(ここで、「クライアント」はモバイルアプリまたはWebサイトです)。クライアントは、認証時にこれらの資格情報を送信する必要があります。 RESTサービスはこれを使用して呼び出しクライアントを検証できます

24
Jørn Wildt

APIへのユーザー認証の問題に対処する1つの方法は、ユーザーがログインするときにAPIから認証トークンを要求することです。このトークンは、その後の要求に使用できます。あなたはすでにこのアプローチに触れました-それはかなり健全です。

特定のWebアプリの制限に関して。各Webアプリに各リクエストで自身を識別させ、この認証をAPI実装内で実行させる必要があります。かなり簡単です。

2
Dave

クライアント資格情報を公開する必要なく、非常に簡単かつ安全に自分のAPIでこれを解決しました。

また、問題を2つの部分に分けました。 API認証-これは、認識されたエンティティ(Webサイトまたはネイティブアプリ)からの有効な要求です。 APIの許可は、この特定のエンドポイントとHTTP動詞の使用を許可されたエンティティです。

許可は、アクセス制御リストと、必要に応じてAPIコード、構成、およびデータベース内でセットアップされるユーザーのアクセス許可と設定を使用して、APIにコーディングされます。 APIの単純なifステートメントは、承認をテストし、適切な応答(承認されていないか、API呼び出しの処理結果)を返すことができます。

認証とは、通話が本物かどうかを確認することです。これを行うには、自己署名証明書をクライアントに発行します。 APIの呼び出しは、必要に応じてサーバーから行われます。通常は、最初のページを生成するとき(または独自のアプリログインチェックを実行するとき)に行われます。この呼び出しでは、以前に提供した証明書を使用します。私の側で証明書が有効であれば、ナンスと期間限定で生成されたAPIキーを返すことができます。このキーは、他のAPIエンドポイントへの以降のすべての呼び出し、たとえばベアラーヘッダーで使用され、HTMLフォームフィールドまたはjavascript変数またはアプリ内の変数に非常にオープンに格納できます。

Nonceはリプレイ攻撃を防ぎ、誰かが望むならAPIキーを盗むことができます-有効期限が切れた後、または次の呼び出しを行う前にnonceが変更された場合、それらは使用を続けることができません。

各APIレスポンスには次のナンスが含まれます。ナンスが一致しない場合、認証エラーが返されます。実際、ノンスが一致しないため、APIキーも削除します。これにより、正規のAPIユーザーは証明書を使用して再認証を強制されます。

エンドユーザーがこれらの証明書を安全に保ち、最初の認証呼び出しを行うために使用するメソッドを公開しない限り(再生可能なajaxリクエストにするなど)、APIはナイスで安全です。

2
PCaligari