#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
Комментарии:
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);