Files
Moonlight/Moonlight.Api/Startup/Startup.Auth.cs

110 lines
4.2 KiB
C#

using System.Security.Claims;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Moonlight.Api.Configuration;
using Moonlight.Api.Implementations;
using Moonlight.Api.Implementations.ApiKeyScheme;
using Moonlight.Api.Services;
namespace Moonlight.Api.Startup;
public partial class Startup
{
private static void AddAuth(WebApplicationBuilder builder)
{
var oidcOptions = new OidcOptions();
builder.Configuration.GetSection("Moonlight:Oidc").Bind(oidcOptions);
var apiKeyOptions = new ApiOptions();
builder.Configuration.GetSection("Moonlight:Api").Bind(apiKeyOptions);
builder.Services.AddOptions<ApiOptions>().BindConfiguration("Moonlight:Api");
builder.Services.AddScoped<UserAuthService>();
builder.Services.AddAuthentication("Main")
.AddPolicyScheme("Main", null, options =>
{
options.ForwardDefaultSelector += context => context.Request.Headers.Authorization.Count > 0 ? "ApiKey" : "Session";
})
.AddCookie("Session", null, options =>
{
options.Events.OnSigningIn += async context =>
{
var authService = context
.HttpContext
.RequestServices
.GetRequiredService<UserAuthService>();
var result = await authService.SyncAsync(context.Principal);
if (result)
context.Properties.IsPersistent = true;
else
context.Principal = new ClaimsPrincipal();
};
options.Events.OnValidatePrincipal += async context =>
{
var authService = context
.HttpContext
.RequestServices
.GetRequiredService<UserAuthService>();
var result = await authService.ValidateAsync(context.Principal);
if (!result)
context.RejectPrincipal();
};
options.Cookie = new CookieBuilder()
{
Name = "token",
Path = "/",
IsEssential = true,
SecurePolicy = CookieSecurePolicy.SameAsRequest
};
})
.AddOpenIdConnect("OIDC", "OpenID Connect", options =>
{
options.Authority = oidcOptions.Authority;
options.RequireHttpsMetadata = oidcOptions.RequireHttpsMetadata;
var scopes = oidcOptions.Scopes ?? ["openid", "email", "profile"];
options.Scope.Clear();
foreach (var scope in scopes)
options.Scope.Add(scope);
options.ResponseType = oidcOptions.ResponseType;
options.ClientId = oidcOptions.ClientId;
options.ClientSecret = oidcOptions.ClientSecret;
options.ClaimActions.MapJsonKey(ClaimTypes.Name, "name");
options.ClaimActions.MapJsonKey(ClaimTypes.Name, "preferred_username");
options.ClaimActions.MapJsonKey(ClaimTypes.Email, "email");
options.GetClaimsFromUserInfoEndpoint = true;
})
.AddScheme<ApiKeySchemeOptions, ApiKeySchemeHandler>("ApiKey", null, options =>
{
options.LookupCacheTime = TimeSpan.FromMinutes(apiKeyOptions.LookupCacheMinutes);
});
builder.Logging.AddFilter("Moonlight.Api.Implementations.ApiKeyScheme.ApiKeySchemeHandler", LogLevel.Warning);
builder.Services.AddSingleton<IAuthorizationHandler, PermissionAuthorizationHandler>();
builder.Services.AddSingleton<IAuthorizationPolicyProvider, PermissionPolicyProvider>();
}
private static void UseAuth(WebApplication application)
{
application.UseAuthentication();
application.UseAuthorization();
}
}