Well, could this pose a slight security risk if I have access to all functions?
When I am logged in as a user of tenant AAA, I can access, for example, xxx.yyy.zzz:8077/api/services/app/Account/IsTenantAvailable (the backend public address, which is not hidden).
I can send the following request body:
{ "tenancyName": "BBB" }
In response, I receive another tenant's ID from the database. This confirms that the other tenant exists in the system.
Now, I can check if a user exists by calling the following function:
Endpoint: /api/services/app/CommonLookup/FindUsers
Request body:
{ "maxResultCount": 1000, "skipCount": 2147483647, "filter": "UserName", "tenantId": 999, "excludeCurrentUser": true }
Response:
{ "result": { "totalCount": 1, "items": [] }, "targetUrl": null, "success": true, "error": null, "unAuthorizedRequest": false, "__abp": true }
Is there a way to restrict the use of the web API only to the Angular client and block other requestors, or limit it only to host members?
Yes, you are right, inside secret.json the name of the database was wrong. Thank you.
I did it. I remove these folders from FlaskOne.Web.Host ( there is appsettings.json, the start project) and all other projects from the solution. Then I rebuild all.
I set the breakpoint here (I am not sure, is it an important place ? but here, the database name is wrong. ):
the exception during the debug is here
Under is copied details :
System.InvalidOperationException
HResult=0x80131509
Message=An exception has been raised that is likely due to a transient failure. Consider enabling transient error resiliency by adding 'EnableRetryOnFailure' to the 'UseSqlServer' call.
Source=Microsoft.EntityFrameworkCore.SqlServer
StackTrace:
at Microsoft.EntityFrameworkCore.SqlServer.Storage.Internal.SqlServerExecutionStrategy.Execute[TState,TResult](TState state, Func3 operation, Func
3 verifySucceeded)
at Microsoft.EntityFrameworkCore.ExecutionStrategyExtensions.Execute[TState,TResult](IExecutionStrategy strategy, TState state, Func2 operation, Func
2 verifySucceeded)
at Microsoft.EntityFrameworkCore.RelationalDatabaseFacadeExtensions.BeginTransaction(DatabaseFacade databaseFacade, IsolationLevel isolationLevel)
at Abp.EntityFrameworkCore.Uow.DbContextEfCoreTransactionStrategy.CreateDbContext[TDbContext](String connectionString, IDbContextResolver dbContextResolver)
at Abp.EntityFrameworkCore.Uow.EfCoreUnitOfWork.GetOrCreateDbContext[TDbContext](Nullable1 multiTenancySide, String name) at Abp.EntityFrameworkCore.Uow.UnitOfWorkExtensions.GetDbContext[TDbContext](IActiveUnitOfWork unitOfWork, Nullable
1 multiTenancySide, String name)
at Abp.EntityFrameworkCore.Uow.UnitOfWorkDbContextProvider1.GetDbContext(Nullable
1 multiTenancySide)
at Abp.EntityFrameworkCore.Repositories.EfCoreRepositoryBase3.GetContext() at Abp.EntityFrameworkCore.Repositories.EfCoreRepositoryBase
3.<GetQueryableAsync>b__8_0(Type key)
at System.Collections.Concurrent.ConcurrentDictionary2.GetOrAdd(TKey key, Func
2 valueFactory)
at Abp.EntityFrameworkCore.Repositories.EfCoreRepositoryBase3.<GetQueryableAsync>d__8.MoveNext() at Abp.EntityFrameworkCore.Repositories.EfCoreRepositoryBase
3.<GetAllAsync>d__21.MoveNext()
at Abp.EntityFrameworkCore.Repositories.EfCoreRepositoryBase3.<GetAllListAsync>d__27.MoveNext() at Abp.Configuration.SettingStore.<>c__DisplayClass3_0.<<GetAllListAsync>b__0>d.MoveNext() at Abp.Domain.Uow.UnitOfWorkManagerExtensions.<WithUnitOfWorkAsync>d__3
1.MoveNext()
at Abp.Configuration.SettingStore.<GetAllListAsync>d__3.MoveNext()
at Abp.Configuration.SettingManager.<<GetApplicationSettingsAsync>b__64_0>d.MoveNext()
at Abp.Runtime.Caching.TypedCacheWrapper2.<>c__DisplayClass21_0.<<GetAsync>b__0>d.MoveNext() at Abp.Runtime.Caching.AbpCacheBase
2.<GetAsync>d__17.MoveNext()
at Abp.Runtime.Caching.TypedCacheWrapper2.<GetAsync>d__21.MoveNext() at Abp.Configuration.SettingManager.<GetApplicationSettingsAsync>d__64.MoveNext() at Abp.Configuration.SettingManager.<GetSettingValueForApplicationOrNullAsync>d__58.MoveNext() at Abp.Configuration.SettingManager.<GetSettingValueInternalAsync>d__54.MoveNext() at FlaskOne.Web.UiCustomization.UiThemeCustomizerFactory.<GetCurrentUiCustomizer>d__3.MoveNext() in D:\RW\PROGRAMING\PROJECTS\FLASK_ONE\SaaS\aspnet-core\src\FlaskOne.Web.Core\UiCustomization\UiThemeCustomizerFactory.cs:line 27 at FlaskOne.Sessions.SessionAppService.<<GetCurrentLoginInformations>b__8_0>d.MoveNext() in D:\RW\PROGRAMING\PROJECTS\FLASK_ONE\SaaS\aspnet-core\src\FlaskOne.Application\Sessions\SessionAppService.cs:line 76 at Abp.Domain.Uow.UnitOfWorkManagerExtensions.<WithUnitOfWorkAsync>d__3
1.MoveNext()
at FlaskOne.Sessions.SessionAppService.<GetCurrentLoginInformations>d__8.MoveNext() in D:\RW\PROGRAMING\PROJECTS\FLASK_ONE\SaaS\aspnet-core\src\FlaskOne.Application\Sessions\SessionAppService.cs:line 57
at FlaskOne.Web.Session.PerRequestSessionCache.<GetCurrentLoginInformationsAsync>d__3.MoveNext() in D:\RW\PROGRAMING\PROJECTS\FLASK_ONE\SaaS\aspnet-core\src\FlaskOne.Web.Core\Session\PerRequestSessionCache.cs:line 33
at FlaskOne.Web.Controllers.UiController.<Index>d__7.MoveNext() in D:\RW\PROGRAMING\PROJECTS\FLASK_ONE\SaaS\aspnet-core\src\FlaskOne.Web.Host\Controllers\UiController.cs:line 47
at Microsoft.AspNetCore.Mvc.Infrastructure.ActionMethodExecutor.TaskOfIActionResultExecutor.<Execute>d__0.MoveNext()
at System.Runtime.CompilerServices.ValueTaskAwaiter`1.GetResult()
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<
This exception was originally thrown at this call stack: [External Code]
Inner Exception 1: SqlException: Cannot open database "FlaskOneDb13V" requested by the login. The login failed. Login failed for user 'DESKTOP-760V5B6\r.wielgus'.
But all the time, the database name is FlaskOneDb13V.
thx
We would like to give tenants only limited option to manage permissions / roles. As part of the process, we have very granular permissions created in the solution, while only very limited part should be avaible for tenant to manage.
That is why we considered to deny tenants access to manage permissions but let them only manage some selected set or roles (which role configuration would remain on host level) but as far as we understand, assigning permissions to roles for particular tenants cannot be managed centrally on host level ? (could you please confirm) ?
So the scenario would be as follows: Host user can predefine and configure roles that could be used on the tenant level tenant user can assign a role to particular users but cannot see / edit granular permissions Or alternatively can we somehow filter the list of permissions available for tenant to configure to avoid confusion ?
Can this be done in the settings or does it need to be programmed? If coding, how do you approach it? Are there any tips?
Is this solution a good solution when I have a few different menus? I need a completely different menu for one tenant than for another.
For example, one tenant has a menu:
but the second tenant one has:
e.t.c.
In my case, it does not depend on editions.
I quote info from https://aspnetboilerplate.com/Pages/Documents/Feature-Management Most SaaS (multi-tenant) applications have editions (packages) that have different features. This way, they can provide different price and feature options to their tenants (customers).
Thanks, for your help, you're right I forgot.