Токен JWT веб-API ASP.NET всегда недействителенC#

Место общения программистов C#
Ответить
Anonymous
 Токен JWT веб-API ASP.NET всегда недействителен

Сообщение Anonymous »

При аутентификации через JWT в веб-API ASP.NET (.NET 8) мне всегда выдается это

Код: Выделить всё

Bearer error="invalid_token"
независимо от того, что я делаю.
Я проверил токен через jwt.io, там все выглядит нормально.
Я также проверил Chrome вкладка "Сеть", где все выглядит нормально.
Понятия не имею, так как я следил за руководством на YouTube, где все работало, и поскольку я новичок в ASP.NET.
Репозиторий: https://github.com/LarsSK06/Home-Server ... d/tree/dev
Program.cs

Код: Выделить всё

using HomeServer.Data;
using Microsoft.OpenApi.Models;
using Swashbuckle.AspNetCore.Filters;
using Microsoft.IdentityModel.Tokens;
using System.Text;

WebApplicationBuilder builder = WebApplication.CreateBuilder(args);

builder.Services.AddControllers();
builder.Services.AddEndpointsApiExplorer();

builder.Services.AddSwaggerGen(options => {
options.AddSecurityDefinition("oauth2", new OpenApiSecurityScheme{
In = ParameterLocation.Header,
Name = "Authorization",
Type = SecuritySchemeType.ApiKey
});

options.OperationFilter();
});

builder.Services.AddSingleton();

builder.Services.AddCors(options => {
options.AddDefaultPolicy(
policy =>
policy.WithOrigins("http://localhost:3000")
);
});

builder.Services.AddAuthentication().AddJwtBearer(options => {
options.TokenValidationParameters = new TokenValidationParameters{
ValidateIssuerSigningKey = true,
ValidateAudience = false,
ValidateIssuer = false,
IssuerSigningKey = new SymmetricSecurityKey(
Encoding.UTF8.GetBytes(
builder.Configuration.GetSection("AppSettings:Token").Value!
)
)
};
});

WebApplication app = builder.Build();

if(app.Environment.IsDevelopment()){
app.UseSwagger();
app.UseSwaggerUI();
}

app.UseCors();
app.UseAuthentication();
app.UseAuthorization();
app.MapControllers();

app.Run();
appsettings.json

Код: Выделить всё

