We have the same requirement as specified in support question #3530
Is there a way to prevent concurrent logins by the same User? Under a subscription-based service my SaaS application is being sold with a specific number of user licenses based on the version they purchase. Users can get around this by simply sharing a login. Is there a way to prevent User2 from logging with User1's credentials if User1 is already logged in
As this question is a couple years old, before adding a LastLogoutTime as suggested in support question #1918, I wanted to ensure that there is still no built-in ability to prevent concurrent logins and that the LastLogoutTime is still the est solution.
Thanks
I am running ASP.NetCore & Angular v6.7.0
I am able to run server and client docker containers locally using localhost:9901 and 9902 When I deploy the same containers to Azure the application all works EXCEPT I get a 404 error (nginx/1.17.0) when I try to change the tenant on the login page (or even just enter the <span class="highlight" style="color: rgb(0, 0, 0);"><span class="colour" style="color: rgb(24, 24, 24);"><span class="font" style="color: rgb(24, 24, 24);"><span class="size" style="color: rgb(24, 24, 24);">___________</span></span></span></span>.eastus.azurecontainer.io/account/login). If I remove the "/account/login" the login page appears and yet the url in the browser location field includes the "account/login". I am also not able to login with Active directory from the Azure version due to the 404 on the account/login redirect. The only things that I change between the two containers are the remote and host urls and the SQL server connection string.
Any ideas as to why this is happening?
Thanks...
<br> <br>
I see that the new abpframework (abp vNext) you are developing as the next version of AspBoilerplate is licensed GNU Lesser General Public License v3.0 (LGPL) This is of GREAT concern to our company as we do not permit any GPL or LGPL licensed code within our product and had hoped to continue developing our products using your AspNetZero but will not be able to if it is based on an LGPL licensed product.
Could you please explain why you have changed to the more restrictive LGPL license.
Thank you
I am trying to run my AspNet Zero application (Abp v4.3 & netcoreapp2.2) from a docker container. I am able to successfully bring up the http://localhost:9901/swagger web page. Unfortunately if I try to execute the IsTenantAvailable API (or anything else) I get a 500 error code I cannot interpret much from the the log file (see below). I get a similar error when I try to run the angular client (localhost:9902) and it executes the AbpUserConfigurationController.GetAll I think this may be related to the service in the container not being able to access the SQL Server that is on the host as I don't see anything in SQL Profiler coming from the container. For the connection string, I have tried using the static IP address of the host (with port) and also tried with the "host.docker.internal,1433"
Any help on what may be wrong or how I can collect more information on the error would be appreciated. Thanks
INFO 2019-04-04 14:02:49,718 [4 ] soft.AspNetCore.Hosting.Internal.WebHost - Request starting HTTP/1.1 GET http://localhost:9901/swagger/index.html
INFO 2019-04-04 14:02:50,374 [5 ] soft.AspNetCore.Hosting.Internal.WebHost - Request starting HTTP/1.1 GET http://localhost:9901/swagger/ui/abp.swagger.js
INFO 2019-04-04 14:02:50,376 [4 ] soft.AspNetCore.Hosting.Internal.WebHost - Request finished in 651.3126ms 200 text/html
INFO 2019-04-04 14:02:50,379 [4 ] soft.AspNetCore.Hosting.Internal.WebHost - Request starting HTTP/1.1 GET http://localhost:9901/swagger/ui/abp.js
INFO 2019-04-04 14:02:50,404 [4 ] NetCore.StaticFiles.StaticFileMiddleware - The file /swagger/ui/abp.js was not modified
INFO 2019-04-04 14:02:50,404 [5 ] NetCore.StaticFiles.StaticFileMiddleware - The file /swagger/ui/abp.swagger.js was not modified
INFO 2019-04-04 14:02:50,413 [5 ] soft.AspNetCore.Hosting.Internal.WebHost - Request finished in 38.6491ms 304 application/javascript
INFO 2019-04-04 14:02:50,413 [4 ] soft.AspNetCore.Hosting.Internal.WebHost - Request finished in 33.9876ms 304 application/javascript
INFO 2019-04-04 14:02:52,450 [5 ] soft.AspNetCore.Hosting.Internal.WebHost - Request starting HTTP/1.1 GET http://localhost:9901/swagger/v1/swagger.json
INFO 2019-04-04 14:02:52,989 [5 ] soft.AspNetCore.Hosting.Internal.WebHost - Request finished in 539.2978ms 200 application/json;charset=utf-8
INFO 2019-04-04 14:03:14,977 [4 ] soft.AspNetCore.Hosting.Internal.WebHost - Request starting HTTP/1.1 POST http://localhost:9901/api/services/app/Account/IsTenantAvailable application/json-patch+json 30
INFO 2019-04-04 14:03:14,986 [4 ] pNetCore.Cors.Infrastructure.CorsService - CORS policy execution successful.
INFO 2019-04-04 14:03:15,005 [4 ] ft.AspNetCore.Routing.EndpointMiddleware - Executing endpoint 'AspenTechnology.AspenPortal.Authorization.Accounts.AccountAppService.IsTenantAvailable (AspenTechnology.AspenPortal.Application)'
INFO 2019-04-04 14:03:15,164 [4 ] ore.Mvc.Internal.ControllerActionInvoker - Route matched with {area = "app", action = "IsTenantAvailable", controller = "Account"}. Executing action AspenTechnology.AspenPortal.Authorization.Accounts.AccountAppService.IsTenantAvailable (AspenTechnology.AspenPortal.Application)
INFO 2019-04-04 14:03:15,180 [4 ] pNetCore.Cors.Infrastructure.CorsService - CORS policy execution successful.
ERROR 2019-04-04 14:03:16,177 [4 ] Mvc.ExceptionHandling.AbpExceptionFilter - Value cannot be null.
Parameter name: key
System.ArgumentNullException: Value cannot be null.
Parameter name: key
at System.Collections.Generic.Dictionary2.FindEntry(TKey key) at System.Collections.Generic.Dictionary
2.TryGetValue(TKey key, TValue& value)
at Abp.Collections.Extensions.DictionaryExtensions.GetOrDefault[TKey,TValue](IDictionary2 dictionary, TKey key) at Abp.EntityFrameworkCore.Uow.DbContextEfCoreTransactionStrategy.CreateDbContext[TDbContext](String connectionString, IDbContextResolver dbContextResolver) at Abp.EntityFrameworkCore.Uow.EfCoreUnitOfWork.GetOrCreateDbContext[TDbContext](Nullable
1 multiTenancySide, String name)
at Abp.EntityFrameworkCore.Repositories.EfCoreRepositoryBase3.get_Table() at Abp.EntityFrameworkCore.Repositories.EfCoreRepositoryBase
3.GetAllIncluding(Expression1[] propertySelectors) at Abp.Domain.Repositories.AbpRepositoryBase
2.FirstOrDefault(TPrimaryKey id)
at Castle.Proxies.Invocations.IRepository2_FirstOrDefault.InvokeMethodOnTarget() at Castle.DynamicProxy.AbstractInvocation.Proceed() at Abp.Domain.Uow.UnitOfWorkInterceptor.PerformSyncUow(IInvocation invocation, UnitOfWorkOptions options) at Castle.DynamicProxy.AbstractInvocation.Proceed() at Castle.Proxies.IRepository
1Proxy.FirstOrDefault(Int32 id)
at Abp.MultiTenancy.TenantCache2.GetTenantOrNull(Int32 tenantId) at Castle.Proxies.Invocations.TenantCache
2_GetTenantOrNull.InvokeMethodOnTarget()
at Castle.DynamicProxy.AbstractInvocation.Proceed()
at Abp.Domain.Uow.UnitOfWorkInterceptor.PerformSyncUow(IInvocation invocation, UnitOfWorkOptions options)
at Castle.DynamicProxy.AbstractInvocation.Proceed()
at Castle.Proxies.TenantCache2Proxy.GetTenantOrNull(Int32 tenantId) at Abp.MultiTenancy.TenantCache
2.<>c__DisplayClass7_0.b__0()
at Abp.Runtime.Caching.CacheExtensions.<>c__DisplayClass5_02.<Get>b__0(String k) at Abp.Runtime.Caching.CacheBase.Get(String key, Func
2 factory)
at Abp.Runtime.Caching.CacheExtensions.Get[TKey,TValue](ICache cache, TKey key, Func2 factory) at Castle.Proxies.Invocations.ITenantCache_GetOrNull.InvokeMethodOnTarget() at Castle.DynamicProxy.AbstractInvocation.Proceed() at Castle.DynamicProxy.AbstractInvocation.Proceed() at Castle.Proxies.TenantCache
2Proxy.GetOrNull(Int32 tenantId)
at Abp.MultiTenancy.TenantStore.Find(Int32 tenantId)
at Abp.MultiTenancy.TenantResolver.GetTenantIdFromContributors()
at Abp.MultiTenancy.TenantResolver.ResolveTenantId()
at Abp.Runtime.Session.ClaimsAbpSession.get_TenantId()
at Abp.Auditing.AuditingHelper.CreateAuditInfo(Type type, MethodInfo method, IDictionary`2 arguments)
at Abp.AspNetCore.Mvc.Auditing.AbpAuditActionFilter.OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.InvokeNextActionFilterAsync()
at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.Rethrow(ActionExecutedContext context)
at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.InvokeInnerFilterAsync()
at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeNextExceptionFilterAsync()
INFO 2019-04-04 14:03:16,257 [4 ] .Mvc.Infrastructure.ObjectResultExecutor - Executing ObjectResult, writing value of type 'Abp.Web.Models.AjaxResponse'.
INFO 2019-04-04 14:03:16,287 [4 ] ore.Mvc.Internal.ControllerActionInvoker - Executed action AspenTechnology.AspenPortal.Authorization.Accounts.AccountAppService.IsTenantAvailable (AspenTechnology.AspenPortal.Application) in 1117.1855ms
INFO 2019-04-04 14:03:16,287 [4 ] ft.AspNetCore.Routing.EndpointMiddleware - Executed endpoint 'AspenTechnology.AspenPortal.Authorization.Accounts.AccountAppService.IsTenantAvailable (AspenTechnology.AspenPortal.Application)'
I was able to set up Azure Active Directory authentication in the past using the old ASP.NET MVC 5.x and jQuery but have not been able to get it working with the Asp.Net Core / Angular 7 (version 6.7.0)
I have registered the application in Azure Active Directory and granted the API pemission
I have set up the parameters in appsettings.json based on the information in Azure
"OpenId": {
"IsEnabled": "true",
"ClientId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"Authority": "https://sts.windows.net/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/",
"LoginUrl": "https://login.microsoftonline.com/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/oauth2/authorize"
},`
I go to my Asp.NetZero application login screen and click in the OpenId icon. It prompts me correctly for a microsoft username and password as expected using the Microsoft and returns a token to the Login page but tht is when I get the following error:
INFO 2019-03-29 11:51:45,083 [4 ] pNetCore.Cors.Infrastructure.CorsService - CORS policy execution successful.
INFO 2019-03-29 11:51:45,310 [4 ] ore.Mvc.Internal.ControllerActionInvoker - Executing action method AspenTechnology.AspenPortal.Web.Controllers.TokenAuthController.ExternalAuthenticate (AspenTechnology.AspenPortal.Web.Core) with arguments (AspenTechnology.AspenPortal.Web.Models.TokenAuth.ExternalAuthenticateModel) - Validation state: Valid
ERROR 2019-03-29 11:51:53,509 [4 ] Mvc.ExceptionHandling.AbpExceptionFilter - The given key 'ValidateIssuer' was not present in the dictionary.
System.Collections.Generic.KeyNotFoundException: The given key 'ValidateIssuer' was not present in the dictionary.
at System.Collections.Generic.Dictionary`2.get_Item(TKey key) at Abp.AspNetZeroCore.Web.Authentication.External.OpenIdConnect.OpenIdConnectAuthProviderApi.ValidateToken(String token, String issuer, IConfigurationManager`1 configurationManager, CancellationToken ct)
at Abp.AspNetZeroCore.Web.Authentication.External.OpenIdConnect.OpenIdConnectAuthProviderApi.GetUserInfo(String token)
at AspenTechnology.AspenPortal.Web.Controllers.TokenAuthController.GetExternalUserInfo(ExternalAuthenticateModel model) in C:\TFSWorkspace\Aspen Portal\Template\aspnet-core\src\AspenTechnology.AspenPortal.Web.Core\Controllers\TokenAuthController.cs:line 476
at AspenTechnology.AspenPortal.Web.Controllers.TokenAuthController.ExternalAuthenticate(ExternalAuthenticateModel model) in C:\TFSWorkspace\Aspen Portal\Template\aspnet-core\src\AspenTechnology.AspenPortal.Web.Core\Controllers\TokenAuthController.cs:line 351
at lambda_method(Closure , Object )
at Microsoft.AspNetCore.Mvc.Internal.ActionMethodExecutor.AwaitableObjectResultExecutor.Execute(IActionResultTypeMapper mapper, ObjectMethodExecutor executor, Object controller, Object[] arguments)
at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.InvokeActionMethodAsync()
at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.InvokeNextActionFilterAsync()
at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.Rethrow(ActionExecutedContext context)
at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.InvokeInnerFilterAsync()
at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeNextExceptionFilterAsync()
INFO 2019-03-29 11:51:54,157 [4 ] .Mvc.Infrastructure.ObjectResultExecutor - Executing ObjectResult, writing value of type 'Abp.Web.Models.AjaxResponse'.
INFO 2019-03-29 11:51:54,240 [4 ] ore.Mvc.Internal.ControllerActionInvoker - Executed action AspenTechnology.AspenPortal.Web.Controllers.TokenAuthController.ExternalAuthenticate (AspenTechnology.AspenPortal.Web.Core) in 9156.2841ms
INFO 2019-03-29 11:51:54,254 [4 ] ft.AspNetCore.Routing.EndpointMiddleware - Executed endpoint 'AspenTechnology.AspenPortal.Web.Controllers.TokenAuthController.ExternalAuthenticate (AspenTechnology.AspenPortal.Web.Core)'
INFO 2019-03-29 11:51:54,305 [4 ] soft.AspNetCore.Hosting.Internal.WebHost - Request finished in 9256.5662ms 500 application/json; charset=utf-8
I have a ASPNet Zero Core application that works fine until I add an application dlls into Plugins Folder. My application I am plugging in is using the same architecture as the main boilerplate (i.e. Application, Core, EntityFramework, Web.Core,...) with only the application specific entities (Abp entities removed) As soon as I drop the dlls into the Plugins Folder and start the server side application I get an error that shows as an error in the Log as "Invalid object name 'AbpLanguages'" As a test, I added an AbpLanguages table to the Plugins application database and the program then complained about another invalid object; adding that table that was referenced and the program went further again, and so on. Obviously the Plugin database DbContext (SampleDbContext) is overriding the Default DbContext. Any ideas on how this is happening and fixing it would be appreciated! Thanks
On the Plugin code:
public class SampleDbContext : DbContext
{
public virtual DbSet<SampleItem> SampleItems { get; set; }
public SampleDbContext(DbContextOptions<SampleDbContext> options)
: base(options)
{
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.ConfigurePersistedGrantEntity();
}
}
-----------------------------------------------
public static class SampleDbContextConfigurer
{
public static void Configure(DbContextOptionsBuilder<SampleDbContext> builder, string connectionString)
{
builder.UseSqlServer(connectionString);
}
public static void Configure(DbContextOptionsBuilder<SampleDbContext> builder, DbConnection connection)
{
builder.UseSqlServer(connection);
}
}
WebCoreModule PreInitialize
Configuration.DefaultNameOrConnectionString = _appConfiguration.GetConnectionString(SampleConst.ConnectionStringName);
We have been using the ASPNet Zero for over three years and are now converting our application from the "old" MVC 5.x/AngularJS1.x to Core 2.x/Angular7.x. While we are at it, we want to split the features into pluggable instances that a customer can chooose to install or not. I have been able to get the Plugin feature pretty much working for the Server side. Are there examples around to show how to do it for the Angular7.x client side?
Thanks