У меня все еще есть серьезная проблема, когда мой jwt 401 не авторизован на моих звонках. Я использую ядро asp. net 3.1. net для создания слоя API.
Это генерируется из следующих Стати c метод класса, который присоединен через мой класс запуска
"JwtConfig": {"secret": "PDv7DrqznYL6nv7DrqzjnQYO9JxIsWdcjnQYL6nu0f", 101 * 101 * мин.
Но когда я вызываю примерный контроллер погоды контроллером котельной пластины, я получаю 401 не авторизованным, даже несмотря на то, что прошел процесс отправки его в раздел аутентификации в почтальоне.
Мой пример погодного контроллера
[ApiController]
[Authorize]
[Route("[controller]")]
public class WeatherForecastController : ControllerBase
{
private static readonly string[] Summaries = new[]
{
"Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
};
private readonly ILogger<WeatherForecastController> _logger;
public WeatherForecastController(ILogger<WeatherForecastController> logger)
{
_logger = logger;
}
[HttpGet]
public IEnumerable<WeatherForecast> Get()
{
var rng = new Random();
return Enumerable.Range(1, 5).Select(index => new WeatherForecast
{
Date = DateTime.Now.AddDays(index),
TemperatureC = rng.Next(-20, 55),
Summary = Summaries[rng.Next(Summaries.Length)]
})
.ToArray();
}
}
Авторизованный attritube - это просто дополнительный слой, который я должен проверить на наличие идентификатора клиента и секретного идентификатора из базы данных.
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
public class ApiKeyAttribute : Attribute, IAsyncActionFilter {
public string ApiKeyHeaderName = "ApiKey";
public string ClientSecret = "ClientSecret";
RoundTableERPContext db = new RoundTableERPContext();
public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next) {
//before
if (!context.HttpContext.Request.Headers.TryGetValue(ApiKeyHeaderName, out var potentialApiKey)) {
context.Result = new UnauthorizedResult();
return;
}
// before
if (!context.HttpContext.Request.Headers.TryGetValue(ClientSecret, out var potentialClientId)) {
context.Result = new UnauthorizedResult();
return;
}
Guid.TryParse(potentialApiKey, out Guid headerApiKey);
Guid.TryParse(potentialClientId, out Guid headerClientId);
if (!db.FindKeysByClientIdByApiKey(headerApiKey, headerClientId)) {
context.Result = new UnauthorizedResult();
return;
}
await next();
//after
}
Любые идеи, почему почтальон возвращается торизованный
Edit 1 Показать класс My Token о том, как токен генерируется.
[Route("api/[controller]")]
[ApiController]
public class TokenController : ControllerBase
{
private IConfiguration _config;
public TokenController(IConfiguration config)
{
_config = config;
}
[HttpGet]
public string GetRandomToken()
{
var jwt = new JwtService(_config);
var token = jwt.GenerateSecurityToken("fake@email.com");
return token;
}
}
}
Я считаю, что проблема может заключаться в делать с тем фактом, что учебник, которому я следовал, использовал fake@email.com
var token = jwt.GenerateSecurityToken ("fake@email.com");
Это говорит о недопустимой подписи, но не почему, когда я проверить это
1047 *
https://jwt.io/#debugger -io? лексема = eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJlbWFpbCI6ImZha2VAZW1haWwuY29tIiwibmJmIjoxNTg3MDY3NTMyLCJleHAiOjE1ODcxNTM5MzIsImlhdCI6MTU4NzA2NzUzMn0.cwQRoRWGxIqfTWsFleJp8qUlCr7ovS4urr8kcvPoxpE 1052 * Это мой JwtService как он получает создан
public class JwtService {
private readonly string _secret;
private readonly string _expDate;
public JwtService(IConfiguration config) {
_secret = config.GetSection("JwtConfig").GetSection("secret").Value;
_expDate = config.GetSection("JwtConfig").GetSection("expirationInMinutes").Value;
}
public string GenerateSecurityToken(string email) {
var tokenHandler = new JwtSecurityTokenHandler();
var key = Encoding.ASCII.GetBytes(_secret);
var tokenDescriptor = new SecurityTokenDescriptor
{
Subject = new ClaimsIdentity(new[]
{
new Claim(ClaimTypes.Email, email)
})
,
Expires = DateTime.UtcNow.AddMinutes(double.Parse(_expDate)),
SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(key), SecurityAlgorithms.HmacSha256Signature)
};
var token = tokenHandler.CreateToken(tokenDescriptor);
return tokenHandler.WriteToken(token);
}
Редактировать 2 Как сказал Jps для тестирования, мне пришлось вставить свой секрет в секретное поле с правой стороны, теперь это проверено, но. net по-прежнему возвращает 401 неавторизованным.
https://jwt.io/#debugger -io? лексема = eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJlbWFpbCI6ImZha2VAZW1haWwuY29tIiwibmJmIjoxNTg3MDY3NTMyLCJleHAiOjE1ODcxNTM5MzIsImlhdCI6MTU4NzA2N zUzMn0.cwQRoRWGxIqfTWsFleJp8qUlCr7ovS4urr8kcvPoxpE
Редактировать 2 Здесь также находятся мои файлы конфигурации.
public void ConfigureServices(IServiceCollection services) {
services.AddTokenAuthentication(Configuration);
services.AddControllers();
services.Configure<ConnectionStringConfig>(Configuration);
services.AddHttpClient("externalservice", c =>
{
// Assume this is an "external" service which requires an API KEY
c.BaseAddress = new Uri("https://localhost:5001/");
});
services
.AddControllersWithViews()
.SetCompatibilityVersion(CompatibilityVersion.Version_3_0);
services.AddControllers().AddJsonOptions(jsonOptions =>
{
jsonOptions.JsonSerializerOptions.PropertyNamingPolicy = null;
})
.SetCompatibilityVersion(CompatibilityVersion.Version_3_0);
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseRouting();
// Enable the application to use bearer tokens to authenticate users
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
}
Редактировать 3 * 72 * Это мой класс, который настраивает аутентификацию
public static IServiceCollection AddTokenAuthentication(this IServiceCollection services, IConfiguration config) {
var secret = config.GetSection("JwtConfig").GetSection("secret").Value;
var keySecret = Base64UrlEncoder.DecodeBytes(secret);
var key = Encoding.ASCII.GetBytes(keySecret.ToString());
services.AddAuthentication(x =>
{
x.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
x.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(x =>
{
x.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuerSigningKey = true,
IssuerSigningKey = new SymmetricSecurityKey(key),
ValidateIssuer = false,
ValidateAudience = false,
// ValidIssuer = "localhost",
//ValidAudience = "localhost"
};
});
return services;
}
}
Редактировать 4
Отображение пост-человека 401 без подтверждения
Отображение отправленных заголовков