Я создал образец основного приложения .Net WebAPI, чтобы понять реализацию JWT. API был создан и в него добавлена аутентификация на основе JWT. API возвращает токен от контроллера токенов. Но если мы добавим токен в заголовок для выполнения последующего запроса, API вернет несанкционированную ошибку. Я не могу найти, в чем проблема. Я приложил как клиентский, так и серверный код, который использовал. Пожалуйста, помогите понять, в чем проблема в написанном мною коде
Код API
Контроллер токенов
using JWTAuthentication.Models;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Microsoft.IdentityModel.Tokens;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using System.Text;
namespace JWTAuthentication.Controllers
{
[Route("api/[controller]")]
[ApiController]
public class TokenController : ControllerBase
{
public IConfiguration _configuration;
public DatabaseContext _context;
public TokenController(IConfiguration configuration, DatabaseContext context)
{
_configuration = configuration;
_context = context;
}
[HttpPost]
public async Task Post(UserInfo userInfo)
{
if (userInfo != null && !string.IsNullOrEmpty(userInfo.Email) && !string.IsNullOrEmpty(userInfo.Password))
{
var user = await _context.UserInfos.FirstOrDefaultAsync(u => u.Email == userInfo.Email && u.Password == userInfo.Password);
if (user != null)
{
var claims = new[] {
new Claim(JwtRegisteredClaimNames.Sub, _configuration["Jwt:Subject"]),
new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()),
new Claim(JwtRegisteredClaimNames.Iat, DateTime.UtcNow.ToString()),
new Claim("UserId", user.UserId.ToString()),
new Claim("DisplayName", user.DisplayName),
new Claim("UserName", user.UserName),
new Claim("Email", user.Email)
};
var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_configuration["Jwt:Key"]));
var signIn = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
var token = new JwtSecurityToken(
_configuration["Jwt:Issuer"],
_configuration["Jwt:Audience"],
claims,
expires: DateTime.UtcNow.AddMinutes(10),
signingCredentials: signIn);
return Ok(new JwtSecurityTokenHandler().WriteToken(token));
}
else
{
return BadRequest("invalid credentials");
}
}
else
{
return BadRequest();
}
}
}
}
Контроллер сотрудников
using JWTAuthentication.Interface;
using JWTAuthentication.Models;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
namespace JWTAuthentication.Controllers
{
[Authorize]
[Route("api/employee")]
[ApiController]
public class EmployeeController : Controller
{
private readonly IEmployee _IEmployee;
public EmployeeController(IEmployee IEmployee)
{
_IEmployee = IEmployee;
}
// GET: api/employee>
[HttpGet]
public async Task Get()
{
return await Task.FromResult(_IEmployee.GetEmployeeDetails());
}
// GET api/employee/5
[HttpGet("{id}")]
public async Task Get(int id)
{
var employees = await Task.FromResult(_IEmployee.GetEmployeeDetails(id));
if (employees == null)
{
return NotFound();
}
return employees;
}
// POST api/employee
[HttpPost]
public async Task Post(Employee employee)
{
_IEmployee.AddEmployee(employee);
return await Task.FromResult(employee);
}
// PUT api/employee/5
[HttpPut("{id}")]
public async Task Put(int id, Employee employee)
{
if (id != employee.EmployeeID)
{
return BadRequest();
}
try
{
_IEmployee.UpdateEmployee(employee);
}
catch (DbUpdateConcurrencyException)
{
if (!EmployeeExists(id))
{
return NotFound();
}
else
{
throw;
}
}
return await Task.FromResult(employee);
}
// DELETE api/employee/5
[HttpDelete("{id}")]
public async Task Delete(int id)
{
var employee = _IEmployee.DeleteEmployee(id);
return await Task.FromResult(employee);
}
private bool EmployeeExists(int id)
{
return _IEmployee.CheckEmployee(id);
}
}
}
Program.cs
using JWTAuthentication.Interface;
using JWTAuthentication.Models;
using JWTAuthentication.Repository;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.EntityFrameworkCore;
using Microsoft.IdentityModel.Tokens;
using Microsoft.OpenApi.Models;
using System.Text;
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddDbContext(x=>x.UseSqlServer(builder.Configuration.GetConnectionString("dbConnection")));
builder.Services.AddTransient();
builder.Services.AddControllers();
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme).AddJwtBearer
(x =>
{ x.RequireHttpsMetadata = false;
x.SaveToken = true;
x.TokenValidationParameters = new Microsoft.IdentityModel.Tokens.TokenValidationParameters()
{
ValidateIssuer = true,
ValidateAudience = true,
ValidIssuer = builder.Configuration["Jwt:Issuer"],
ValidAudience = builder.Configuration["Jwt:Audience"],
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(builder.Configuration["Jwt:Key"]))
};
}
);
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
//builder.Services.AddSwaggerGen();
builder.Services.AddSwaggerGen(c => {
c.SwaggerDoc("v1", new OpenApiInfo
{
Title = "JWTToken_Auth_API",
Version = "v1"
});
c.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme()
{
Name = "Authorization",
Type = SecuritySchemeType.ApiKey,
Scheme = "Bearer",
BearerFormat = "JWT",
In = ParameterLocation.Header,
Description = "JWT Authorization header using the Bearer scheme. \r\n\r\n Enter 'Bearer' [space] and then your token in the text input below.\r\n\r\nExample: \"Bearer 1safsfsdfdfd\"",
});
c.AddSecurityRequirement(new OpenApiSecurityRequirement {
{
new OpenApiSecurityScheme {
Reference = new OpenApiReference {
Type = ReferenceType.SecurityScheme,
Id = "Bearer"
}
},
new string[] {}
}
});
});
var app = builder.Build();
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
}
app.UseAuthentication();
app.UseHttpsRedirection();
app.UseAuthorization();
app.MapControllers();
app.Run();
Код приложения консоли вызова
using ConsumeJWTWebApiCore.Models;
using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json;
using System.Net.Http.Headers;
namespace ConsumeJWTWebApiCore.Controllers
{
public class HomeController : Controller
{
public async Task Index()
{
HttpClient client = new HttpClient();
client.BaseAddress = new Uri(@"https://localhost:44303/");
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/json"));
//var reqMsg=new HttpRequestMessage(HttpMethod.Get, client.BaseAddress+@"api/employee");
// var response = await client.GetAsync(client.BaseAddress + @"api/employee");
JsonContent content = JsonContent.Create(new UserInfo() { Email="[email protected]",Password="$admin@2022"});
var response = await client.PostAsync(client.BaseAddress + @"api/Token", content);
string token = null;
if (response.IsSuccessStatusCode)
{
token = (string?)JsonConvert.DeserializeObject(await response.Content.ReadAsStringAsync());
}
client.DefaultRequestHeaders.Authorization =new AuthenticationHeaderValue("Bearer", token);
client.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/json"));
var getResp = await client.GetAsync(client.BaseAddress+ @"api/employee");
if(getResp.IsSuccessStatusCode)
{
var emp = JsonConvert.DeserializeObject(await getResp.Content.ReadAsStringAsync());
}
return View();
}
}
}
Подробнее здесь: https://stackoverflow.com/questions/785 ... rization-h
Несанкционированная ошибка токена веб-API JWT, несмотря на передачу токена в заголовке авторизации ⇐ C#
-
- Похожие темы
- Ответы
- Просмотры
- Последнее сообщение
-
-
401 Несанкционированная ошибка с аутентификацией JWT в приложении .NET 8 и Vue.js
Anonymous » » в форуме C# - 0 Ответы
- 15 Просмотры
-
Последнее сообщение Anonymous
-