mirror of
https://github.com/zoriya/Kyoo.git
synced 2025-05-24 02:02:36 -04:00
171 lines
5.5 KiB
C#
171 lines
5.5 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using IdentityServer4.Extensions;
|
|
using IdentityServer4.Services;
|
|
using Kyoo.Authentication.Models;
|
|
using Kyoo.Controllers;
|
|
using Microsoft.AspNetCore.Authentication.JwtBearer;
|
|
using Microsoft.AspNetCore.Authorization;
|
|
using Microsoft.AspNetCore.Builder;
|
|
using Microsoft.AspNetCore.Http;
|
|
using Microsoft.AspNetCore.Identity;
|
|
using Microsoft.Extensions.Configuration;
|
|
using Microsoft.Extensions.DependencyInjection;
|
|
using Microsoft.Extensions.Logging;
|
|
|
|
namespace Kyoo.Authentication
|
|
{
|
|
/// <summary>
|
|
/// A module that enable OpenID authentication for Kyoo.
|
|
/// </summary>
|
|
public class AuthenticationModule : IPlugin
|
|
{
|
|
/// <inheritdoc />
|
|
public string Slug => "auth";
|
|
|
|
/// <inheritdoc />
|
|
public string Name => "Authentication";
|
|
|
|
/// <inheritdoc />
|
|
public string Description => "Enable OpenID authentication for Kyoo.";
|
|
|
|
/// <inheritdoc />
|
|
public ICollection<Type> Provides => ArraySegment<Type>.Empty;
|
|
|
|
/// <inheritdoc />
|
|
public ICollection<ConditionalProvide> ConditionalProvides => ArraySegment<ConditionalProvide>.Empty;
|
|
|
|
/// <inheritdoc />
|
|
public ICollection<Type> Requires => ArraySegment<Type>.Empty;
|
|
|
|
|
|
/// <summary>
|
|
/// The configuration to use.
|
|
/// </summary>
|
|
private readonly IConfiguration _configuration;
|
|
|
|
/// <summary>
|
|
/// A logger factory to allow IdentityServer to log things.
|
|
/// </summary>
|
|
private readonly ILoggerFactory _loggerFactory;
|
|
|
|
|
|
/// <summary>
|
|
/// Create a new authentication module instance and use the given configuration and environment.
|
|
/// </summary>
|
|
/// <param name="configuration">The configuration to use</param>
|
|
/// <param name="loggerFactory">The logger factory to allow IdentityServer to log things</param>
|
|
public AuthenticationModule(IConfiguration configuration, ILoggerFactory loggerFactory)
|
|
{
|
|
_configuration = configuration;
|
|
_loggerFactory = loggerFactory;
|
|
}
|
|
|
|
/// <inheritdoc />
|
|
public IServiceCollection Configure(IServiceCollection services, ICollection<Type> availableTypes)
|
|
{
|
|
string publicUrl = _configuration.GetValue<string>("public_url");
|
|
|
|
// services.AddDbContext<IdentityDatabase>(options =>
|
|
// {
|
|
// options.UseNpgsql(_configuration.GetDatabaseConnection("postgres"));
|
|
// });
|
|
|
|
// services.AddIdentityCore<User>(o =>
|
|
// {
|
|
// o.Stores.MaxLengthForKeys = 128;
|
|
// })
|
|
// .AddSignInManager()
|
|
// .AddDefaultTokenProviders()
|
|
// .AddEntityFrameworkStores<IdentityDatabase>();
|
|
|
|
CertificateOption certificateOptions = new();
|
|
_configuration.GetSection(CertificateOption.Path).Bind(certificateOptions);
|
|
services.AddIdentityServer(options =>
|
|
{
|
|
options.IssuerUri = publicUrl;
|
|
options.UserInteraction.LoginUrl = publicUrl + "login";
|
|
options.UserInteraction.ErrorUrl = publicUrl + "error";
|
|
options.UserInteraction.LogoutUrl = publicUrl + "logout";
|
|
})
|
|
// .AddAspNetIdentity<User>()
|
|
// .AddConfigurationStore(options =>
|
|
// {
|
|
// options.ConfigureDbContext = builder =>
|
|
// builder.UseNpgsql(_configuration.GetDatabaseConnection("postgres"),
|
|
// sql => sql.MigrationsAssembly(assemblyName));
|
|
// })
|
|
// .AddOperationalStore(options =>
|
|
// {
|
|
// options.ConfigureDbContext = builder =>
|
|
// builder.UseNpgsql(_configuration.GetDatabaseConnection("postgres"),
|
|
// sql => sql.MigrationsAssembly(assemblyName));
|
|
// options.EnableTokenCleanup = true;
|
|
// })
|
|
.AddInMemoryIdentityResources(IdentityContext.GetIdentityResources())
|
|
.AddInMemoryApiScopes(IdentityContext.GetScopes())
|
|
.AddInMemoryApiResources(IdentityContext.GetApis())
|
|
// .AddProfileService<AccountController>()
|
|
.AddSigninKeys(certificateOptions);
|
|
|
|
services.AddAuthentication(o =>
|
|
{
|
|
o.DefaultScheme = IdentityConstants.ApplicationScheme;
|
|
o.DefaultSignInScheme = IdentityConstants.ExternalScheme;
|
|
})
|
|
.AddIdentityCookies(_ => { });
|
|
services.AddAuthentication()
|
|
.AddJwtBearer(options =>
|
|
{
|
|
options.Authority = publicUrl;
|
|
options.Audience = "Kyoo";
|
|
options.RequireHttpsMetadata = false;
|
|
});
|
|
|
|
services.AddAuthorization(options =>
|
|
{
|
|
AuthorizationPolicyBuilder scheme = new(IdentityConstants.ApplicationScheme,
|
|
JwtBearerDefaults.AuthenticationScheme);
|
|
options.DefaultPolicy = scheme.RequireAuthenticatedUser().Build();
|
|
|
|
string[] permissions = {"Read", "Write", "Play", "Admin"};
|
|
foreach (string permission in permissions)
|
|
{
|
|
options.AddPolicy(permission, policy =>
|
|
{
|
|
policy.AuthenticationSchemes.Add(IdentityConstants.ApplicationScheme);
|
|
policy.AuthenticationSchemes.Add(JwtBearerDefaults.AuthenticationScheme);
|
|
policy.AddRequirements(new AuthorizationValidator(permission));
|
|
policy.RequireScope($"kyoo.{permission.ToLower()}");
|
|
});
|
|
}
|
|
});
|
|
services.AddSingleton<IAuthorizationHandler, AuthorizationValidatorHandler>();
|
|
|
|
DefaultCorsPolicyService cors = new(_loggerFactory.CreateLogger<DefaultCorsPolicyService>())
|
|
{
|
|
AllowedOrigins = {new Uri(publicUrl).GetLeftPart(UriPartial.Authority)}
|
|
};
|
|
services.AddSingleton<ICorsPolicyService>(cors);
|
|
return services;
|
|
}
|
|
|
|
/// <inheritdoc />
|
|
public void ConfigureAspNet(IApplicationBuilder app)
|
|
{
|
|
app.UseAuthorization();
|
|
|
|
app.UseCookiePolicy(new CookiePolicyOptions
|
|
{
|
|
MinimumSameSitePolicy = SameSiteMode.Strict
|
|
});
|
|
app.UseAuthentication();
|
|
app.Use((ctx, next) =>
|
|
{
|
|
ctx.SetIdentityServerOrigin(_configuration.GetValue<string>("public_url"));
|
|
return next();
|
|
});
|
|
app.UseIdentityServer();
|
|
}
|
|
}
|
|
} |