It doesn't get back to the app because of the URI issue, so what we need to figure out is how to have domain tenant resolver enabled, and not have to create a new redirect URI (tenantx.app.mydomain.com) every time in our azure app for every new tenant. Is it possible to have it always come back to app.mydomain.com and go from there?
[10:27:38 INF] Executing endpoint '/Account/Login'
[10:27:38 INF] Route matched with {page = "/Account/Login", action = "", controller = "", area = ""}. Executing page /Account/Login
[10:27:38 INF] Skipping the execution of current filter as its not the most effective filter implementing the policy Microsoft.AspNetCore.Mvc.ViewFeatures.IAntiforgeryPolicy
[10:27:38 INF] Executing handler method Volo.Abp.Account.Public.Web.Pages.Account.LoginModel.OnPostExternalLogin - ModelState is Invalid
[10:27:38 INF] Executed handler method OnPostExternalLogin, returned result Microsoft.AspNetCore.Mvc.ChallengeResult.
[10:27:38 INF] Executing ChallengeResult with authentication schemes (["Microsoft"]).
[10:27:38 INF] AuthenticationScheme: Microsoft was challenged.
[10:27:38 INF] Executed page /Account/Login in 9.9514ms
[10:27:38 INF] Executed endpoint '/Account/Login'
[10:27:38 INF] Request finished HTTP/1.1 POST https://tenant1.app.mydomain.com/Account/Login?returnUrl=https%3A%2F%2Ftenant1.app.mydomain.com%2F%3Fpage%3D%252FAccount%252F~%252FAccount%252FLogin&handler=ExternalLogin - 302 0 null 27.1038ms
We have an application that is multitenant. We have enabled the tenant domain name resolver. However we use sign in with microsoft, meaning we have to register an app on azure and provide the redirect uri. if we provide the standard root of our app, we can login with no problem because the redirect uri is valid. when a tenant tries to login it says the redirect uri is invalid. In this case we would have to add a new redirect uri for each subdomain for each tenant, which is tedious and could hit a limit. What can we do in code to work around this and use the one root redirect uri for the auth part?
for example app.mydomain.com works tenant1.app.mydomain.com does not work after returning from microsoft login to our app
Seems correct!
create a new project, add a tenant, login to tenant and set account overide for external login support.
Fill in the settings and log out. Attempt to login to the tenant with the external provider (without first creating abp user). External provider login succeeds redirects to main application, 400 bad request error: Logs show as below
[22:32:51 INF] Executing endpoint '/Account/Register'
[22:32:51 INF] Route matched with {page = "/Account/Register", action = "", controller = "", area = ""}. Executing page /Account/Register
[22:32:51 INF] Skipping the execution of current filter as its not the most effective filter implementing the policy Microsoft.AspNetCore.Mvc.ViewFeatures.IAntiforgeryPolicy
[22:32:51 INF] Executing handler method Volo.Abp.Account.Public.Web.Pages.Account.RegisterModel.OnPostAsync - ModelState is Invalid
[22:32:51 INF] Start processing HTTP request GET https://graph.microsoft.com/v1.0/me/photo/$value
[22:32:51 INF] Sending HTTP request GET https://graph.microsoft.com/v1.0/me/photo/$value
[22:32:51 INF] Received HTTP response headers after 228.7578ms - 200
[22:32:51 INF] End processing HTTP request after 228.9203ms - 200
[22:32:52 INF] AuthenticationScheme: Identity.Application signed in.
[22:32:52 INF] Executed handler method OnPostAsync, returned result Microsoft.AspNetCore.Mvc.RedirectResult.
[22:32:52 INF] Executing RedirectResult, redirecting to https://mydomain/?page=%2FAccount%2F~%2FAccount%2FLogin.
[22:32:52 INF] Executed page /Account/Register in 816.1899ms
[22:32:52 INF] Executed endpoint '/Account/Register'
[22:32:52 INF] Sending welcome email to tenant user: 3a1f6215-78b1-8c0b-88c4-73b736847965, TenantId: 3a1f6144-16da-f3f5-27cf-6826c562fcbf
[22:32:52 INF] Executing endpoint 'Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Controllers.ErrorController.Index (Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared)'
[22:32:52 INF] Route matched with {action = "Index", controller = "Error", area = "", page = ""}. Executing controller action with signature System.Threading.Tasks.Task`1[Microsoft.AspNetCore.Mvc.IActionResult] Index(Int32) on controller Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Controllers.ErrorController (Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared).
[22:32:52 WRN] The provided antiforgery token was meant for a different claims-based user than the current user.
[22:32:52 INF] Authorization failed for the request at filter 'Volo.Abp.AspNetCore.Mvc.AntiForgery.AbpAutoValidateAntiforgeryTokenAuthorizationFilter'.
[22:32:52 INF] Executing StatusCodeResult, setting HTTP status code 400
[22:32:52 INF] Executed action Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Controllers.ErrorController.Index (Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared) in 2.6912ms
[22:32:52 INF] Executed endpoint 'Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Controllers.ErrorController.Index (Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared)'
[22:32:52 ERR] An unhandled exception has occurred while executing the request.
System.Collections.Generic.KeyNotFoundException: The given key 'IsSeeding' was not present in the dictionary.
at System.Collections.Generic.Dictionary`2.get_Item(TKey key)
at Cns.Cloud.Apps.Users.UserCreatedEventHandler.HandleEventAsync(EntityCreatedEto`1 eventData) in /work/src/myproject/Users/UserCreatedEventHandler.cs:line 46
at Volo.Abp.EventBus.EventHandlerInvoker.InvokeAsync(IEventHandler eventHandler, Object eventData, Type eventType)
at Volo.Abp.EventBus.EventBusBase.TriggerHandlerAsync(IEventHandlerFactory asyncHandlerFactory, Type eventType, Object eventData, List`1 exceptions, InboxConfig inboxConfig)
at Volo.Abp.EventBus.EventBusBase.ThrowOriginalExceptions(Type eventType, List`1 exceptions)
at Volo.Abp.EventBus.EventBusBase.TriggerHandlersAsync(Type eventType, Object eventData)
at Volo.Abp.EventBus.Local.LocalEventBus.PublishAsync(LocalEventMessage localEventMessage)
at Volo.Abp.EventBus.Local.LocalEventBus.PublishToEventBusAsync(Type eventType, Object eventData)
at Volo.Abp.EventBus.EventBusBase.PublishAsync(Type eventType, Object eventData, Boolean onUnitOfWorkComplete)
at Volo.Abp.EventBus.Distributed.LocalDistributedEventBus.PublishToEventBusAsync(Type eventType, Object eventData)
at Volo.Abp.EventBus.Distributed.LocalDistributedEventBus.PublishAsync(Type eventType, Object eventData, Boolean onUnitOfWorkComplete, Boolean useOutbox)
at Volo.Abp.EventBus.UnitOfWorkEventPublisher.PublishDistributedEventsAsync(IEnumerable`1 distributedEvents)
at Volo.Abp.Uow.UnitOfWork.CompleteAsync(CancellationToken cancellationToken)
at Volo.Abp.AspNetCore.Uow.AbpUnitOfWorkMiddleware.InvokeAsync(HttpContext context, RequestDelegate next)
at Microsoft.AspNetCore.Builder.UseMiddlewareExtensions.InterfaceMiddlewareBinder.<>c__DisplayClass2_0.<b__0>d.MoveNext()
--- End of stack trace from previous location ---
at Volo.Abp.AspNetCore.ExceptionHandling.AbpExceptionHandlingMiddleware.InvokeAsync(HttpContext context, RequestDelegate next)
at Volo.Abp.AspNetCore.ExceptionHandling.AbpExceptionHandlingMiddleware.InvokeAsync(HttpContext context, RequestDelegate next)
at Microsoft.AspNetCore.Builder.UseMiddlewareExtensions.InterfaceMiddlewareBinder.<>c__DisplayClass2_0.<b__0>d.MoveNext()
--- End of stack trace from previous location ---
at Microsoft.AspNetCore.Timing.AbpTimeZoneMiddleware.InvokeAsync(HttpContext context, RequestDelegate next)
at Microsoft.AspNetCore.Builder.UseMiddlewareExtensions.InterfaceMiddlewareBinder.<>c__DisplayClass2_0.<b__0>d.MoveNext()
--- End of stack trace from previous location ---
at Volo.Abp.AspNetCore.MultiTenancy.MultiTenancyMiddleware.InvokeAsync(HttpContext context, RequestDelegate next)
at Microsoft.AspNetCore.Builder.UseMiddlewareExtensions.InterfaceMiddlewareBinder.<>c__DisplayClass2_0.<b__0>d.MoveNext()
--- End of stack trace from previous location ---
at Microsoft.AspNetCore.Builder.ApplicationBuilderAbpOpenIddictMiddlewareExtension.<>c__DisplayClass0_0.<b__0>d.MoveNext()
--- End of stack trace from previous location ---
at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
at Volo.Abp.AspNetCore.Security.AbpSecurityHeadersMiddleware.InvokeAsync(HttpContext context, RequestDelegate next)
at Microsoft.AspNetCore.Builder.UseMiddlewareExtensions.InterfaceMiddlewareBinder.<>c__DisplayClass2_0.<b__0>d.MoveNext()
--- End of stack trace from previous location ---
at Volo.Abp.Studio.Client.AspNetCore.AbpStudioMiddleware.InvokeAsync(HttpContext context, RequestDelegate next)
at Volo.Abp.Studio.Client.AspNetCore.AbpStudioMiddleware.InvokeAsync(HttpContext context, RequestDelegate next)
at Microsoft.AspNetCore.Builder.UseMiddlewareExtensions.InterfaceMiddlewareBinder.<>c__DisplayClass2_0.<b__0>d.MoveNext()
--- End of stack trace from previous location ---
at Volo.Abp.AspNetCore.Tracing.AbpCorrelationIdMiddleware.InvokeAsync(HttpContext context, RequestDelegate next)
at Microsoft.AspNetCore.Builder.UseMiddlewareExtensions.InterfaceMiddlewareBinder.<>c__DisplayClass2_0.<b__0>d.MoveNext()
--- End of stack trace from previous location ---
at Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddlewareImpl.g__Awaited|10_0(ExceptionHandlerMiddlewareImpl middleware, HttpContext context, Task task)
[22:32:52 INF] Request finished HTTP/1.1 POST https://mydomain/Account/Register?isExternalLogin=True&returnUrl=https%3A%2F%2Fmydomain%2F%3Fpage%3D%252FAccount%252F%7E%252FAccount%252FLogin - 302 0 null 1190.0806ms
[22:32:52 INF] Request starting HTTP/1.1 GET http://mydomain/Error?httpStatusCode=400 - null null
[22:32:52 INF] Executing endpoint 'Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Controllers.ErrorController.Index (Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared)'
[22:32:52 INF] Route matched with {action = "Index", controller = "Error", area = "", page = ""}. Executing controller action with signature System.Threading.Tasks.Task`1[Microsoft.AspNetCore.Mvc.IActionResult] Index(Int32) on controller Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Controllers.ErrorController (Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared).
[22:32:52 INF] Executing ViewResult, running view ~/Views/Error/Default.cshtml.
Create a new project, try to use oauth for the email sender, theres no native support. Override the EmailSender or the EmailSenderBase to add oauth, this is successful if you want to always send from same mailbox, with same credentials. If you want tenants to be able to configure their own oauth on their tenant (for example to send email notifications to their users using their own domain) its not possible in current UI.
Sorry, my question is targeted at removing migrations from many tenants.
If we have many tenants, manually running a rollback for each is unfeasible, is the approach to extend db migrator (why isnt there a flag for this already) or to keep track of how many tenants there are and update a script rollback?
our solution has a db context for host and db context for tenants. Each tenant has its own connection string to its own db.
When we add new migrations, we do so in the efcore project of the main apps project (we have several sub modules) and we point it to the --context tenantsdbcontext. We run db migrator things work as expected.
Now, how do we rollback migrations applied to the tenant dbs in development (with db migrator or tools like dotnet ef) and in production (production runs in containers for us)
Yes
Fix for this was to add the snippet below in main app blazor module
Configure<AbpAspNetCoreContentOptions>(options =>
{
options.ContentTypeMaps.Add(".mjs", "application/javascript");
});
The above lets the system load the purify and marked modules we copied into /ai-libs
And update the path of module imports in razor components in your submodule
protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (firstRender)
{
try
{
var module = await JS.InvokeAsync<IJSObjectReference>("import", "/_content/yourmodule/Components/Chat/ChatInput.razor.js");
await module.InvokeVoidAsync("init", textArea);
await module.DisposeAsync();
}
catch (JSDisconnectedException)
{
}
}
}
It was missing the / before _content