web-dev-qa-db-ja.com

JWT Bearer Authenticationのファイルからの.NET Core IssuerSigningKey

JWT Bearer Token認証用の署名キーの実装(または理解)に苦労しています。そして、誰かが私を助けてくれたり、私が誤解していることを説明してくれることを願っています。

ここ数週間、私は大量のチュートリアルをクロールし、トークンを発行するカスタムAuth-Controllerを実行し、ヘッダー内のトークンを検証するためにJWTベアラ認証をセットアップしました。

できます。

私の問題は、すべての例とチュートリアルがランダムまたはメモリ(発行者)署名キーを生成するか、ハードコードされた「パスワード」文字列を使用するか、構成ファイルから取得することです(コードサンプルで「パスワード」を探します)。

検証セットアップの意味(StartUp.cs内):


  //using hardcoded "password"
  SecurityKey key = new SymmetricSecurityKey(System.Text.Encoding.ASCII.GetBytes("password"));

  app.UseJwtBearerAuthentication(new JwtBearerOptions
  {
    AutomaticAuthenticate = true,
    AutomaticChallenge = true,
    TokenValidationParameters = new TokenValidationParameters
    {
      ValidateIssuer = true,
      ValidIssuer = "MyIssuer",
      ValidateAudience = true,
      ValidAudience = "MyAudience",
      ValidateLifetime = true,
      IssuerSigningKey = key
    }
  });

トークンを作成するAuthControllerで:


  //using hardcoded password
  var signingKey = new SymmetricSecurityKey(System.Text.Encoding.ASCII.GetBytes("password"));
  SigningCredentials credentials = new SigningCredentials(signingKey, SecurityAlgorithms.HmacSha256);

  var jwt = new JwtSecurityToken     // Create the JWT and write it to a string
  (
    issuer: _jwtTokenSettings.Issuer,
    audience: _jwtTokenSettings.Audience,
    claims: claims,
    notBefore: now,
    expires: now.AddSeconds(_jwtTokenSettings.LifetimeInSeconds),
    signingCredentials: credentials
  );

この質問 で使用したもの:

RSAParameters keyParams = RSAKeyUtils.GetRandomKey();

私の(現在の)前提は、実稼働環境では、トークン署名キーにハードコーディングされた文字列または構成ファイルの文字列を使用しないことです。しかし、代わりにいくつかの証明書ファイルを使用します???私が間違っている?

そこで、認証コントローラーで機能する証明書で文字列を置き換えようとしました:


  //using a certificate file
  X509Certificate2 cert = new X509Certificate2("MySelfSignedCertificate.pfx", "password");
  X509SecurityKey key = new X509SecurityKey(cert);
  SigningCredentials credentials = new SigningCredentials(key, "RS256");

  var jwt = new JwtSecurityToken      // Create the JWT and write it to a string
  (
     issuer: _jwtTokenSettings.Issuer,
     audience: _jwtTokenSettings.Audience,
     claims: claims,
     notBefore: now,
     expires: now.AddSeconds(_jwtTokenSettings.LifetimeInSeconds),
     signingCredentials: credentials
  );

しかし、証明書を使用して検証を取得する方法はないようです。


  X509Certificate2 cert = new X509Certificate2("MySelfSignedCertificate.pfx", "password");
  SecurityKey key == // ??? how to get the security key from file (not necessarily pfx)

  app.UseJwtBearerAuthentication(new JwtBearerOptions
  {
    AutomaticAuthenticate = true,
    AutomaticChallenge = true,
    TokenValidationParameters = new TokenValidationParameters
    {
      ValidateIssuer = true,
      ValidIssuer = "MyIssuer",
      ValidateAudience = true,
      ValidAudience = "MyAudience",
      ValidateLifetime = true,
      IssuerSigningKey = key
    }
  });

署名キーに証明書を使用する必要があるのは間違っていますか?認証コントローラが消費/セキュリティで保護されたWeb APIとは異なるサーバー上にあるときに、運用環境で署名キーを変更する方法は他にありますか(今ではなく、一度だけかもしれません)。

この質問 の答えを得るためのポイント(必要な手順)を見逃しているようです。


今、私はそれを実行しましたが、それがそのようでなければならない場合、私はまだポイントを逃していますか?


注目すべき:ファイルが見つかりません(サーバーへの展開後)

これを使用し、Visual Studioから起動したときに機能しますが、サーバー/ Azureへの展開後、「ファイルが見つかりません」と表示されます。

この質問を読んで、賛成票を投じてください: X509証明書がサーバーに秘密鍵ファイルをロードしていません


注目に値する2:実際にはトークンベースの認証には必要ない

公開鍵は、API側にある必要はありません。認証サーバーの検出エンドポイントを介して自動的に取得されます。

15
monty

親愛なる、あのシンプル:

SecurityKey key = new X509SecurityKey(cert);

または、上記の完全なサンプルとして:

X509Certificate2 cert = new X509Certificate2("MySelfSignedCertificate.pfx", "password");
SecurityKey key = new X509SecurityKey(cert); //well, seems to be that simple
app.UseJwtBearerAuthentication(new JwtBearerOptions
{
    AutomaticAuthenticate = true,
    AutomaticChallenge = true,
    TokenValidationParameters = new TokenValidationParameters
    {
        ValidateIssuer = true,
        ValidIssuer = "MyIssuer",
        ValidateAudience = true,
        ValidAudience = "MyAudience",
        ValidateLifetime = true,
        IssuerSigningKey = key
     }
});
11
monty

非常に重要な点は、証明書ファイルを使用している場合、サーバーは秘密鍵付きのファイルを必要としますが、クライアントは公開鍵のみを使用する必要があることです。

秘密鍵ファイルをだれにも与えたくありません。公開鍵のみが必要です。

// On client
var publicCert = new X509Certificate2("MySelfSignedCertificate.cer");
var publicKey = new X509SecurityKey(publicCert);
...
    IssuerSigningKey = publicKey

PFX(プライベート)をCER(パブリック)に変換する最も簡単な方法は、Windows証明書マネージャーにインポートし、パブリックキーのみでエクスポートすることです。

コマンドラインから、PowerShell 5を使用して作成することもできます(PowerShell 6にはまだありません)。

Get-PfxCertificate -FilePath MySelfSignedCertificate.pfx | Export-Certificate -FilePath MySelfSignedCertificate.cer

または、OpenSSLをインストールして使用し、コマンドラインから変換できます。

注1:見つけたように、機関を設定すると、自動検出はサーバーから公開鍵を見つけることができる場合があります。

注2:証明書をファイルに保存するのではなく、Windows証明書ストアに保存し、thumb印で参照することもできます(PFXファイルとCERファイルの両方をインポートできます)。

1
Sly Gryphon