web-dev-qa-db-ja.com

JWTを使用してAsp.net Web APIに認証を実装する

私はJWTについて読んでいます。

しかし、私が読んだことから、それは認証メカニズムではなく、認証メカニズムの重要なコンポーネントのようなものです。

現在、動作するソリューションを実装していますが、JWTを試して、その動作を確認するだけでした。しかし、今私がしているのは、それをどのように利用すべきかということです。それの私の経験から、それは基本的にあなたにユニークな暗号化されたキーを与えるただの暗号化メカニズムです。このトークン内に情報を入れることもできます。

モバイルアプリケーションで使用されるASP.NET Web API 2で用語を実装したいと考えています。

ステップ1:

  1. app =>サーバー:ログイン(ユーザー、パスワード)
  2. サーバー=>アプリ:ログインOK、JWTが表示されます
  3. app => server:プロファイルを取得(リクエストでJWTを送信)サーバーはJWTを復号化し、リクエストのIDを決定します。

今、これはそれについての私の理解にすぎません。

JWTの理想は、すべてのリクエストで認証する必要がないことですか?サーバーが単にJWTを使用でき、DB内のユーザーpwとユーザーを検索する必要がなくなった後、ユーザーの資格情報を(最初のログインで)認証するだけです。

JWTを使用して、ユーザーを特定したいだけです。私はそれらを認証した後、それから認可します。私が知っているように、新しいMVCおよび認証と承認とは大きな混乱があります。

だから私の質問は何に帰着します。

JWTを使用して認証メカニズムを安全かつ効果的に実装するにはどうすればよいですか?私は、機能するように思われ、セキュリティへの影響についての考えを持っていない何かをせき立てたくありません。私の要件に合った安全なメカニズムを設計した可能性のあるソースが存在することを確信しています。

私の要件は次のとおりです。

  • セッションごとに一度だけユーザーの資格情報を確認する必要がありますか?パスワードを比較するために多くのリソースを使用するbcryptの使用のため。
  • リクエストからユーザーを識別できる必要があります。 (つまり、ユーザーIDで十分です)、できればDBにもアクセスせずに
  • 要求を処理するサーバー側のリソースに関して、可能な限り低いオーバーヘッドである必要があります。
  • 侵入者が以前のリクエストをデバイスにコピーしなければならなかった場合、実際のユーザーデータにアクセスすることはできません。 (明らかに)

ありがとう

56
Zapnologica

JWTの理解は良好です。しかし、ここにいくつかの修正といくつかの推奨事項があります。

認証と承認

  • JWTは認証とは関係ありません。 DBのヒットとパスワードのハッシュは、JWTの作成時に認証するときにのみ発生します。これはJWTに直交しており、好きな方法で行うことができます。個人的には Membership Reboot が好きです。これにはJWTの使用例もあります。
  • 理論的には、ユーザーに1年に1回パスワードを入力させ、JWTをその年全体で有効にすることができます。 JWTが任意の時点で盗まれると、ユーザーリソースが危険にさらされる可能性があります。

暗号化

  • トークンは暗号化できますが、暗号化する必要はありません。トークンを暗号化すると、システムの複雑さと、サーバーがJWTを読み取るために必要な計算量が増加します。これは、トークンが静止しているときに誰もトークンを読み取れないようにする必要がある場合に重要です。
  • トークンは、その完全性を確保するために、発行者によって常に暗号で署名されます。つまり、ユーザーまたは第三者が改ざんすることはできません。

請求

JWTには、必要な情報を含めることができます。ユーザーの名前、生年月日、電子メールなど。これは、クレームベースの承認で行います。次に、クレーム原則からのこれらのクレームを使用してJWTを作成するようにプロバイダーに指示します。次のコードは、Membership Rebootの例からのもので、これがどのように行われるかを示しています。

public override Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
{
    var svc = context.OwinContext.Environment.GetUserAccountService<UserAccount>();
    UserAccount user;
    if (svc.Authenticate("users", context.UserName, context.Password, out user))
    {
        var claims = user.GetAllClaims();

        var id = new System.Security.Claims.ClaimsIdentity(claims, "MembershipReboot");
        context.Validated(id);
    }

    return base.GrantResourceOwnerCredentials(context);
}

これにより、プロセッサを集中的に使用する認証サービスにアクセスすることなく、誰がリソースにアクセスしているかを正確に制御できます。

実装

トークンプロバイダーを実装する非常に簡単な方法は、WebAPIプロジェクトで MicrosoftのOAuth=承認サーバー を使用することです。 OAuth APIのサーバー。

また、Thinktectureの Identity Server を調べることもできます。これにより、ユーザーをより簡単に制御できます。たとえば、ユーザーが一度認証されると、IDサーバーで更新トークンを簡単に実装できます。その後、一定期間(1か月程度)、Identity Serverから短命のJWTを取得し続けることができます。更新トークンは取り消すことができますが、JWTは取り消せないため、優れています。このソリューションの欠点は、Identity Serviceをホストするために別のサーバーを1つまたは2つセットアップする必要があることです。

最後の点に対処するには、侵入者がリソースへのアクセスを取得するための最後のリクエストをコピーできないようにする必要があります最低限SSLを使用する必要がありますこれにより、転送中のトークンが保護されます。

非常に機密性の高いものを保護する場合は、トークンの有効期間を非常に短い時間に保つ必要があります。機密性の低いものを保護する場合は、寿命を長くすることができます。有効なトークンが長いほど、ユーザーのマシンが危険にさらされた場合に、攻撃者が認証済みユーザーになりすます時間が長くなります。

55
Thomas Sobieck

デフォルトのトークンではなく、署名されたJSON Webトークンを発行するようにOWIN承認サーバーを構成することに関する詳細なブログ記事を書きました。そのため、リソースサーバー(オーディエンス)は認証サーバーに登録でき、すべてのパーティ間でmachineKey値を統一する必要なく、トークン発行者パーティが発行したJWTトークンを使用できます。投稿を読むことができます Owinを使用したASP.NET Web API 2のJSON Web Token

23
Taiseer Joudeh