ASP.NET Аутентификация Core 3 JWT

#c# #asp.net-core #jwt #openid-connect #jwt-auth

#c# #asp.net-ядро #jwt #OpenID-подключение #jwt-аутентификация

Вопрос:

В последнее время потратил несколько дней на то, чтобы узнать, как защитить ASP.NET Базовый веб-API / веб-приложение с аутентификацией JWT и / или OIDC.

Я до сих пор не смог найти надлежащую документацию для двух (?) Разных расширений промежуточного программного обеспечения ( .AddOpenIdConnect и .AddJwtBearer ). Из поиска в Google и экспериментов я пришел к предположению, что первый поддерживает полный цикл OIDC (проверка, перенаправление в authority и т. Д., Подходит для веб-приложения), Тогда как последний используется только для проверки JWT (больше подходит для API).

Все статьи, которые я нашел, — это рецепты, посвященные настройке для определенного поставщика идентификаторов, такого как Azure или IdentityServer4, но я не нашел почти ничего, что действительно раскрывало бы поведение этих компонентов и то, как каждый настраиваемый параметр влияет на это поведение. Моя компания использует своего собственного поставщика идентификаторов для аутентификации и выдачи токенов JWT, поэтому большинство рецептов, которые я нахожу, дают лишь случайные подсказки, а не реальное понимание.

Я понимаю, что документация должна существовать, но я не смог найти ничего, кроме скелетного документа, предоставленного Microsoft на docs.microsoft.com .

Был бы очень признателен за более подробную информацию о том, как использовать эти два промежуточных ПО; не специально для именованного поставщика идентификаторов, а в более общем плане:

  • Верно ли мое предположение, которое .AddOpenIdConnect выполняет как проверку JWT, так и поддерживает танец OIDC, автоматически перенаправляя на орган власти, эмитента токена и т. Д.?
  • Зависит ли промежуточное программное обеспечение от аутентификации cookie; т. Е. Могу ли я опустить .AddCookie настройку?
  • Будет ли когда-нибудь иметь смысл использовать оба компонента промежуточного программного обеспечения ( .AddOpenIdConnect и .AddJwtBearer )?
  • Пожалуйста, опишите поведение каждого компонента и то, как параметры влияют на это поведение.
  • Какие обязательные параметры должны быть указаны, а какие являются необязательными?
  • Есть ли необходимость взаимодействовать с «танцем» OAuth2 (через события) или они предназначены только для отладки и настройки ответа / перенаправления?

Ответ №1:

AddOpenIdConnect, как вы говорите, отвечает за танец oauth, аутентификацию пользователя и создание сеанса пользователя. Он обрабатывает все внутри, поэтому вам не нужно подключать события, если вам не нужно их настраивать.

Обычно вы используете AddOpenIdConnect с AddCookie, чтобы AddCookie отвечал за cookie сеанса пользователя. AddOpenIdConnect используется только для части запроса потока входа пользователя.

AddJwtBearer предназначен только для API / сервисов, которые получают и аутентифицируют токены, он будет выполнять только проверку подлинности токена и создавать пользователя ClaimsPrincipal на основе токена.

вы можете использовать оба в одном сервисе, но я рекомендую вам этого не делать, потому что может быть очень сложно понять, что происходит. Сохраняйте простоту и следуйте принципу единой ответственности, и все готово. (т.е. Поместить их в разные службы)

Типичная настройка AddJwtBearer может выглядеть следующим образом:

 .AddJwtBearer(opt =>
{
    opt.Authority = "https://localhost:6001";
    opt.Audience = "paymentapi";

    opt.TokenValidationParameters.RoleClaimType = "roles";
    opt.TokenValidationParameters.NameClaimType = "name";
    opt.TokenValidationParameters.ClockSkew = TimeSpan.FromSeconds(0);


    // IdentityServer emits a typ header by default, recommended extra check
    opt.TokenValidationParameters.ValidTypes = new[] { "at jwt" };
});
 

Типичная настройка AddOpenIdConnect может выглядеть следующим образом:

     .AddOpenIdConnect(options =>
{
    options.AccessDeniedPath = "/User/AccessDenied";
    options.Authority = _configuration["openid:authority"];
    options.ClientId = _configuration["openid:clientid"];
    options.ClientSecret = "mysecret";
    options.ResponseType = "code";

    options.Scope.Clear();
    options.Scope.Add("openid");
    options.Scope.Add("profile");
    options.Scope.Add("email");
    options.Scope.Add("employee");
    options.Scope.Add("payment");
    options.Scope.Add("offline_access");

    options.GetClaimsFromUserInfoEndpoint = true;
    options.SaveTokens = true;
    options.Prompt = "consent";

    options.TokenValidationParameters = new TokenValidationParameters
    {
        NameClaimType = JwtClaimTypes.Name,
    };


});