Hi @burkay,
ABP Commercial doesn't have a feature to prevent concurrent login. If your application requires it, you should implement it yourself. If you have any trouble because of ABP, or you want to get advice how to do a specific thing in ABP, we help you, but we can't fully implement a feature that is needed for you. I agree that this can be a good feature for ABP Commercial, but currently it is not included, sorry.
Beside my response, I personally can give you a few suggestions that may help you on your implementation. For an example implementation, you can go like that:
I suppose you can also find some solutions on web since your requirement is a common requirement. As I said, we will consider to implement it in ABP Commercial's standard.
Hi @ccernat
In my experiences, if the authentication fails in Blazor WASM apps, it waits too much to respond. That's something in Blazor's internal, I don't know why. After you solve the issue about authentication (and the problems in your browser console), the load time problem should be solved.
Blazor never loads as fast as other UIs (MVC and Angular) in our tests. What I can clearly say is that it is not related to ABP's backend, because as I already said, MVC and Angular UI are loading pretty fast. Especially, you can compare Blazor with Angular since they are both SPAs. ABP's Blazor UI actually has no much magic that cause such a slowness.
We want to help you. Please, first try to resolve the errors. If you find it still slow, please help us to reproduce it, since we don't have such a problem in ABP Commercial's standard Blazor startup template.
Hi,
Unfortunately, we can't declare an availability date yet. All I can say that it is one of the important and prioritized items in our product backlog.
Hi,
I suppose you are talking about the Volo.Abp.Users.Abstractions package. We created it to not depend on the Microsoft Identity library from our other modules and make the Identity library replaceable in advanced scenarios.
We don't plan and we don't want to create abstractions for organization units and roles. We already have abstractions for permissions (and settings, features, etc - these are defined in the core abp framework packages, while the database implementation are in separate modules). You don't need to have a reference to the Permission Management module, for example, to check a permission.
We don't think it is true to create such a detailed abstraction. OU and roles are mainly used to organize permissions and your module should only need to the permission system dependency (it already has). These details are internals of the Identity module.
Creating an abstraction is a very serious decision and has important costs. If we create abstractions for OUs and roles, we implicitly force all the implementations should support these systems (in ideal). Abstractions should be minimal and should have very few assumptions about the implementations. If we completely wrap all Identity details, no point to make an abstraction, we directly use it.
Finally, such abstractions are useful while developing a modular framework. But you probably don't need it. You can directly depend on the Identity module from your other modules, especially if you don't need a system that makes possible to change the Identity without effecting other modules. Even if you need it, creating such a detailed abstraction may have a bigger cost than changing the Identity module when you need it in the future.
With that, if the integration effort is more or less the same as keeping IDS4 alive, without tapping on new features that Duende has in stock and provided the API remains largely the same for the ABP use cases, then why not?
We were considering this scenario. If we provide an option to start a new solution with IDS installed, then it is a huge effort to support multiple auth server option. If we only upgrade packages to Duende IDS for existing customer projects, it also may not worth effort. We have time to make the final decision. It is mostly based on how many customers will want to continue with Duende IDS. We will see, but we can't promise unfortunately.
Any plans to keep the IDS support option? Any plans for Commercial IDS support?
We are not removing IDS packages and will continue to release new versions of IDS related Nuget/NPM packages. That means you won't have an issue while upgrading to v6.0 (when it is released). We will continue to fix bugs in our packages for a while. ABP 7.0 will be based on .NET 7. If IDS continue to work with .NET 7, we will continue to ship nuget packages for our IDS integration.
BTW, IDS itself is canceling support for the open source IDS in the end of this year. They are moved to Duende IDS you know. We won't migrate to Duende IDS.
Hi,
IdentityUser
class is not in your application, it comes from the Identity module as you know. So, you can not directly change its source code to add a navigation collection (unless you include Identity modules's source code into your solution).
So, when you don't add ICollection<T>
to the IdentityUser
, there is no way to define many-to-many relationship as you want. Not possible to do it with fluent api and defining collection only in one side. EF Core doesn't allow to it. You can see these links for more info:
The best solution I can suggest is to manually create the relation entity. I tried with the following entities:
public class Book : AggregateRoot<int>
{
public string Name { get; set; }
public Collection<UserBook> UserBooks { get; set; }
}
public class UserBook : BasicAggregateRoot<int>
{
public IdentityUser User { get; set; }
public Book Book { get; set; }
}
My purpose is to establish a many-to-many relation between IdentityUser
and Book
entities. So, I defined UserBook
as a relation entity. Then mapped it like that:
builder.Entity<UserBook>(b =>
{
b.ToTable("UserBooks");
b.ConfigureByConvention();
b.HasOne(x => x.User).WithMany().HasForeignKey("UserId");
b.HasOne(x => x.Book).WithMany(x => x.UserBooks).HasForeignKey("BookId");
});
The relation table is created when I add a new migration. So, now you can include Users while querying books. However, you can not do vice verse. You should separately query books of a user or perform a LINQ JOIN query yourself since Include won't work (no navigation collection on the IdentityUser
entity).
IFeatureChecker
is only for checking features for the current user and has limitations due to its design and purpose.
Use IFeatureManager
as documented here: https://docs.abp.io/en/abp/latest/Modules/Feature-Management#ifeaturemanager
But when we will place Modules in different service, what we need to do so IBookService will be resolved to HttpApiClient, so call will be made over http?
Yest, that's the design of ABP's modularity. This document explains it well: https://docs.abp.io/en/abp/latest/Best-Practices/Module-Architecture It explains all the scenarios.
The second question is what to do when we will add authorization to endpoints in IBookService
Authentication and authorization is automated when you properly configure the client and the server. Create a MVC tiered application. In this setup, MVC UI uses the app service interfaces, but it actually make an HTTP request to the HTTP API server by authenticating and authorizing.
Console test app in the startup template also does that: https://github.com/abpframework/abp/tree/dev/templates/app/aspnet-core/test/MyCompanyName.MyProjectName.HttpApi.Client.ConsoleTestApp It uses resource owner password authentication, but you can easily configure client-secret auth too.
Another document: https://docs.abp.io/en/abp/latest/Samples/Microservice-Demo#identityserver-client here, blogging microservice calls the identity microservice and this section shows the auth config.
We suggest client-secret auth when you want to consume a microservice from a background worker/job.
Hi,
ICurrentTenant.Change
is the only way to operate on a specific tenant in a background worker. I can recommend to create a separate console application for the background workers and run only a single instance of that application. Otherwise, if you make it a part of a service, you should care when you run multiple instances of that service - the worker may work on the same data which may cause duplications.
Disabling the tenancy filter is needed if you want to query from all tenants. It can only work for "shared database" approach. It can't work if a tenant has a seperate database. However, if you want to query a list of tenants (from the AbpTenants table), no need to disable the tenancy filter, because the Tenant entity is not multi-tenant.
In your background worker app, you can add a reference to the Volo.SaaS.EntityFrameworkCore and set the connection string for the saas database. Alternatively, you can perform a call to the SaaS service if you don't want to access the SaaS db from the worker app. But, I suggest to use the db.