Hi @maliming,
I have used below code for Azure configuration. I have tried by adding below code in Domain, Application & APIHost module.
Configure<AbpBlobStoringOptions>(options =>
{
options.Containers.ConfigureDefault(c =>
{
c.UseAzure(container =>
{
container.ConnectionString = configuration["Azure:BlobConnectionString"];
container.ContainerName = configuration["Azure:BlobContainerName"];
container.CreateContainerIfNotExists = true;
});
})
options.Containers.Configure<FileManagementContainer>(c =>
{
//c.UseDatabase();
c.UseAzure(container =>
{
container.ConnectionString = configuration["Azure:BlobConnectionString"];
container.ContainerName = configuration["Azure:BlobContainerName"];
container.CreateContainerIfNotExists = true;
// Add other configurations as needed
});
});
});
Hello,
Thank you for support
I need a login URL and send an email include the URL. Users should click on the login url from email and redirect to the login page with the selected tenant.
Thanks
Hi Engincan, Thank you for your reply.
Yes I am removing the duplicate dbset for now.
Please also check because I am also getting an error if I generate the unit test for an existing entity which were created before upgrade.
I am not reopening the ticket, but please try to follow the same steps with generating unit test and you will get the error. Please keep track of it with your internal issue too.
Thank you.
Hi Engincan, Thank you for your reply. Please follow the below steps
Thank you.
Hi EngincanV, do you have any update on this?
Thank you.
Hi
It's not working for me this code
Configure<AbpAspNetCoreMultiTenancyOptions>(options =>
{
options.MultiTenancyMiddlewareErrorPageBuilder = async (httpContext, exception) =>
{
foreach (var cookie in httpContext.Request.Cookies)
{
httpContext.Response.Cookies.Delete(cookie.Key);
}
httpContext.Response.Redirect(httpContext.Request.GetEncodedPathAndQuery());
return true;
};
});
I have follow all steps from your video. thank you
Hi,
Thank you for support. I shared steps to reproduce:
Thank you
my last logs of authserver
2023-10-20 08:14:34.720 -06:00 [INF] Starting BOMS.AuthServer. 2023-10-20 08:14:35.278 -06:00 [FTL] BOMS.AuthServer terminated unexpectedly! Volo.Abp.AbpInitializationException: An error occurred during ConfigureServicesAsync phase of the module Volo.Abp.OpenIddict.AbpOpenIddictAspNetCoreModule, Volo.Abp.OpenIddict.AspNetCore, Version=7.4.0.0, Culture=neutral, PublicKeyToken=null. See the inner exception for details. ---> System.Security.Cryptography.CryptographicException: Access denied. at System.Security.Cryptography.X509Certificates.CertificatePal.FilterPFXStore(ReadOnlySpan
1 rawData, SafePasswordHandle password, PfxCertStoreFlags pfxCertStoreFlags)
at System.Security.Cryptography.X509Certificates.CertificatePal.FromBlobOrFile(ReadOnlySpan1 rawData, String fileName, SafePasswordHandle password, X509KeyStorageFlags keyStorageFlags) at System.Security.Cryptography.X509Certificates.X509Certificate..ctor(String fileName, String password, X509KeyStorageFlags keyStorageFlags) at BOMS.BOMSAuthServerModule.GetSigningCertificate(IWebHostEnvironment hostingEnv, IConfiguration configuration) in C:\BOMS\aspnet-core\src\BOMS.AuthServer\BOMSAuthServerModule.cs:line 309 at BOMS.BOMSAuthServerModule.<>c__DisplayClass0_0.<PreConfigureServices>b__2(OpenIddictServerBuilder builder) in C:\BOMS\aspnet-core\src\BOMS.AuthServer\BOMSAuthServerModule.cs:line 96 at Volo.Abp.Options.PreConfigureActionList
1.Configure(TOptions options)
at Microsoft.Extensions.DependencyInjection.ServiceCollectionPreConfigureExtensions.ExecutePreConfiguredActions[TOptions](IServiceCollection services, TOptions options)
at Volo.Abp.OpenIddict.AbpOpenIddictAspNetCoreModule.<>c__DisplayClass1_0.<AddOpenIddictServer>b__0(OpenIddictServerBuilder builder)
at Microsoft.Extensions.DependencyInjection.OpenIddictServerExtensions.AddServer(OpenIddictBuilder builder, Action1 configuration) at Volo.Abp.OpenIddict.AbpOpenIddictAspNetCoreModule.AddOpenIddictServer(IServiceCollection services) at Volo.Abp.OpenIddict.AbpOpenIddictAspNetCoreModule.ConfigureServices(ServiceConfigurationContext context) at Volo.Abp.Modularity.AbpModule.ConfigureServicesAsync(ServiceConfigurationContext context) at Volo.Abp.AbpApplicationBase.ConfigureServicesAsync() --- End of inner exception stack trace --- at Volo.Abp.AbpApplicationBase.ConfigureServicesAsync() at Volo.Abp.AbpApplicationFactory.CreateAsync[TStartupModule](IServiceCollection services, Action
1 optionsAction)
at Microsoft.Extensions.DependencyInjection.ServiceCollectionApplicationExtensions.AddApplicationAsync[TStartupModule](IServiceCollection services, Action1 optionsAction) at Microsoft.Extensions.DependencyInjection.WebApplicationBuilderExtensions.AddApplicationAsync[TStartupModule](WebApplicationBuilder builder, Action
1 optionsAction)
at BOMS.Program.Main(String[] args) in C:\BOMS\aspnet-core\src\BOMS.AuthServer\Program.cs:line 36
`
Hi anjali,
AuthServerModule.cs `using System; using System.IO; using System.Linq; using Localization.Resources.AbpUi; using Medallion.Threading; using Medallion.Threading.Redis; using Microsoft.AspNetCore.Authentication.Google; using Microsoft.AspNetCore.Authentication.MicrosoftAccount; using Microsoft.AspNetCore.Authentication.Twitter; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Cors; using Microsoft.AspNetCore.DataProtection; using Microsoft.AspNetCore.Extensions.DependencyInjection; using Volo.Abp.Caching.StackExchangeRedis; using Volo.Abp.DistributedLocking; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using BOMS.EntityFrameworkCore; using BOMS.Localization; using BOMS.MultiTenancy; using OpenIddict.Server.AspNetCore; using OpenIddict.Validation.AspNetCore; using StackExchange.Redis; using Volo.Abp; using Volo.Abp.Account; using Volo.Abp.Account.Public.Web; using Volo.Abp.Account.Public.Web.ExternalProviders; using Volo.Abp.Account.Web; using Volo.Abp.Account.Public.Web.Impersonation; using Volo.Abp.AspNetCore.Mvc.UI; using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap; using Volo.Abp.AspNetCore.Mvc.UI.Bundling; using Volo.Abp.AspNetCore.Mvc.UI.Theme.LeptonX; using Volo.Abp.AspNetCore.Mvc.UI.Theme.LeptonX.Bundling; using Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared; using Volo.Abp.AspNetCore.Serilog; using Volo.Abp.Auditing; using Volo.Abp.Autofac; using Volo.Abp.BackgroundJobs; using Volo.Abp.Caching; using Volo.Abp.Identity; using Volo.Abp.LeptonX.Shared; using Volo.Abp.Localization; using Volo.Abp.Modularity; using Volo.Abp.UI.Navigation.Urls; using Volo.Abp.UI; using Volo.Abp.VirtualFileSystem; using Volo.Saas.Host; using Volo.Abp.OpenIddict; using System.Security.Cryptography.X509Certificates; using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.Configuration;
namespace BOMS;
[DependsOn( typeof(AbpAutofacModule), typeof(AbpCachingStackExchangeRedisModule), typeof(AbpDistributedLockingModule), typeof(AbpAspNetCoreSerilogModule), typeof(AbpAccountPublicWebOpenIddictModule), typeof(AbpAccountPublicHttpApiModule), typeof(AbpAspNetCoreMvcUiLeptonXThemeModule), typeof(AbpAccountPublicApplicationModule), typeof(AbpAccountPublicWebImpersonationModule), typeof(SaasHostApplicationContractsModule), typeof(BOMSEntityFrameworkCoreModule) )] public class BOMSAuthServerModule : AbpModule { public override void PreConfigureServices(ServiceConfigurationContext context) { var hostingEnvironment = context.Services.GetHostingEnvironment(); var configuration = context.Services.GetConfiguration();
PreConfigure<OpenIddictBuilder>(builder =>
{
builder.AddValidation(options =>
{
options.AddAudiences("TEST");
options.UseLocalServer();
options.UseAspNetCore();
});
});
if (!hostingEnvironment.IsDevelopment())
{
PreConfigure<WebHostBuilder>(options =>
{
options.UseKestrel()
.UseUrls("https://example.com/auth")
.UseContentRoot(Directory.GetCurrentDirectory())
.UseIIS();
});
PreConfigure<AbpOpenIddictAspNetCoreOptions>(options =>
{
options.AddDevelopmentEncryptionAndSigningCertificate = false;
});
PreConfigure<OpenIddictServerBuilder>(builder =>
{
builder.AddSigningCertificate(GetSigningCertificate(hostingEnvironment, configuration));
builder.AddEncryptionCertificate(GetSigningCertificate(hostingEnvironment, configuration));
builder.SetIssuer(new Uri(configuration["AuthServer:Authority"]));
});
}
}
public override void ConfigureServices(ServiceConfigurationContext context)
{
var hostingEnvironment = context.Services.GetHostingEnvironment();
var configuration = context.Services.GetConfiguration();
if (!Convert.ToBoolean(configuration["App:DisablePII"]))
{
Microsoft.IdentityModel.Logging.IdentityModelEventSource.ShowPII = true;
}
if (!Convert.ToBoolean(configuration["AuthServer:RequireHttpsMetadata"]))
{
Configure<OpenIddictServerAspNetCoreOptions>(options =>
{
options.DisableTransportSecurityRequirement = true;
});
}
context.Services.ForwardIdentityAuthenticationForBearer(OpenIddictValidationAspNetCoreDefaults.AuthenticationScheme);
Configure<AbpLocalizationOptions>(options =>
{
options.Resources
.Get<BOMSResource>()
.AddBaseTypes(
typeof(AbpUiResource)
);
});
Configure<AbpBundlingOptions>(options =>
{
options.StyleBundles.Configure(
LeptonXThemeBundles.Styles.Global,
bundle =>
{
bundle.AddFiles("/global-styles.css");
}
);
});
Configure<AbpAuditingOptions>(options =>
{
//options.IsEnabledForGetRequests = true;
options.ApplicationName = "AuthServer";
});
if (hostingEnvironment.IsDevelopment())
{
Configure<AbpVirtualFileSystemOptions>(options =>
{
options.FileSets.ReplaceEmbeddedByPhysical<BOMSDomainSharedModule>(Path.Combine(hostingEnvironment.ContentRootPath, string.Format("..{0}BOMS.Domain.Shared", Path.DirectorySeparatorChar)));
options.FileSets.ReplaceEmbeddedByPhysical<BOMSDomainModule>(Path.Combine(hostingEnvironment.ContentRootPath, string.Format("..{0}BOMS.Domain", Path.DirectorySeparatorChar)));
});
}
Configure<AppUrlOptions>(options =>
{
options.Applications["MVC"].RootUrl = configuration["App:SelfUrl"];
options.RedirectAllowedUrls.AddRange(configuration["App:RedirectAllowedUrls"]?.Split(',') ?? Array.Empty<string>());
options.Applications["Angular"].RootUrl = configuration["App:AngularUrl"];
options.Applications["Angular"].Urls[AccountUrlNames.PasswordReset] = "account/reset-password";
options.Applications["Angular"].Urls[AccountUrlNames.EmailConfirmation] = "account/email-confirmation";
});
Configure<AbpBackgroundJobOptions>(options =>
{
options.IsJobExecutionEnabled = false;
});
Configure<AbpDistributedCacheOptions>(options =>
{
options.KeyPrefix = "BOMS:";
});
var dataProtectionBuilder = context.Services.AddDataProtection().SetApplicationName("BOMS");
if (!hostingEnvironment.IsDevelopment())
{
var redis = ConnectionMultiplexer.Connect(configuration["Redis:Configuration"]);
dataProtectionBuilder.PersistKeysToStackExchangeRedis(redis, "BOMS-Protection-Keys");
}
context.Services.AddSingleton<IDistributedLockProvider>(sp =>
{
var connection = ConnectionMultiplexer
.Connect(configuration["Redis:Configuration"]);
return new RedisDistributedSynchronizationProvider(connection.GetDatabase());
});
context.Services.AddCors(options =>
{
options.AddDefaultPolicy(builder =>
{
builder
.WithOrigins(
configuration["App:CorsOrigins"]?
.Split(",", StringSplitOptions.RemoveEmptyEntries)
.Select(o => o.Trim().RemovePostFix("/"))
.ToArray() ?? Array.Empty<string>()
)
.WithAbpExposedHeaders()
.SetIsOriginAllowedToAllowWildcardSubdomains()
.AllowAnyHeader()
.AllowAnyMethod()
.AllowCredentials();
});
});
context.Services.AddAuthentication()
.AddGoogle(GoogleDefaults.AuthenticationScheme, _ => { })
.WithDynamicOptions<GoogleOptions, GoogleHandler>(
GoogleDefaults.AuthenticationScheme,
options =>
{
options.WithProperty(x => x.ClientId);
options.WithProperty(x => x.ClientSecret, isSecret: true);
}
)
.AddMicrosoftAccount(MicrosoftAccountDefaults.AuthenticationScheme, options =>
{
//Personal Microsoft accounts as an example.
options.AuthorizationEndpoint = "https://login.microsoftonline.com/consumers/oauth2/v2.0/authorize";
options.TokenEndpoint = "https://login.microsoftonline.com/consumers/oauth2/v2.0/token";
})
.WithDynamicOptions<MicrosoftAccountOptions, MicrosoftAccountHandler>(
MicrosoftAccountDefaults.AuthenticationScheme,
options =>
{
options.WithProperty(x => x.ClientId);
options.WithProperty(x => x.ClientSecret, isSecret: true);
}
)
.AddTwitter(TwitterDefaults.AuthenticationScheme, options => options.RetrieveUserDetails = true)
.WithDynamicOptions<TwitterOptions, TwitterHandler>(
TwitterDefaults.AuthenticationScheme,
options =>
{
options.WithProperty(x => x.ConsumerKey);
options.WithProperty(x => x.ConsumerSecret, isSecret: true);
}
);
context.Services.Configure<AbpAccountOptions>(options =>
{
options.TenantAdminUserName = "admin";
options.ImpersonationTenantPermission = SaasHostPermissions.Tenants.Impersonation;
options.ImpersonationUserPermission = IdentityPermissions.Users.Impersonation;
});
Configure<LeptonXThemeOptions>(options =>
{
options.DefaultStyle = LeptonXStyleNames.System;
});
}
public override void OnApplicationInitialization(ApplicationInitializationContext context)
{
var app = context.GetApplicationBuilder();
var env = context.GetEnvironment();
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseAbpRequestLocalization();
if (!env.IsDevelopment())
{
app.UseErrorPage();
}
app.UseCorrelationId();
app.UseAbpSecurityHeaders();
app.UseStaticFiles();
app.UseRouting();
app.UseCors();
app.UseAuthentication();
app.UseAbpOpenIddictValidation();
app.UseHttpsRedirection();
if (MultiTenancyConsts.IsEnabled)
{
app.UseMultiTenancy();
}
app.UseUnitOfWork();
app.UseAuthorization();
app.UseAuditing();
app.UseAbpSerilogEnrichers();
app.UseConfiguredEndpoints();
}
private X509Certificate2 GetSigningCertificate(IWebHostEnvironment hostingEnv, IConfiguration configuration)
{
var fileName = "authserver.pfx";
var passPhrase = "********************";
var file = Path.Combine(hostingEnv.ContentRootPath, fileName);
if (!File.Exists(file))
{
throw new FileNotFoundException($"Signing Certificate couldn't found: {file}");
}
return new X509Certificate2(file, passPhrase);
}
} `
Startup.cs `using System; using System.IO; using System.Threading.Tasks; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using Serilog; using Serilog.Events;
namespace BOMS;
public class Program { public async static Task
try
{
Log.Information("Starting TEST.AuthServer.");
var builder = WebApplication.CreateBuilder(args);
builder.Host
.AddAppSettingsSecretsJson()
.UseAutofac()
.UseSerilog();
await builder.AddApplicationAsync<BOMSAuthServerModule>();
var app = builder.Build();
await app.InitializeApplicationAsync();
await app.RunAsync();
//var host = new WebHostBuilder()
// .UseKestrel()
// .UseUrls("https://localhost:5000/auth")
// .UseContentRoot(Directory.GetCurrentDirectory())
// .UseIISIntegration()
// .UseStartup<BOMSAuthServerModule>()
// .Build();
//host.Run();
return 0;
}
catch (Exception ex)
{
if (ex is HostAbortedException)
{
throw;
}
Log.Fatal(ex, "BOMS.AuthServer terminated unexpectedly!");
return 1;
}
finally
{
Log.CloseAndFlush();
}
}
} `