Bump dependencies
This commit is contained in:
parent
29eb91c3b1
commit
1495cdda39
|
@ -1 +1 @@
|
||||||
Subproject commit b67ba4a1a6bb8a58ee44b34dbadbd6a0e99c5c87
|
Subproject commit 8b2e541cfe92c7bfaada6a95e427a3d6c92ce768
|
|
@ -1,9 +0,0 @@
|
||||||
<Project Sdk="Microsoft.NET.Sdk">
|
|
||||||
|
|
||||||
<PropertyGroup>
|
|
||||||
<TargetFramework>net6.0</TargetFramework>
|
|
||||||
<ImplicitUsings>enable</ImplicitUsings>
|
|
||||||
<Nullable>enable</Nullable>
|
|
||||||
</PropertyGroup>
|
|
||||||
|
|
||||||
</Project>
|
|
|
@ -1,278 +0,0 @@
|
||||||
using System;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using BlueWest.Domain;
|
|
||||||
using BlueWest.Domain;
|
|
||||||
using BlueWest.Cryptography;
|
|
||||||
using BlueWest.Data.Application.Users;
|
|
||||||
using BlueWest.Data.Auth;
|
|
||||||
using BlueWest.Data.Auth.Context.Users;
|
|
||||||
using BlueWest.WebApi.Configuration;
|
|
||||||
using BlueWest.WebApi.Context.Users;
|
|
||||||
using BlueWest.WebApi.Session;
|
|
||||||
using Microsoft.AspNetCore.Authentication.Cookies;
|
|
||||||
using Microsoft.AspNetCore.Authentication.JwtBearer;
|
|
||||||
using Microsoft.AspNetCore.Hosting;
|
|
||||||
using Microsoft.AspNetCore.Http;
|
|
||||||
using Microsoft.AspNetCore.Identity;
|
|
||||||
using Microsoft.EntityFrameworkCore;
|
|
||||||
using Microsoft.Extensions.Configuration;
|
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
|
||||||
using Microsoft.Extensions.Hosting;
|
|
||||||
using Microsoft.Extensions.Logging;
|
|
||||||
using Microsoft.IdentityModel.Tokens;
|
|
||||||
using Redis.OM;
|
|
||||||
|
|
||||||
namespace BlueWest.Startyp
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Startup Extensions
|
|
||||||
/// </summary>
|
|
||||||
public static class StartupExtensions
|
|
||||||
{
|
|
||||||
private static MySqlServerVersion GetMySqlServerVersion(int major, int minor, int build) => new (new Version(major, minor, build));
|
|
||||||
|
|
||||||
private static BlueWestConnectionString GetConnectionString(this IConfigurationRoot configurationRoot)
|
|
||||||
{
|
|
||||||
// Docker / No-Docker
|
|
||||||
var startupMode = configurationRoot["mode"];
|
|
||||||
|
|
||||||
if (startupMode == "docker")
|
|
||||||
{
|
|
||||||
var config = configurationRoot.Get<ConnectionStringDocker>();
|
|
||||||
return config;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
var config = configurationRoot.Get<ConnectionStringNoDocker>();
|
|
||||||
return config;
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Get MYSQL Connection String
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="optionsBuilder"></param>
|
|
||||||
/// <param name="configuration"></param>
|
|
||||||
/// <param name="environment"></param>
|
|
||||||
private static DbContextOptionsBuilder GetMySqlSettings(
|
|
||||||
this DbContextOptionsBuilder optionsBuilder,
|
|
||||||
IConfiguration configuration,
|
|
||||||
IConfigurationRoot configurationRoot,
|
|
||||||
IWebHostEnvironment environment)
|
|
||||||
{
|
|
||||||
var sqlVersion = GetMySqlServerVersion(8, 0, 11);
|
|
||||||
|
|
||||||
// Docker / No-Docker
|
|
||||||
|
|
||||||
string mySqlConnectionString = configurationRoot.GetConnectionString().MySql;
|
|
||||||
|
|
||||||
if (mySqlConnectionString == string.Empty)
|
|
||||||
{
|
|
||||||
throw new InvalidOperationException("Fatal error: MySQL Connection string is empty.");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
optionsBuilder
|
|
||||||
.UseMySql(
|
|
||||||
mySqlConnectionString,
|
|
||||||
sqlVersion)
|
|
||||||
.UseMySql(sqlVersion,
|
|
||||||
builder =>
|
|
||||||
{
|
|
||||||
builder.EnableRetryOnFailure(6, TimeSpan.FromSeconds(3), null);
|
|
||||||
});
|
|
||||||
|
|
||||||
// The following three options help with debugging, but should
|
|
||||||
// be changed or removed for production.
|
|
||||||
if (environment.IsDevelopment())
|
|
||||||
{
|
|
||||||
optionsBuilder
|
|
||||||
.LogTo(Console.WriteLine, LogLevel.Information)
|
|
||||||
.EnableSensitiveDataLogging()
|
|
||||||
.EnableDetailedErrors();
|
|
||||||
}
|
|
||||||
|
|
||||||
return optionsBuilder;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Setup database Contexts
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="serviceCollection"></param>
|
|
||||||
/// <param name="configuration"></param>
|
|
||||||
/// <param name="environment"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
public static IServiceCollection PrepareMySqlDatabasePool(this IServiceCollection serviceCollection,
|
|
||||||
IConfiguration configuration, IWebHostEnvironment environment, IConfigurationRoot configurationRoot)
|
|
||||||
{
|
|
||||||
return serviceCollection
|
|
||||||
.AddDbContextPool<UserDbContext>(options =>
|
|
||||||
options.GetMySqlSettings(configuration, configurationRoot, environment))
|
|
||||||
.AddDbContextPool<CountryDbContext>(options =>
|
|
||||||
options.GetMySqlSettings(configuration, configurationRoot, environment))
|
|
||||||
.AddDbContextPool<FinanceDbContext>(options =>
|
|
||||||
options.GetMySqlSettings(configuration, configurationRoot, environment))
|
|
||||||
.AddDbContextPool<CompanyDbContext>(options =>
|
|
||||||
options.GetMySqlSettings(configuration, configurationRoot, environment))
|
|
||||||
.AddDbContextPool<ApplicationUserDbContext>(options =>
|
|
||||||
options.GetMySqlSettings(configuration, configurationRoot, environment));
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Setup database Contexts
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="serviceCollection"></param>
|
|
||||||
/// <param name="configuration"></param>
|
|
||||||
/// <param name="environment"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
public static IServiceCollection PrepareSqlLiteDatabasePool(this IServiceCollection serviceCollection,
|
|
||||||
IConfiguration configuration, IWebHostEnvironment environment)
|
|
||||||
{
|
|
||||||
var sqliteConString = "Data Source=BlueWest.Api.db";
|
|
||||||
|
|
||||||
return serviceCollection
|
|
||||||
.AddDbContextPool<UserDbContext>(options => options.UseSqlite(sqliteConString))
|
|
||||||
.AddDbContextPool<CountryDbContext>(options => options.UseSqlite(sqliteConString))
|
|
||||||
.AddDbContextPool<FinanceDbContext>(options => options.UseSqlite(sqliteConString))
|
|
||||||
.AddDbContextPool<CompanyDbContext>(options => options.UseSqlite(sqliteConString))
|
|
||||||
.AddDbContextPool<ApplicationUserDbContext>(options => options.UseSqlite(sqliteConString));
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
internal static IServiceCollection AddAuthServerServices(this IServiceCollection services, IConfiguration configuration , IWebHostEnvironment environment, IConfigurationRoot configurationRoot)
|
|
||||||
{
|
|
||||||
|
|
||||||
var connectionString = configurationRoot.GetConnectionString();
|
|
||||||
|
|
||||||
if (connectionString == null)
|
|
||||||
{
|
|
||||||
throw new InvalidOperationException("Redis connection string is empty");
|
|
||||||
}
|
|
||||||
|
|
||||||
services
|
|
||||||
.AddSingleton(new RedisConnectionProvider(connectionString.Redis))
|
|
||||||
.AddScoped<IJwtTokenHandler, JwtTokenHandler>()
|
|
||||||
.AddScoped<IJwtFactory, JwtFactory>()
|
|
||||||
.AddHostedService<SessionManager>()
|
|
||||||
.AddSingleton<ISessionCache, SessionManager>()
|
|
||||||
.AddScoped<UserRepository>()
|
|
||||||
.AddScoped<IUserManager, ApplicationUserManager>()
|
|
||||||
.AddScoped<IAuthManager, AuthManager>()
|
|
||||||
.AddScoped<IHasher, Hasher>();
|
|
||||||
|
|
||||||
// Database Context and Swagger
|
|
||||||
|
|
||||||
|
|
||||||
// Register the ConfigurationBuilder instance of AuthSettings
|
|
||||||
var authSettings = configuration.GetSection(nameof(AuthSettings));
|
|
||||||
services.Configure<AuthSettings>(authSettings);
|
|
||||||
var signingKey = new SymmetricSecurityKey
|
|
||||||
(Encoding.ASCII.GetBytes(authSettings[nameof(AuthSettings.SecretKey)]));
|
|
||||||
|
|
||||||
// jwt wire up
|
|
||||||
// Get options from app settings
|
|
||||||
var jwtAppSettingOptions = configuration
|
|
||||||
.GetSection(nameof(JwtIssuerOptions));
|
|
||||||
|
|
||||||
// Configure JwtIssuerOptions
|
|
||||||
services.Configure<JwtIssuerOptions>(options =>
|
|
||||||
{
|
|
||||||
options.Issuer = jwtAppSettingOptions[nameof(JwtIssuerOptions.Issuer)];
|
|
||||||
options.Audience = jwtAppSettingOptions[nameof(JwtIssuerOptions.Audience)];
|
|
||||||
options.SigningCredentials = new SigningCredentials
|
|
||||||
(signingKey, SecurityAlgorithms.HmacSha256);
|
|
||||||
});
|
|
||||||
|
|
||||||
var tokenValidationParameters = new TokenValidationParameters
|
|
||||||
{
|
|
||||||
ValidateIssuer = true,
|
|
||||||
ValidIssuer = jwtAppSettingOptions[nameof(JwtIssuerOptions.Issuer)],
|
|
||||||
|
|
||||||
ValidateAudience = true,
|
|
||||||
ValidAudience = jwtAppSettingOptions[nameof(JwtIssuerOptions.Audience)],
|
|
||||||
|
|
||||||
ValidateIssuerSigningKey = true,
|
|
||||||
IssuerSigningKey = signingKey,
|
|
||||||
|
|
||||||
RequireExpirationTime = false,
|
|
||||||
ValidateLifetime = true,
|
|
||||||
ClockSkew = TimeSpan.Zero
|
|
||||||
};
|
|
||||||
|
|
||||||
services.AddAuthentication(options =>
|
|
||||||
{
|
|
||||||
|
|
||||||
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
|
|
||||||
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
|
|
||||||
options.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
|
|
||||||
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
|
|
||||||
options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
|
|
||||||
})
|
|
||||||
.AddCookie(options =>
|
|
||||||
{
|
|
||||||
options.Cookie.SameSite = SameSiteMode.Lax;
|
|
||||||
options.Cookie.SecurePolicy = CookieSecurePolicy.SameAsRequest;
|
|
||||||
options.Cookie.MaxAge = SessionConstants.DefaultSessionMaxAge;
|
|
||||||
options.LoginPath = "/api/auth/logincookie";
|
|
||||||
options.LogoutPath = "/api/auth/logout";
|
|
||||||
})
|
|
||||||
.AddJwtBearer(configureOptions =>
|
|
||||||
{
|
|
||||||
configureOptions.ClaimsIssuer = jwtAppSettingOptions[nameof(JwtIssuerOptions.Issuer)];
|
|
||||||
configureOptions.TokenValidationParameters = tokenValidationParameters;
|
|
||||||
configureOptions.SaveToken = true;
|
|
||||||
|
|
||||||
configureOptions.Events = new JwtBearerEvents
|
|
||||||
{
|
|
||||||
OnAuthenticationFailed = context =>
|
|
||||||
{
|
|
||||||
if (context.Exception.GetType() == typeof(SecurityTokenExpiredException))
|
|
||||||
{
|
|
||||||
context.Response.Headers.Add("Token-Expired", "true");
|
|
||||||
}
|
|
||||||
|
|
||||||
return Task.CompletedTask;
|
|
||||||
},
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
// api user claim policy
|
|
||||||
services.AddAuthorization(options =>
|
|
||||||
{
|
|
||||||
options.AddPolicy(SessionConstants.ApiNamePolicy,
|
|
||||||
policy => policy.RequireClaim(Data.Auth.Context.Users.Constants.JwtClaimIdentifiers.Rol,
|
|
||||||
Data.Auth.Context.Users.Constants.JwtClaims.ApiAccess));
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
// add identity
|
|
||||||
var identityBuilder = services.AddIdentityCore<ApplicationUser>(o =>
|
|
||||||
{
|
|
||||||
o.User.RequireUniqueEmail = true;
|
|
||||||
|
|
||||||
// configure identity options
|
|
||||||
o.Password.RequireDigit = false;
|
|
||||||
o.Password.RequireLowercase = false;
|
|
||||||
o.Password.RequireUppercase = false;
|
|
||||||
o.Password.RequireNonAlphanumeric = false;
|
|
||||||
o.Password.RequiredLength = 6;
|
|
||||||
})
|
|
||||||
.AddUserManager<ApplicationUserManager>()
|
|
||||||
.AddUserStore<UserRepository>();
|
|
||||||
|
|
||||||
identityBuilder = new IdentityBuilder(identityBuilder.UserType, typeof(ApplicationRole), identityBuilder.Services);
|
|
||||||
identityBuilder
|
|
||||||
.AddEntityFrameworkStores<ApplicationUserDbContext>()
|
|
||||||
.AddDefaultTokenProviders();
|
|
||||||
|
|
||||||
return services;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
Subproject commit f999ac592914792df3150d3513d1ba91496fbcdf
|
Subproject commit 05eef7070f990d692151d535564eaf6dc25d1ab8
|
Loading…
Reference in New Issue