Replace MSAL and custom cookie auth with Microsoft.Identity.EntityFramework Also some UI redesign to accommodate different login experience.
106 lines
3.1 KiB
C#
106 lines
3.1 KiB
C#
using Microsoft.AspNetCore.Identity.UI.Services;
|
|
using Microsoft.AspNetCore.ResponseCompression;
|
|
using Microsoft.EntityFrameworkCore;
|
|
using Shogi.Api;
|
|
using Shogi.Api.Application;
|
|
using Shogi.Api.Identity;
|
|
using Shogi.Api.Repositories;
|
|
|
|
var builder = WebApplication.CreateBuilder(args);
|
|
var allowedOrigins = builder
|
|
.Configuration
|
|
.GetSection("Cors:AllowedOrigins")
|
|
.Get<string[]>() ?? throw new InvalidOperationException("Configuration for allowed origins is missing.");
|
|
|
|
builder.Services
|
|
.AddControllers()
|
|
.AddJsonOptions(options =>
|
|
{
|
|
options.JsonSerializerOptions.WriteIndented = true;
|
|
});
|
|
builder.Services.AddEndpointsApiExplorer();
|
|
builder.Services.AddSwaggerGen();
|
|
builder.Services.AddTransient<SessionRepository>();
|
|
builder.Services.AddTransient<QueryRepository>();
|
|
builder.Services.AddTransient<ShogiApplication>();
|
|
builder.Services.AddTransient<GameHubContext>();
|
|
builder.Services.AddHttpClient<IEmailSender, EmailSender>();
|
|
builder.Services.Configure<ApiKeys>(builder.Configuration.GetSection("ApiKeys"));
|
|
|
|
AddIdentity(builder, builder.Configuration);
|
|
builder.Services.AddSignalR();
|
|
builder.Services.AddResponseCompression(opts =>
|
|
{
|
|
opts.MimeTypes = ResponseCompressionDefaults.MimeTypes.Concat(["application/octet-stream"]);
|
|
});
|
|
var app = builder.Build();
|
|
|
|
app.MapIdentityApi<ShogiUser>();
|
|
|
|
if (app.Environment.IsDevelopment())
|
|
{
|
|
app.UseHttpsRedirection(); // Apache handles HTTPS in production.
|
|
}
|
|
else
|
|
{
|
|
app.UseResponseCompression();
|
|
}
|
|
app.UseSwagger();
|
|
app.UseSwaggerUI(options => options.DocumentTitle = "Shogi.Api");
|
|
app.UseAuthorization();
|
|
app.Map("/", () => "OK");
|
|
app.MapControllers();
|
|
app.UseCors(policy =>
|
|
{
|
|
policy.WithOrigins(allowedOrigins).AllowAnyHeader().AllowAnyMethod().AllowCredentials();
|
|
});
|
|
|
|
app.MapHub<GameHub>("/gamehub").RequireAuthorization();
|
|
|
|
app.Run();
|
|
|
|
static void AddIdentity(WebApplicationBuilder builder, ConfigurationManager configuration)
|
|
{
|
|
builder.Services
|
|
.AddAuthorizationBuilder()
|
|
.AddPolicy("Admin", policy =>
|
|
{
|
|
policy.RequireAuthenticatedUser();
|
|
policy.RequireAssertion(context => context.User?.Identity?.Name switch
|
|
{
|
|
"Hauth@live.com" => true,
|
|
"aat-account" => true,
|
|
_ => false
|
|
});
|
|
});
|
|
|
|
builder.Services
|
|
.AddDbContext<ApplicationDbContext>(options =>
|
|
{
|
|
var cs = configuration.GetConnectionString("ShogiDatabase") ?? throw new InvalidOperationException("Database not configured.");
|
|
options.UseSqlServer(cs);
|
|
|
|
// This is helpful to debug account issues without affecting the database.
|
|
//options.UseInMemoryDatabase("AppDb");
|
|
})
|
|
.AddIdentityApiEndpoints<ShogiUser>(options =>
|
|
{
|
|
options.SignIn.RequireConfirmedEmail = true;
|
|
options.User.RequireUniqueEmail = true;
|
|
})
|
|
.AddEntityFrameworkStores<ApplicationDbContext>();
|
|
|
|
// I shouldn't this because I have it above, right?
|
|
//builder.Services.Configure<IdentityOptions>(options =>
|
|
//{
|
|
// options.SignIn.RequireConfirmedEmail = true;
|
|
// options.User.RequireUniqueEmail = true;
|
|
//});
|
|
|
|
builder.Services.ConfigureApplicationCookie(options =>
|
|
{
|
|
options.SlidingExpiration = true;
|
|
options.ExpireTimeSpan = TimeSpan.FromDays(3);
|
|
});
|
|
|
|
} |