Подтвердить что ты не робот

.NET Core ЭмитентSigningKey из файла для аутентификации на предъявителя JWT

Я борюсь с реализацией (или пониманием) подписи ключей для аутентификации маркера на предъявителя JWT. И я надеюсь, что кто-то может мне помочь или объяснить мне, что я недопонимаю.

В течение последних нескольких недель я просканировал множество обучающих программ и сумел запустить пользовательский 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();

Мои (текущие) предположения заключались в том, что в процессе производства вы не должны использовать жестко заданные строки или строки из файлов конфигурации для ключей подписи маркера. Но вместо этого используйте некоторые файлы сертификатов??? Я не прав?

Итак, я попытался заменить строки сертификатом, который работает в контроллере auth:


  //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
    }
  });

Я ошибаюсь, что должен использовать сертификаты для ключей подписи? Как еще я могу изменить ключи подписи в процессе производства, когда контроллер авторизации находится на другом сервере, чем потребительский/защищенный веб-api (может один раз, а не сейчас)?

Кажется, я тоже пропустил (необходимые шаги), чтобы получить ответ этого вопроса.


Теперь, когда я его запускал, я все еще не вижу смысла, если это так?


Примечательно: файл не найден (после развертывания на сервере)

Для всех тех, кто использует это, и он работает при запуске из Visual Studio, но после развертывания на сервере /azure он говорит "Файл не найден":

прочитайте и подтвердите этот вопрос: сертификат X509 не загружает файл закрытого ключа на сервер


Примечательно 2: на самом деле он не нужен для аутентификации на токенах

Открытый ключ не обязательно должен быть на стороне API. Он будет автоматически извлечен через конечную точку обнаружения сервера аутентификации.

4b9b3361

Ответ 1

О, дорогая, это просто:

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
     }
});

Ответ 2

Очень важный момент, если вы используете файлы сертификатов, то, что для сервера требуется файл с закрытым ключом, клиент должен использовать только открытый ключ.

Вы не хотите никому передавать свой файл закрытого ключа; им нужен только открытый ключ.

// 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 и ссылаться на него по отпечатку пальца (можно импортировать как файлы PFX, так и файлы CER).