{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*",
"ConnectionStrings": {
"DatabaseConnection": "mongodb://localhost:27017/dev"
},
"AppSettings": {
"Token": "jdiwlpmfpn210dff1kg92wagwagagrgrgrddgdgdrdrrggrdwdwafawfwafwafawfafawfffwwf"
}
}
Users.cs (API-контроллер для пользователей/ конечной точки

Код: Выделить всё

using Microsoft.AspNetCore.Mvc;
using MongoDB.Driver;
using HomeServer.Models;
using HomeServer.Data;
using HomeServer.Utilities;
using Microsoft.AspNetCore.Authorization;

namespace HomeServer.Controllers;

[ApiController]
[Route("[controller]")]
public class UsersController : ControllerBase{

private readonly IMongoCollection? _users;
private readonly IConfiguration _config;

public UsersController(MongoDBService mongoDBService, IConfiguration configuration){
_users = mongoDBService.Database?.GetCollection("users");
_config = configuration;
}

[HttpGet, Authorize]
public async Task GetUsers(){
if(_users is null)
return NotFound();

FilterDefinition? filter = FilterDefinition.Empty;
IAsyncCursor? cursor = await _users.FindAsync(filter);
List? users = await cursor.ToListAsync();
List publicUsers = [];

foreach(User i in users)
publicUsers.Add(i.ToPublic());

return Ok(publicUsers);
}

[HttpGet("{id}")]
public async Task GetUser(int id){
if(_users is null)
return NotFound();

FilterDefinition? filter = Builders.Filter.Eq(i =>  i.Id, id);
IAsyncCursor? cursor = await _users.FindAsync(filter);
User? first = await cursor.FirstOrDefaultAsync();

if(first is null)
return NotFound();

return first.ToPublic();
}

[HttpPost]
public async Task CreateUser(MutableUser data){
if(_users is null)
return NotFound();

FilterDefinition conflictedUsersFilter =
Builders.Filter.Eq(i => i.Email, data.Email);

IAsyncCursor? conflictedUsersCursor =
await _users.FindAsync(conflictedUsersFilter);

List conflictedUsers = await conflictedUsersCursor.ToListAsync();

if(conflictedUsers.Count > 0)
return Conflict();

User user = new(){
Id = Generator.GetEpoch(),
Name = data.Name,
Password = BCrypt.Net.BCrypt.HashPassword(data.Password, 15),
Email = data.Email,
Admin = data.Email.Equals("lars@kvihaugen.no")
};

await _users.InsertOneAsync(user);

return CreatedAtAction(
nameof(GetUser),
new { id = user.Id },
user.ToPublic()
);
}

[HttpPost("LogIn")]
public async Task LogIn(Credentials credentials){
if(_users is null)
return NotFound();

FilterDefinition? filter = Builders.Filter.Eq(i => i.Email, credentials.Email);
IAsyncCursor? users = await _users.FindAsync(filter);
User? user = await users.FirstOrDefaultAsync();

if(user is null)
return BadRequest();

if(!BCrypt.Net.BCrypt.Verify(credentials.Password, user.Password))
return Unauthorized();

string token = JWT.CreateToken(_config, user.ToPublic());

return Ok(token);
}

}

public class Credentials{
public required string Email { get; set; }
public required string Password { get; set; }
}
User.cs (модель MongoDB)

Код: Выделить всё

using MongoDB.Bson;
using MongoDB.Bson.Serialization.Attributes;

namespace HomeServer.Models;

public class User{

[BsonId]
[BsonElement("_id"), BsonRepresentation(BsonType.ObjectId)]
public string? MongoId { get; set; }

[BsonElement("id"), BsonRepresentation(BsonType.Int32)]
public required int Id { get; set; }

[BsonElement("name"), BsonRepresentation(BsonType.String)]
public required string Name { get; set; }

[BsonElement("password"), BsonRepresentation(BsonType.String)]
public required string Password { get; set; }

[BsonElement("email"), BsonRepresentation(BsonType.String)]
public required string Email { get; set; }

[BsonElement("admin"), BsonRepresentation(BsonType.Boolean)]
public required bool Admin { get; set; }

public PublicUser ToPublic(){
return new PublicUser{
Id = Id,
Name = Name,
Email = Email,
Admin = Admin
};
}

public MutableUser ToMutable(){
return new MutableUser{
Name = Name,
Password = Password,
Email = Email
};
}

}

public class PublicUser{

public required int Id { get; set; }
public required string Name { get; set; }
public required string Email { get; set; }
public required bool Admin { get; set; }

}

public class MutableUser{

public required string Name { get; set; }
public required string Password { get; set; }
public required string Email { get; set; }

}
JWT.cs (расположение функции CreateToken)

Код: Выделить всё

using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using System.Text;
using HomeServer.Models;
using Microsoft.IdentityModel.Tokens;

namespace HomeServer.Utilities;

public struct JWT{
public static string CreateToken(IConfiguration config, PublicUser user){
List  claims = new List{
new Claim(ClaimTypes.Email, user.Email)
};

SymmetricSecurityKey key =
new SymmetricSecurityKey(Encoding.UTF8.GetBytes(
config.GetSection("AppSettings:Token").Value!)
);

SigningCredentials credentials =
new SigningCredentials(key, SecurityAlgorithms.HmacSha512Signature);

JwtSecurityToken token = new JwtSecurityToken(
claims: claims,
expires: DateTime.Now.AddHours(12),
signingCredentials: credentials
);

string jwt = new JwtSecurityTokenHandler().WriteToken(token);

return jwt;
}
}
Коммиты можно увидеть в репозитории, но кроме этого я перепробовал большинство обучающих программ YouTube, но безуспешно.
Я пробовал пробовал добавлять разные параметры в AddSwaggerGen, AddAuthentication, AddJwtBearer, но не могу разобраться.

Подробнее здесь: https://stackoverflow.com/questions/791 ... ys-invalid
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C#»