All [ApiController] classes (BlogApi, BlogTags, PostTags, FileSystem,
FileSystemStream, Comments, TagsApi) returned 404 on every route,
even though Kestrel was up. The pipeline in Program.cs was missing
MapControllers(), so the controllers were never attached to the
endpoint data source. MapIdentityApi and MapGet("/identity")
worked because they're explicit minimal-API routes; the attribute-
routed controllers didn't.
Confirmed end-to-end: GET /api/v1/blog now returns 401 (auth
required by [Authorize("BlogScope")]) instead of 404.
103 lines
3.3 KiB
C#
103 lines
3.3 KiB
C#
using IdentityModel;
|
|
using Microsoft.AspNetCore.Authorization;
|
|
using Microsoft.AspNetCore.Mvc;
|
|
using Microsoft.EntityFrameworkCore;
|
|
using Microsoft.Extensions.DependencyInjection.Extensions;
|
|
using Yavsc;
|
|
using Yavsc.Interface;
|
|
using Yavsc.Interfaces;
|
|
using Yavsc.Models;
|
|
using Yavsc.Services;
|
|
using Yavsc.Server.Helpers;
|
|
using Microsoft.AspNetCore.Identity;
|
|
namespace Yavsc.Blogs;
|
|
|
|
internal class Program
|
|
{
|
|
private static async Task Main(string[] args)
|
|
{
|
|
Console.Title = "Yavsc.Blogs";
|
|
|
|
var builder = WebApplication.CreateBuilder(args);
|
|
|
|
builder.AddConfiguration("blogs");
|
|
|
|
var services = builder.Services;
|
|
|
|
// MvcBuilder
|
|
builder.Services
|
|
.AddAuthorization(options =>
|
|
{
|
|
options.AddPolicy("BlogScope", policy =>
|
|
{
|
|
policy
|
|
.RequireAuthenticatedUser()
|
|
.RequireClaim(JwtClaimTypes.Scope, new string[] { "blogs" });
|
|
});
|
|
})
|
|
.AddYavscCors(builder.Configuration)
|
|
.AddControllers();
|
|
|
|
// AuthenticationBuilder
|
|
services.AddAuthentication("Bearer")
|
|
.AddYavscJwtBearer(builder.Configuration);
|
|
|
|
// DbContextBuilder
|
|
services.AddDbContext<ApplicationDbContext>(options =>
|
|
options.UseNpgsql(builder.Configuration.GetConnectionString(
|
|
YavscConstants.YavscConnectionStringName)));
|
|
|
|
// other services
|
|
services
|
|
.AddTransient<ITrueEmailSender, MailSender>()
|
|
.AddTransient<IEmailSender<ApplicationUser>, MailSender>()
|
|
.TryAddSingleton<ISmtpClientFactory, SmtpClientFactory>();
|
|
services
|
|
.AddTransient<IBillingService, BillingService>()
|
|
.AddTransient<ICalendarManager, CalendarManager>()
|
|
.AddTransient<IFileSystemAuthManager, FileSystemAuthManager>()
|
|
.AddTransient<BlogSpotService>()
|
|
.AddScoped<IAuthorizationHandler, PermissionHandler>()
|
|
.AddLocalization(options =>
|
|
{
|
|
options.ResourcesPath = "Resources";
|
|
})
|
|
.AddDistributedMemoryCache()
|
|
.AddSession(options =>
|
|
{
|
|
options.IdleTimeout = TimeSpan.FromMinutes(30);
|
|
options.Cookie.HttpOnly = true;
|
|
options.Cookie.IsEssential = false;
|
|
}).Configure<RequestLocalizationOptions>(options =>
|
|
{
|
|
var supportedCultures = new[] { "fr", "en", "pt" };
|
|
options.SetDefaultCulture(supportedCultures[0])
|
|
.AddSupportedCultures(supportedCultures)
|
|
.AddSupportedUICultures(supportedCultures);
|
|
});
|
|
|
|
// App startup
|
|
using (var app = builder.Build())
|
|
{
|
|
if (app.Environment.IsDevelopment())
|
|
app.UseDeveloperExceptionPage();
|
|
|
|
app
|
|
.UseRouting()
|
|
.UseAuthentication()
|
|
.UseAuthorization()
|
|
.UseCors("default")
|
|
;
|
|
app.MapControllers();
|
|
app.MapIdentityApi<ApplicationUser>().RequireAuthorization("BlogScope");
|
|
|
|
app.MapGet("/identity", (HttpContext context) =>
|
|
new JsonResult(context?.User?.Claims.Select(c => new { c.Type, c.Value }))
|
|
);
|
|
|
|
app.UseSession();
|
|
await app.RunAsync();
|
|
}
|
|
}
|
|
|
|
}
|