Skip to content

Commit fa6ec77

Browse files
JWT Authentication with Bearer token support. Authorized GetAllErrors Api and LogErrors Api.
1 parent 32584f0 commit fa6ec77

File tree

6 files changed

+75
-1
lines changed

6 files changed

+75
-1
lines changed
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
namespace CentralizedLoggingApi.DTO.Auth
2+
{
3+
public class JwtOptions
4+
{
5+
public string Issuer { get; set; } = null!;
6+
public string Audience { get; set; } = null!;
7+
public string Key { get; set; } = null!;
8+
public int ExpiresMinutes { get; set; }
9+
}
10+
}

CentralizedLoggingApi/CentralizedLoggingApi.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
</PropertyGroup>
1111

1212
<ItemGroup>
13+
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="9.0.8" />
1314
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="9.0.7" />
1415
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="9.0.8" />
1516
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="9.0.8">

CentralizedLoggingApi/Controllers/ErrorLogsController.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
using CentralizedLoggingApi.Data;
22
using CentralizedLoggingApi.DTO;
33
using CentralizedLoggingApi.Models;
4+
using Microsoft.AspNetCore.Authorization;
45
using Microsoft.AspNetCore.Mvc;
56
using Microsoft.EntityFrameworkCore;
67

@@ -17,6 +18,7 @@ public ErrorLogsController(LoggingDbContext context)
1718
_context = context;
1819
}
1920

21+
[Authorize]
2022
// POST api/errorlogs
2123
[HttpPost]
2224
public async Task<IActionResult> LogError([FromBody] CreateErrorLogDto errorLogDto)
@@ -59,6 +61,7 @@ public async Task<IActionResult> GetErrorById(long id)
5961
return Ok(error);
6062
}
6163

64+
[Authorize]
6265
// GET api/errorlogs
6366
[HttpGet]
6467
public async Task<IActionResult> GetAllErrors()

CentralizedLoggingApi/Program.cs

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,14 @@
11
using CentralizedLoggingApi;
22
using CentralizedLoggingApi.Data;
3+
using CentralizedLoggingApi.DTO.Auth;
34
using CentralizedLoggingApi.Middlewares;
5+
using Microsoft.AspNetCore.Authentication.JwtBearer;
46
using Microsoft.EntityFrameworkCore;
7+
using Microsoft.IdentityModel.Tokens;
58
using Microsoft.OpenApi.Models;
69
using Serilog;
710
using System.Reflection;
11+
using System.Text;
812

913

1014

@@ -24,6 +28,30 @@
2428
builder.Services.AddDbContext<LoggingDbContext>(options =>
2529
options.UseSqlServer(builder.Configuration.GetConnectionString("DefaultConnection")));
2630

31+
// Add JwtOptions + Authentication
32+
builder.Services.Configure<JwtOptions>(builder.Configuration.GetSection("Jwt"));
33+
var jwt = builder.Configuration.GetSection("Jwt").Get<JwtOptions>()!;
34+
35+
var keyBase64 = builder.Configuration["Jwt:Key"]!;
36+
var keyPlain = Encoding.UTF8.GetString(Convert.FromBase64String(keyBase64));
37+
38+
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
39+
.AddJwtBearer(opt =>
40+
{
41+
opt.TokenValidationParameters = new TokenValidationParameters
42+
{
43+
ValidateIssuer = true,
44+
ValidateAudience = true,
45+
ValidateIssuerSigningKey = true,
46+
ValidIssuer = jwt.Issuer,
47+
ValidAudience = jwt.Audience,
48+
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(keyPlain)),
49+
ClockSkew = TimeSpan.Zero
50+
};
51+
});
52+
53+
builder.Services.AddAuthorization();
54+
2755

2856
builder.Services.AddHttpContextAccessor();
2957

@@ -41,6 +69,33 @@
4169
Version = "v1",
4270
Description = "API for centralized error logging and monitoring"
4371
});
72+
73+
// Bearer token support
74+
var jwtSecurityScheme = new Microsoft.OpenApi.Models.OpenApiSecurityScheme
75+
{
76+
Scheme = "bearer",
77+
BearerFormat = "JWT",
78+
Name = "Authorization",
79+
In = Microsoft.OpenApi.Models.ParameterLocation.Header,
80+
Type = Microsoft.OpenApi.Models.SecuritySchemeType.Http,
81+
Description = "JWT auth using Bearer scheme. Paste **only** the token below.",
82+
83+
Reference = new Microsoft.OpenApi.Models.OpenApiReference
84+
{
85+
Id = "Bearer",
86+
Type = Microsoft.OpenApi.Models.ReferenceType.SecurityScheme
87+
}
88+
};
89+
90+
c.AddSecurityDefinition("Bearer", jwtSecurityScheme);
91+
92+
// Require Bearer token for all operations (you can remove if you prefer per-endpoint)
93+
c.AddSecurityRequirement(new Microsoft.OpenApi.Models.OpenApiSecurityRequirement
94+
{
95+
{ jwtSecurityScheme, Array.Empty<string>() }
96+
});
97+
98+
4499
var xmlFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml";
45100
var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile);
46101
c.IncludeXmlComments(xmlPath, includeControllerXmlComments: true); // ok if your Swashbuckle version supports the bool

CentralizedLoggingApi/appsettings.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,12 @@
2323
"restrictedToMinimumLevel": "Information"
2424
}
2525
]
26+
},
27+
"Jwt": {
28+
"Issuer": "PermsApi",
29+
"Audience": "PermsApiAudience",
30+
"Key": "dmVyeV9sb25nX2Rldl9rZXlfY2hhbmdlX2luX3Byb2RfMTIzNDU2Nzg5MA==",
31+
"ExpiresMinutes": 60
2632
}
2733

2834
}

UserManagementApi/Program.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
using Microsoft.AspNetCore.Authentication.JwtBearer;
22
using Microsoft.EntityFrameworkCore;
33
using Microsoft.IdentityModel.Tokens;
4-
using Microsoft.OpenApi.Models;
54
using Serilog;
65
using System.Reflection;
76
using System.Text;

0 commit comments

Comments
 (0)