metrics service

fixes to auth info
This commit is contained in:
2025-07-05 23:55:40 -04:00
parent 5a34860fca
commit cc64675c9c
8 changed files with 104 additions and 15 deletions

View File

@@ -16,15 +16,9 @@ using System.Threading.Tasks;
namespace AobaCore; namespace AobaCore;
public static class Extensions public static class Extensions
{ {
public static IServiceCollection AddAoba(this IServiceCollection services, string dbString) public static IServiceCollection AddAoba(this IServiceCollection services)
{ {
var settings = MongoClientSettings.FromConnectionString(dbString);
settings.ClusterConfigurator = cb => cb.Subscribe(new DiagnosticsActivityEventSubscriber());
var dbClient = new MongoClient(settings);
var db = dbClient.GetDatabase("Aoba");
services.AddSingleton(dbClient);
services.AddSingleton<IMongoDatabase>(db);
services.AddSingleton<AobaService>(); services.AddSingleton<AobaService>();
services.AddSingleton<ThumbnailService>(); services.AddSingleton<ThumbnailService>();
services.AddSingleton<AccountsService>(); services.AddSingleton<AccountsService>();

View File

@@ -34,6 +34,7 @@
<ItemGroup> <ItemGroup>
<Protobuf Include="Proto\Aoba.proto"></Protobuf> <Protobuf Include="Proto\Aoba.proto"></Protobuf>
<Protobuf Include="Proto\Auth.proto"></Protobuf> <Protobuf Include="Proto\Auth.proto"></Protobuf>
<Protobuf Include="Proto\Metrics.proto"></Protobuf>
</ItemGroup> </ItemGroup>
</Project> </Project>

View File

@@ -1,6 +1,7 @@
using AobaCore.Services; using AobaCore.Services;
using AobaServer.Models; using AobaServer.Models;
using AobaServer.Services;
using AobaServer.Utils; using AobaServer.Utils;
using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Authorization;
@@ -16,7 +17,7 @@ namespace AobaServer.Controllers;
#if DEBUG #if DEBUG
[AllowAnonymous] [AllowAnonymous]
[Route("auth")] [Route("auth")]
public class AuthController(AccountsService accountsService, AuthInfo authInfo) : Controller public class AuthController(AccountsService accountsService, AuthConfigService authConfig) : Controller
{ {
[HttpPost("login")] [HttpPost("login")]
public async Task<IActionResult> Login([FromForm] string username, [FromForm] string password, CancellationToken cancellationToken) public async Task<IActionResult> Login([FromForm] string username, [FromForm] string password, CancellationToken cancellationToken)
@@ -25,6 +26,7 @@ public class AuthController(AccountsService accountsService, AuthInfo authInfo)
if (user == null) if (user == null)
return Problem("Invalid login Credentials", statusCode: StatusCodes.Status400BadRequest); return Problem("Invalid login Credentials", statusCode: StatusCodes.Status400BadRequest);
var authInfo = await authConfig.GetDefaultAuthInfoAsync();
Response.Cookies.Append("token", user.GetToken(authInfo), new CookieOptions Response.Cookies.Append("token", user.GetToken(authInfo), new CookieOptions
{ {
IsEssential = true, IsEssential = true,

View File

@@ -1,4 +1,6 @@
using MongoDB.Bson.IO; using MongoDB.Bson;
using MongoDB.Bson.IO;
using MongoDB.Bson.Serialization.Attributes;
using System.Security.Cryptography; using System.Security.Cryptography;
using System.Text.Json; using System.Text.Json;
@@ -7,6 +9,8 @@ namespace AobaServer.Models;
public class AuthInfo public class AuthInfo
{ {
[BsonId]
public ObjectId Id { get; set; }
public required string Issuer { get; set; } public required string Issuer { get; set; }
public required string Audience { get; set; } public required string Audience { get; set; }
public required byte[] SecureKey { get; set; } public required byte[] SecureKey { get; set; }

View File

@@ -10,6 +10,9 @@ using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Http.Features; using Microsoft.AspNetCore.Http.Features;
using Microsoft.IdentityModel.Tokens; using Microsoft.IdentityModel.Tokens;
using MongoDB.Driver;
using MongoDB.Driver.Core.Extensions.DiagnosticSources;
var builder = WebApplication.CreateBuilder(args); var builder = WebApplication.CreateBuilder(args);
builder.WebHost.ConfigureKestrel(o => builder.WebHost.ConfigureKestrel(o =>
@@ -33,8 +36,21 @@ builder.Services.AddControllers(opt => opt.ModelBinderProviders.Add(new BsonIdMo
builder.Services.AddObersability(builder.Configuration); builder.Services.AddObersability(builder.Configuration);
builder.Services.AddGrpc(); builder.Services.AddGrpc();
var authInfo = AuthInfo.LoadOrCreate("Auth.json", "aobaV2", "aoba"); //DB
builder.Services.AddSingleton(authInfo); var dbString = config["DB_STRING"];
var settings = MongoClientSettings.FromConnectionString(dbString);
settings.ClusterConfigurator = cb => cb.Subscribe(new DiagnosticsActivityEventSubscriber());
var dbClient = new MongoClient(settings);
var db = dbClient.GetDatabase("Aoba");
builder.Services.AddSingleton(dbClient);
builder.Services.AddSingleton<IMongoDatabase>(db);
var authCfg = new AuthConfigService(db);
builder.Services.AddSingleton(authCfg);
var authInfo = authCfg.GetDefaultAuthInfoAsync().GetAwaiter().GetResult();
var signingKey = new SymmetricSecurityKey(authInfo.SecureKey); var signingKey = new SymmetricSecurityKey(authInfo.SecureKey);
var validationParams = new TokenValidationParameters var validationParams = new TokenValidationParameters
@@ -66,6 +82,7 @@ builder.Services.AddCors(o =>
}); });
}); });
var metricsAuthInfo = authCfg.GetAuthInfoAsync("aoba", "metrics").GetAwaiter().GetResult();
builder.Services.AddAuthentication(options => builder.Services.AddAuthentication(options =>
{ {
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme; options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
@@ -73,7 +90,7 @@ builder.Services.AddAuthentication(options =>
}).AddJwtBearer(JwtBearerDefaults.AuthenticationScheme, options => //Bearer auth }).AddJwtBearer(JwtBearerDefaults.AuthenticationScheme, options => //Bearer auth
{ {
options.TokenValidationParameters = validationParams; options.TokenValidationParameters = validationParams;
options.TokenHandlers.Add(new MetricsTokenValidator(authInfo)); options.TokenHandlers.Add(new MetricsTokenValidator(metricsAuthInfo));
options.Events = new JwtBearerEvents options.Events = new JwtBearerEvents
{ {
OnMessageReceived = ctx => //Retreive token from cookie if not found in headers OnMessageReceived = ctx => //Retreive token from cookie if not found in headers
@@ -102,8 +119,8 @@ builder.Services.AddAuthentication(options =>
}; };
}).AddScheme<AuthenticationSchemeOptions, AobaAuthenticationHandler>("Aoba", null); }).AddScheme<AuthenticationSchemeOptions, AobaAuthenticationHandler>("Aoba", null);
var dbString = config["DB_STRING"];
builder.Services.AddAoba(dbString ?? "mongodb://localhost:27017"); builder.Services.AddAoba();
builder.Services.Configure<FormOptions>(opt => builder.Services.Configure<FormOptions>(opt =>
{ {
opt.ValueLengthLimit = int.MaxValue; opt.ValueLengthLimit = int.MaxValue;

View File

@@ -0,0 +1,12 @@
syntax = "proto3";
option csharp_namespace = "Aoba.RPC.Metrics";
package aoba.Metrics;
import "Proto/Auth.proto";
import "google/protobuf/empty.proto";
service Metrics {
rpc GetToken(google.protobuf.Empty) returns (Auth.Jwt);
}

View File

@@ -0,0 +1,26 @@
using AobaServer.Models;
using MongoDB.Driver;
namespace AobaServer.Services;
public class AuthConfigService(IMongoDatabase db)
{
public IMongoCollection<AuthInfo> _authInfo = db.GetCollection<AuthInfo>("auth_config");
public async Task<AuthInfo> GetAuthInfoAsync(string issuer, string audience)
{
var info = await _authInfo.Find("{}").FirstOrDefaultAsync();
if(info != null)
return info;
info = AuthInfo.Create(issuer, audience);
await _authInfo.InsertOneAsync(info);
return info;
}
public Task<AuthInfo> GetDefaultAuthInfoAsync()
{
return GetAuthInfoAsync("aobaV2", "aoba");
}
}

View File

@@ -0,0 +1,33 @@
using Aoba.RPC;
using Aoba.RPC.Auth;
using Google.Protobuf.WellKnownTypes;
using Grpc.Core;
using Microsoft.AspNetCore.Authorization;
using Microsoft.IdentityModel.Tokens;
using System.IdentityModel.Tokens.Jwt;
namespace AobaServer.Services;
public class MetricsRpcService(AuthConfigService authConfig): Aoba.RPC.Metrics.Metrics.MetricsBase
{
[AllowAnonymous]
public override async Task<Jwt> GetToken(Empty request, ServerCallContext context)
{
var authInfo = await authConfig.GetAuthInfoAsync("aoba", "metrics");
var handler = new JwtSecurityTokenHandler();
var jwt = handler.CreateEncodedJwt(new SecurityTokenDescriptor
{
Audience = authInfo.Audience,
Issuer = authInfo.Issuer,
IssuedAt = DateTime.UtcNow,
SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(authInfo.SecureKey), SecurityAlgorithms.HmacSha256)
});
return new Jwt { Token = jwt };
}
}