using Insight.Infrastructure.Entities; using Insight.Infrastructure.Services; using Microsoft.AspNetCore.Authentication.JwtBearer; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.HttpOverrides; using Microsoft.AspNetCore.Identity; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Primitives; using Microsoft.IdentityModel.Tokens; using Microsoft.Net.Http.Headers; using MongoDB.Bson; using System.Text; namespace Insight.Infrastructure; public static partial class ServiceExtensions { public static IServiceCollection AddTokenServices(this IServiceCollection services, IConfiguration configuration) { var options = new Models.TokenOptions( key: configuration.GetValue(Appsettings.Jwt.Key) ?? throw new Exception($"{Appsettings.Jwt.Key} value not set (appsettings)"), expires: configuration.GetValue(Appsettings.Jwt.Exp) ?? throw new Exception($"{Appsettings.Jwt.Exp} value not set (appsettings)"), audience: configuration.GetValue(Appsettings.Jwt.Audience) ?? throw new Exception($"{Appsettings.Jwt.Audience} value not set (appsettings)"), issuer: configuration.GetValue(Appsettings.Jwt.Issuer) ?? throw new Exception($"{Appsettings.Jwt.Issuer} value not set (appsettings)")); services.AddSingleton(options); services.AddTransient(); return services; } public static IServiceCollection AddProxyServices(this IServiceCollection services) { // add before routing services.Configure(options => { options.ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto; }); return services; } public static IServiceCollection AddRoutingServices(this IServiceCollection services) { // add after proxy services.AddRouting(options => { options.LowercaseUrls = true; }); return services; } public static IServiceCollection AddIdentityServices(this IServiceCollection services, IConfiguration configuration) { var connectionString = configuration.GetValue(Appsettings.Mongo.ConnectionString) ?? throw new Exception($"{Appsettings.Mongo.ConnectionString} value not set (appsettings)"); services.AddIdentity(options => { }) .AddMongoDbStores(connectionString, Settings.Database) .AddDefaultTokenProviders() .AddSignInManager(); return services; } public static IServiceCollection AddCustomAuthentication(this IServiceCollection services, IConfiguration configuration) { // REWRITE TO COOKIE ONLY FOR WEB services.AddAuthentication(options => { options.DefaultScheme = "Custom"; options.DefaultChallengeScheme = "Custom"; }) .AddCookie("Cookies", options => { //options.Cookie.Domain = "insight.webmatic.de"; options.Cookie.Name = "insight"; options.LoginPath = "/account/login"; options.LogoutPath = "/account/logout"; options.ExpireTimeSpan = TimeSpan.FromHours(1); options.SlidingExpiration = true; options.Events.OnRedirectToLogin = options => { if (options.Request.Path.StartsWithSegments("/api") && options.Response.StatusCode == 200) options.Response.StatusCode = 401; else options.Response.Redirect(options.RedirectUri); return Task.CompletedTask; }; }) .AddJwtBearer("Bearer", options => { options.RequireHttpsMetadata = false; options.SaveToken = true; options.TokenValidationParameters.ValidateActor = false; options.TokenValidationParameters.ValidAudience = configuration.GetSection("Jwt:Audience").Value; options.TokenValidationParameters.ValidateAudience = true; options.TokenValidationParameters.ValidIssuer = configuration.GetSection("Jwt:Issuer").Value; options.TokenValidationParameters.ValidateIssuer = true; options.TokenValidationParameters.IssuerSigningKey = new SymmetricSecurityKey( Encoding.UTF8.GetBytes(configuration.GetSection("Jwt:Key").Value ?? throw new Exception("Configuration for [Jwt:Key] not found")) ); options.TokenValidationParameters.ValidateIssuerSigningKey = true; options.TokenValidationParameters.ValidateLifetime = true; }) .AddPolicyScheme("Custom", "Custom", options => { options.ForwardDefaultSelector = context => { if (context.Request.Headers[HeaderNames.Authorization] is StringValues auth && auth.ToString().StartsWith("Bearer ")) return "Bearer"; else return "Cookies"; }; }); return services; } public static IServiceCollection AddBearerAuthentication(this IServiceCollection services, IConfiguration configuration) { services.AddAuthentication(options => { options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme; options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme; options.DefaultSignInScheme = JwtBearerDefaults.AuthenticationScheme; }) .AddJwtBearer(options => { options.RequireHttpsMetadata = false; options.SaveToken = true; options.TokenValidationParameters.ValidateActor = false; options.TokenValidationParameters.ValidAudience = configuration.GetValue(Appsettings.Jwt.Audience) ?? throw new Exception($"{Appsettings.Jwt.Audience} value not set (appsettings)"); options.TokenValidationParameters.ValidateAudience = true; options.TokenValidationParameters.ValidIssuer = configuration.GetValue(Appsettings.Jwt.Issuer) ?? throw new Exception($"{Appsettings.Jwt.Issuer} value not set (appsettings)"); options.TokenValidationParameters.ValidateIssuer = true; options.TokenValidationParameters.IssuerSigningKey = new SymmetricSecurityKey( Encoding.UTF8.GetBytes(configuration.GetValue(Appsettings.Jwt.Key) ?? throw new Exception($"{Appsettings.Jwt.Key} value not set (appsettings)")) ); options.TokenValidationParameters.ValidateIssuerSigningKey = true; options.TokenValidationParameters.ValidateLifetime = true; }); return services; } //private static IServiceCollection AddIdentityServices2(this IServiceCollection services, IConfiguration configuration) //{ // var identityOptions = new MongoDbIdentityConfiguration // { // MongoDbSettings = new MongoDbSettings // { // ConnectionString = configuration.GetSection("ConnectionStrings:Mongo").Value, // DatabaseName = "insight" // }, // IdentityOptionsAction = options => // { // options.User.RequireUniqueEmail = true; // options.User.AllowedUserNameCharacters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789@.-_"; // options.Password.RequireDigit = false; // options.Password.RequiredLength = 8; // options.Password.RequireNonAlphanumeric = false; // options.Password.RequireUppercase = false; // options.Password.RequireLowercase = false; // options.SignIn.RequireConfirmedAccount = false; // options.SignIn.RequireConfirmedEmail = false; // options.SignIn.RequireConfirmedPhoneNumber = false; // options.Lockout.MaxFailedAccessAttempts = 5; // options.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromMinutes(5); // } // }; // services.ConfigureMongoDbIdentity(identityOptions) // .AddDefaultTokenProviders() // .AddSignInManager(); // return services; //} //private static IServiceCollection AddIdentityAuthentication(this IServiceCollection services, IConfiguration configuration) //{ // services.AddAuthentication(options => // { // options.DefaultAuthenticateScheme = // }); // cookieBuilder.ApplicationCookie = builder.AddApplicationCookie(); // cookieBuilder.ExternalCookie = builder.AddExternalCookie(); // cookieBuilder.TwoFactorRememberMeCookie = builder.AddTwoFactorRememberMeCookie(); // cookieBuilder.TwoFactorUserIdCookie = builder.AddTwoFactorUserIdCookie(); // .AddCookie(options => // { // options. // }; // .AddIdentityCookies(); // .AddCookie(options => // { // // Specify where to redirect un-authenticated users // options.LoginPath = "/account/login"; // // Specify the name of the auth cookie. // // ASP.NET picks a dumb name by default. // options.Cookie.Name = "insight"; // }); // return services; //} }