
401 Unauthorized Error in User Update Endpoint (ASP.NET Core 7, JWT, Swagger)
Hello, I am learning ASP.NET Core and currently facing an issue with JWT -Authentifizierung. Ich teste meine API mit der Swagger -Benutzeroberfläche, und wenn ich versuche, einen Benutzer nach dem Anmelden zu aktualisieren, erhalte ich immer wieder einen 401 nicht autorisierten Fehler.
Code: Select all
using BlogAPI.Data;
using BlogAPI.Services;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.EntityFrameworkCore;
using Microsoft.IdentityModel.Tokens;
using Microsoft.OpenApi.Models;
using System.Text;
using System.Text.Json.Serialization;
var builder = WebApplication.CreateBuilder(args);
var configuration = builder.Configuration;
// 📌 PostgreSQL Bağlantısı
builder.Services.AddDbContext(options =>
options.UseNpgsql(configuration.GetConnectionString("DefaultConnection"))
);
// 📌 JSON Serializer Ayarları
builder.Services.AddControllers()
.AddJsonOptions(options =>
{
options.JsonSerializerOptions.PropertyNamingPolicy = null;
options.JsonSerializerOptions.ReferenceHandler = ReferenceHandler.IgnoreCycles;
});
// 📌 Servis Bağımlılıkları
builder.Services.AddScoped();
// 📌 CORS Politikası (Güvenlik için belirli domainleri kabul et)
builder.Services.AddCors(options =>
{
options.AddPolicy("AllowSpecificOrigins", policy =>
{
policy.WithOrigins("http://localhost:3000") // React, Vue veya Angular için frontend URL'sini ekle
.AllowAnyMethod()
.AllowAnyHeader();
});
});
// 📌 JWT Ayarları
var jwtKey = configuration["Jwt:Key"] ?? "thisisaverysecureandlongkeyforjwt123!";
var key = Encoding.UTF8.GetBytes(jwtKey);
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options =>
{
options.RequireHttpsMetadata = false;
options.SaveToken = true;
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuerSigningKey = true,
IssuerSigningKey = new SymmetricSecurityKey(key),
ValidateIssuer = false,
ValidateAudience = false,
ValidateLifetime = true,
ClockSkew = TimeSpan.Zero
};
});
builder.Services.AddAuthorization();
// 📌 Swagger JWT Desteği
builder.Services.AddSwaggerGen(c =>
{
c.SwaggerDoc("v1", new OpenApiInfo { Title = "BlogAPI", Version = "v1" });
var securityScheme = new OpenApiSecurityScheme
{
Name = "Authorization",
Description = "Bearer token'ınızı girin (Örn: Bearer eyJhbGciOiJIUzI...)",
In = ParameterLocation.Header,
Type = SecuritySchemeType.Http,
Scheme = JwtBearerDefaults.AuthenticationScheme,
BearerFormat = "JWT"
};
c.AddSecurityDefinition(JwtBearerDefaults.AuthenticationScheme, securityScheme);
c.AddSecurityRequirement(new OpenApiSecurityRequirement
{
{ securityScheme, new string[] {} }
});
});
var app = builder.Build();
// 📌 Middleware Yapılandırması
app.UseHttpsRedirection();
app.UseCors("AllowSpecificOrigins");
app.UseAuthentication();
app.UseAuthorization();
app.MapControllers();
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
}
app.Run();
< /code>
using BCrypt.Net;
using BlogAPI.Data;
using BlogAPI.DTOs;
using BlogAPI.Models;
using BlogAPI.Services;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using System.Security.Claims;
namespace BlogAPI.Controllers
{
[Route("api/user")]
[ApiController]
public class UserController : ControllerBase
{
private readonly AppDbContext _context;
private readonly AuthService _authService;
public UserController(AppDbContext context, AuthService authService)
{
_context = context;
_authService = authService;
}
// 📌 Tüm Kullanıcıları Getir (Sadece Admin Yetkili)
[HttpGet]
[Authorize(Roles = "Admin")]
public async Task GetAllUsers()
{
var users = await _context.Users.ToListAsync();
return Ok(users);
}
// 📌 Belirtilen Kullanıcıyı Getir
[HttpGet("{id}")]
[Authorize]
public async Task GetUserById(int id)
{
var user = await _context.Users.FindAsync(id);
if (user == null)
{
return NotFound(new { message = "Kullanıcı bulunamadı" });
}
var loggedInUserId = User.FindFirst(ClaimTypes.NameIdentifier)?.Value;
var loggedInUserRole = User.FindFirst(ClaimTypes.Role)?.Value;
// Eğer giriş yapan admin değilse sadece kendisini görebilir
if (loggedInUserRole != "Admin" && loggedInUserId != user.Id.ToString())
{
return Forbid();
}
return Ok(user);
}
[HttpPut("{id}")]
[Authorize]
public async Task UpdateUser(int id, [FromBody] User updatedUser)
{
Console.WriteLine("🔥 PUT isteği geldi!");
// Token'dan giriş yapan kullanıcı ID'sini al
var loggedInUserIdClaim = User.FindFirst(ClaimTypes.NameIdentifier)?.Value;
var loggedInUserRole = User.FindFirst(ClaimTypes.Role)?.Value;
Console.WriteLine($"🔹 Token'dan Alınan ID: {loggedInUserIdClaim}");
Console.WriteLine($"🔹 Token'dan Alınan Rol: {loggedInUserRole}");
if (string.IsNullOrEmpty(loggedInUserIdClaim))
{
Console.WriteLine("🚨 Kullanıcı kimliği bulunamadı!");
return Unauthorized(new { message = "Geçersiz token." });
}
if (!int.TryParse(loggedInUserIdClaim, out var loggedInUserId))
{
return Unauthorized(new { message = "Token'daki kimlik bilgisi geçersiz." });
}
var user = await _context.Users.FindAsync(id);
if (user == null)
{
return NotFound(new { message = "Kullanıcı bulunamadı" });
}
if (loggedInUserRole != "Admin" && loggedInUserId != id)
{
Console.WriteLine("🚨 Yetkisiz güncelleme girişimi!");
return Forbid();
}
user.Username = updatedUser.Username ?? user.Username;
user.Email = updatedUser.Email ?? user.Email;
if (!string.IsNullOrEmpty(updatedUser.PasswordHash))
{
user.PasswordHash = BCrypt.Net.BCrypt.HashPassword(updatedUser.PasswordHash);
}
await _context.SaveChangesAsync();
return Ok(new { message = "Kullanıcı bilgileri güncellendi", user });
}
// 📌 Kullanıcı Silme (Sadece Admin Yetkili)
[HttpDelete("{id}")]
[Authorize(Roles = "Admin")]
public async Task DeleteUser(int id)
{
var user = await _context.Users.FindAsync(id);
if (user == null)
{
return NotFound(new { message = "Kullanıcı bulunamadı" });
}
_context.Users.Remove(user);
await _context.SaveChangesAsync();
return Ok(new { message = "Kullanıcı başarıyla silindi" });
}
// 📌 Yeni Kullanıcı Kaydı
[HttpPost("register")]
public async Task Register([FromBody] User newUser)
{
if (newUser == null)
{
return BadRequest(new { message = "Geçersiz kullanıcı verisi" });
}
var userExists = await _context.Users.AnyAsync(u => u.Email == newUser.Email);
if (userExists)
{
return BadRequest(new { message = "Bu e-posta adresi zaten kayıtlı" });
}
newUser.PasswordHash = BCrypt.Net.BCrypt.HashPassword(newUser.PasswordHash);
if (string.IsNullOrEmpty(newUser.Role) || newUser.Role.ToLower() != "admin")
{
newUser.Role = "User";
}
await _context.Users.AddAsync(newUser);
await _context.SaveChangesAsync();
return Ok(new { message = "Kullanıcı başarıyla kaydedildi" });
}
// 📌 Kullanıcı Girişi (JWT Token Döndürür)
[HttpPost("login")]
public async Task Login([FromBody] LoginRequest request)
{
var user = await _context.Users.FirstOrDefaultAsync(u => u.Email == request.Email);
if (user == null || !BCrypt.Net.BCrypt.Verify(request.Password, user.PasswordHash))
{
return Unauthorized(new { message = "Geçersiz email veya şifre" });
}
var token = _authService.GenerateJwtToken(user);
return Ok(new { token });
}
}
}