AuthServer¶
- Install
GridLab.Abp.Security.Providers.DockerSecrets
module.
<ItemGroup>
<PackageReference Include="GridLab.Abp.Security.Providers.DockerSecrets" Version="X.Y.Z" />
</ItemGroup>
Replace version number with latest available.
Extend dependency list at PSSXAuthServerModule.cs
[DependsOn(
//...other dependencies
typeof(AbpZeroTrustModule),
//
typeof(PSSXEntityFrameworkCoreModule)
)]
public class PSSXAuthServerModule : AbpModule
{
}
.NET Core configuration provider extensions allows reading docker secrets files and pull them into the .net core configuration.
builder.Host
.UseAutofac()
....
.UseSerilog((context, services, loggerConfiguration) =>
{
loggerConfiguration
#if DEBUG
.MinimumLevel.Debug()
.MinimumLevel.Override("DockerSecrets", LogEventLevel.Debug)
#else
.MinimumLevel.Information()
.MinimumLevel.Override("DockerSecrets", LogEventLevel.Information)
#endif
.MinimumLevel.Override("Microsoft", LogEventLevel.Information)
.MinimumLevel.Override("Microsoft.EntityFrameworkCore", LogEventLevel.Warning)
.WriteTo.Async(c => c.Console())
})
....
.ConfigureAppConfiguration((context, config) => {
if (!context.HostingEnvironment.IsDevelopment())
{
config.AddDockerSecrets(
options: () => new DockerSecretsConfigurationOptions
{
ColonPlaceholder = "__"
},
secretsPath: "/run/secrets",
logger: new SerilogLoggerProvider(Log.Logger).CreateLogger("DockerSecrets")
);
}
})
....
- Add Hangfire support.
Install GridLab.Abp.Hangfire
module.
<ItemGroup>
<PackageReference Include="GridLab.Abp.Hangfire" Version="X.Y.Z" />
</ItemGroup>
Replace version number with latest available.
Add the AbpHangfireModule to the dependency list of your module:
[DependsOn(
//...other dependencies
typeof(AbpHangfireModule)
)]
public class PSSXAuthServerModule : AbpModule
{
}
Configure Hangfire module;
public override void ConfigureServices(ServiceConfigurationContext context)
{
string serverName = configuration["Hangfire:ServerName"] ?? "pssx-auth-server";
string schemaName = configuration["Hangfire:SchemaName"] ?? string.Empty;
string? connectionString = configuration.GetConnectionString(PSSXDbProperties.ConnectionStringHangfireName);
if (connectionString.IsNullOrEmpty())
throw new ArgumentNullException(paramName: PSSXDbProperties.ConnectionStringHangfireName);
var serverStorageOptions = new EFCoreStorageOptions
{
CountersAggregationInterval = new TimeSpan(0, 5, 0),
DistributedLockTimeout = new TimeSpan(0, 10, 0),
JobExpirationCheckInterval = new TimeSpan(0, 30, 0),
QueuePollInterval = new TimeSpan(0, 0, 15),
Schema = schemaName,
SlidingInvisibilityTimeout = new TimeSpan(0, 5, 0),
};
var options = new DbContextOptionsBuilder<PSSXHangfireDbContext>()
.UseSqlServer(connectionString)
.Options;
GlobalConfiguration.Configuration.UseEFCoreStorage(
() => new PSSXHangfireDbContext(options, schemaName),
serverStorageOptions
);
Configure<AbpHangfireOptions>(options =>
{
options.Storage = EFCoreStorage.Current;
options.ServerOptions = new BackgroundJobServerOptions() { ServerName = serverName };
});
}
Add a new section for hangfire to application configuration settings.
"Hangfire": {
"ServerName": "pssx-auth-server"
},
Make sure you have updated your connection strings defined under ConnectionString at appsettings.json
file.
"ConnectionStrings": {
...
"Hangfire": "Server=(localdb)\\MSSQLLocalDB;Database=pssx-hangfire;Trusted_Connection=True;TrustServerCertificate=true"
}
- The versions of npm packages defined in
package.json
should be checked, where extra npm packages to be used in mvc ui should be defined.
{
"version": "0.1.0",
"name": "my-app-authserver",
"private": true,
"dependencies": {
"@volo/abp.aspnetcore.mvc.ui.theme.lepton": "~8.2.0",
"@volo/account": "~8.2.0"
}
}
add extra packages if necessary
{
"version": "0.1.0",
"name": "my-app-authserver",
"private": true,
"dependencies": {
"@volo/abp.aspnetcore.mvc.ui.theme.lepton": "~8.2.0",
"@volo/account": "~8.2.0",
"ace-builds": "^1.4.12",
"bootstrap-markdown-editor-4": "^3.0.0",
"jquery-datetimepicker": "^2.5.21",
"moment": "^2.29.1"
}
}
In order to run abp install-libs
automation scripts, a definition must be made in abp.resourcemapping.js
.
module.exports = {
aliases: {
"@node_modules": "./node_modules",
"@libs": "./wwwroot/libs"
},
clean: [
"@libs",
"!@libs/**/foo.txt"
],
mappings: {
"@node_modules/bootstrap-markdown-editor-4/dist/css/bootstrap-markdown-editor.min.css": "@libs/bootstrap-markdown-editor-4/css/",
"@node_modules/bootstrap-markdown-editor-4/dist/js/bootstrap-markdown-editor.min.js": "@libs/bootstrap-markdown-editor-4/js/",
"@node_modules/ace-builds/src-noconflict/ace.js": "@libs/ace/",
"@node_modules/ace-builds/src-noconflict/theme-tomorrow.js": "@libs/ace/",
"@node_modules/ace-builds/src-noconflict/mode-markdown.js": "@libs/ace/",
"@node_modules/ace-builds/src-noconflict/ext-language_tools.js": "@libs/ace/",
"@node_modules/moment/moment.js": "@libs/moment/",
"@node_modules/jquery-datetimepicker/jquery.datetimepicker.js": "@libs/jquery-datetimepicker/",
"@node_modules/jquery-datetimepicker/jquery.datetimepicker.css": "@libs/jquery-datetimepicker/",
}
};
Clean wwwroot/libs
and node_modules
folders for clean installation. This is required action for abp install-libs
script.
ABP CLI's abp install-libs command copies resources from node_modules to wwwroot/libs folder. Each standard package (see the @ABP NPM Packages section) defines the mapping for its own files. So, most of the time, you only configure dependencies.
- Activate clock at
PSSXAuthServerModule.cs
, defaultKind
isUnspecified
that actually make the Clock as it doesn't exists at all.
public override void ConfigureServices(ServiceConfigurationContext context)
{
Configure<AbpClockOptions>(options =>
{
options.Kind = DateTimeKind.Utc;
});
}
- Add the following MSBuild instruction to your
GridLab.PSSX.AuthServer.csproj
file in order to load .pdb files during debugging.
<Target Name="_ResolveCopyLocalNuGetPackagePdbs" Condition="$(CopyLocalLockFileAssemblies) == true" AfterTargets="ResolveReferences">
<ItemGroup>
<ReferenceCopyLocalPaths Include="@(ReferenceCopyLocalPaths->'%(RootDir)%(Directory)%(Filename).pdb')" Condition="'%(ReferenceCopyLocalPaths.NuGetPackageId)' != '' and Exists('%(RootDir)%(Directory)%(Filename).pdb')" />
</ItemGroup>
</Target>
- Configure
OpenIddict
library
Add GetSigningCertificate
and GetEncryptionCertificate
certificate method for handling certificates.
using GridLab.Abp.ZeroTrust;
private X509Certificate2 GetSigningCertificate(ServiceConfigurationContext context, IConfiguration configuration)
{
var certificateFactory = context.Services.GetCertificateFactory();
return certificateFactory.CreateFromPkcs12File(
configuration["App:Certificates:Signing:Path"],
configuration["App:Certificates:Signing:CertPassphrase"]
);
}
using GridLab.Abp.ZeroTrust;
private X509Certificate2 GetEncryptionCertificate(ServiceConfigurationContext context, IConfiguration configuration)
{
var certificateFactory = context.Services.GetCertificateFactory();
return certificateFactory.CreateFromPkcs12File(
configuration["App:Certificates:Encryption:Path"],
configuration["App:Certificates:Encryption:CertPassphrase"]
);
}
Add GetIssuer
and GetAccessTokenLifetime
specific library options methods.
private string GetIssuer(IConfiguration configuration)
{
// Solves bearer was not authenticated. Failure message: IDX10205: Issuer validation failed.
var issuer = configuration["App:Issuer"]?.Trim();
var selfUrl = configuration["App:SelfUrl"]?.Trim();
if (!string.IsNullOrEmpty(issuer))
return issuer;
if (!string.IsNullOrEmpty(selfUrl))
return selfUrl;
throw new InvalidOperationException("Neither App:Issuer nor App:SelfUrl is provided in configuration.");
}
private TimeSpan GetAccessTokenLifetime(IConfiguration configuration)
{
var accessTokenLifetimeString = configuration["App:AccessTokenLifetime"]?.Trim();
var defaultAccessTokenLifetime = TimeSpan.FromHours(1); // Define a default fallback value (1 hour)
if (TimeSpan.TryParse(accessTokenLifetimeString, out var accessTokenLifetime))
return accessTokenLifetime;
return defaultAccessTokenLifetime;
}
- Configure caching.
Replace Volo.Abp.Caching.StackExchangeRedis
with GridLab.Abp.Caching.StackExchangeValkey
module.
Remove:
<ItemGroup>
<PackageReference Include="Volo.Abp.Caching.StackExchangeRedis" Version="X.Y.Z" />
</ItemGroup>
Add:
<ItemGroup>
<PackageReference Include="GridLab.Abp.Caching.StackExchangeValkey" Version="X.Y.Z" />
</ItemGroup>
Replace package at PSSXAuthServerModule.cs
[DependsOn(
//...other dependencies
~~typeof(AbpStackExchangeRedisModule),~~
typeof(AbpStackExchangeValkeyModule),
//
typeof(PSSXEntityFrameworkCoreModule)
)]
public class PSSXAuthServerModule : AbpModule
{
}
Add GetRedisConnectionMultiplexer
method for handling cache connections.
private ConnectionMultiplexer GetRedisConnectionMultiplexer(
ServiceConfigurationContext context,
IConfiguration configuration)
{
var valkeyConfiguration = configuration["Valkey:Configuration"]!;
var valkeyOptions = ConfigurationOptions.Parse(valkeyConfiguration);
valkeyOptions.Password = configuration["Valkey:Connections:Password"];
if (configuration.GetValue<bool>("Valkey:Connections:Ssl:IsEnabled", false))
{
var certificateFactory = context.Services.GetCertificateFactory();
var certificateValidation = context.Services.GetCertificateValidationService();
valkeyOptions.Ssl = true;
valkeyOptions.SslHost = configuration["Valkey:Connections:Ssl:Host"];
valkeyOptions.SslProtocols = SslProtocols.Tls12 | SslProtocols.Tls13;
if (!configuration["Valkey:Connections:Ssl:CertPath"].IsNullOrEmpty())
{
certificateFactory.CreateFromPkcs12File(
configuration["Valkey:Connections:Ssl:CertPath"],
configuration["Valkey:Connections:Ssl:CertPassphrase"]
);
}
// Client side certificate selection, this is going to be used when the server requests validation
valkeyOptions.CertificateSelection += (sender, host, certificates, certificate, issuers) =>
{
return certificateValidation.LocalCertificateSelectionCallback(sender, host, certificateFactory.Certs, certificate, issuers)!;
};
// Server side certificate validation
valkeyOptions.CertificateValidation += (sender, certificate, chain, sslPolicyErrors) =>
{
// You can control which type validation errors are acceptable
return certificateValidation.RemoteCertificateValidationCallback(sender, certificate, chain, sslPolicyErrors);
};
}
return ConnectionMultiplexer.Connect(valkeyOptions);
}
Add a new section for caching to application configuration settings.
"Valkey": {
"Configuration": "127.0.0.1",
"Connections": {
"Password": "",
"Ssl": {
"IsEnabled": "false"
}
}
},
- Add new
PSSXBrandingProvider.cs
cs file to project root directory atGridLab.PSSX.AuthServer
project.
Copy the wwwroot
folder from template folder to the src/GridLab.PSSX.AuthServer
folder.
Delete existing logo-dark.png
and logo-dark.png
logos
[Dependency(ReplaceServices = true)]
public class PSSXBrandingProvider : DefaultBrandingProvider
{
private IStringLocalizer<PSSXResource> _localizer;
public PSSXBrandingProvider(IStringLocalizer<PSSXResource> localizer)
{
_localizer = localizer;
}
public override string AppName => "PSSX Auth Server";
public override string LogoUrl => "/images/logo/leptonx/logo-light.png";
public override string LogoReverseUrl => "/images/logo/leptonx/logo-dark.png";
}