Промежуточное программное обеспечение аутентификации на Предъявителя Jwt всегда устанавливает Пользователя.Идентичность.Не соответствует действительности

#c# #asp.net-web-api #jwt #owin-middleware

Вопрос:

Я добавил UseJwtBearerAuthentication промежуточное программное обеспечение в свое приложение для проверки подлинности всех входящих запросов:

 public void Configuration(IAppBuilder app)
{

    var config = new HttpConfiguration();
    WebApiConfig.Register(config);
    #region Autofac config

    var container =AutofacWebapiConfig.Initialize(GlobalConfiguration.Configuration);
    config.DependencyResolver = new AutofacWebApiDependencyResolver(container);

    #endregion
    #region RoutConfig

    RouteConfig.RegisterRoutes(RouteTable.Routes);

    #endregion

    //Register middlewares
    app.UseJwtBearerAuthentication(new MyJwtAuthenticationOptions());
    app.UseAutofacMiddleware(container);
    app.Use<ReadBodyMiddleware>();
    app.UseWebApi(config);

}
 

И это мой класс MyJwtAuthenticationOptions:

 public class MyJwtAuthenticationOptions: JwtBearerAuthenticationOptions
{
    public MyJwtAuthenticationOptions()
    {
        var secretkey = ConfigurationManager.AppSettings["SecretKey"].ToString();

        AuthenticationMode = Microsoft.Owin.Security.AuthenticationMode.Active;
        AuthenticationType = "Basic";
        TokenValidationParameters = new TokenValidationParameters()
        {
            ValidateIssuerSigningKey = true,
            IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(secretkey)),
            ValidAlgorithms = new string[] { SecurityAlgorithms.HmacSha256Signature }
        };
    }
}
 

Теперь давайте посмотрим, как генерируется токен:

 public static string GenerateToken(string userid)
{
    var expireMin = ConfigurationManager.AppSettings["TokenExpirationMinutes"].ToString();
    var secretKey = ConfigurationManager.AppSettings["SecretKey"].ToString();

    byte[] key = Convert.FromBase64String(secretKey);
    SymmetricSecurityKey securityKey = new SymmetricSecurityKey(key);
    var descriptor = new SecurityTokenDescriptor
    {
        Subject = new ClaimsIdentity(new[] {
              new Claim("UserId", userid)}, "Basic"),
        Expires = DateTime.UtcNow.AddMinutes(Convert.ToInt32(expireMin)),
        SigningCredentials = new SigningCredentials(securityKey,
        SecurityAlgorithms.HmacSha256Signature)
    };

    JwtSecurityTokenHandler handler = new JwtSecurityTokenHandler();
    JwtSecurityToken token = handler.CreateJwtSecurityToken(descriptor);
    return handler.WriteToken(token);
}
 

Но когда я помещаю сгенерированный токен в Authorization заголовок и отправляю его на сервер через Postman

 HttpContext.Current.User.Identity.IsAuthenticated is always false
 

Заголовок авторизации правильно задан в Bearer формате
введите описание изображения здесь

введите описание изображения здесь

Комментарии:

1. У вашего контроллера или метода есть [Authorize] атрибут?

2. no…it это не так… Промежуточное ПО аутентификации должно установить для IsAuthenticated значение true, если это допустимый токен.

3. У вас есть документы на это?

4. Тогда какой смысл использовать промежуточное ПО «UseJwtBearerAuthentication»?

5. он отвечает за аутентификацию, авторизация в настоящее время не является моим делом.

Ответ №1:

Моя проблема возникла из двух моментов:

т. 1:

 public static void Register(HttpConfiguration config)
{
    // Owin auth
    config.SuppressDefaultHostAuthentication();
    config.Filters.Add(new HostAuthenticationFilter(OAuthDefaults.AuthenticationType));

    // Web API routes
    config.EnableCors(new EnableCorsAttribute("*", "*", "*"));
    config.MapHttpAttributeRoutes();
    config.Services.Insert(typeof(ModelBinderProvider), 0,
     new SimpleModelBinderProvider(typeof(DocumentModel), new FromFormDataBinding()));
    config.Routes.MapHttpRoute(
        name: "DefaultApi",
        routeTemplate: "{controller}/{action}/{id}",
        defaults: new { id = RouteParameter.Optional }
    );
}
 

эта строка отличалась от других точек моего api, которые я использовал Signature

 config.Filters.Add(new HostAuthenticationFilter(OAuthDefaults.AuthenticationType));
 

Изменено на это:

 config.Filters.Add(new HostAuthenticationFilter("Signature"));
 

пункт 2:

Внутри GenerateTokebn класса я читал secretkey таким образом:

 byte[] key = Convert.FromBase64String(secretKey);
 

изменено на эту строку, чтобы быть таким же, как MyJwtAuthenticationOptions класс:

 byte[] key = Encoding.UTF8.GetBytes(secretKey);