0

so im trying to create a SaaS application with ASP.NET Boilerplate, and i come into some problem as follows:

As i observe the framework, i noted that the "RegisterAsync" function in UserRegistrationManager create user based on the currently active tenant. It means if i currently log in on tenant '1', then when i register new user, the new user will have tenantId '1'. On the other hand, when i currently not logged in, if i register a new user, the app will show exception 'cannot register host user'.

public async Task<User> RegisterAsync(string name, string surname, string emailAddress, string phoneNumber, string userName, string plainPassword, bool isEmailConfirmed)
        {
            CheckForTenant();

            var tenant = await GetActiveTenantAsync();

            var user = new User
            {
                TenantId = tenant.Id,
                Name = name,
                Surname = surname,
                EmailAddress = emailAddress,
                PhoneNumber = phoneNumber,
                IsActive = true,
                UserName = userName,
                IsEmailConfirmed = isEmailConfirmed,
                Roles = new List<UserRole>()
            };

            return user;
        }

private void CheckForTenant()
        {
            if (!AbpSession.TenantId.HasValue)
            {
                throw new InvalidOperationException("Can not register host users!");
            }
        }

The application that i want to build requires the function for new user to be able to sign up along with free trial and then paid subscription. So i think that the new user should be able to create tenant by themself. So if the new user register, they will be forced to create new tenant before they can do any other thing in the app.

The problem is that the tenantId column in User table cannot be null, so i can register without tenant. Im thinking of assign all newly created user to 'Default' tenant at first, but i think that this was not the best practices.

Is there any way to overcome this problem or any references about that? Thanks in advance!

Nosferatu
  • 11
  • 4

2 Answers2

1

Based on my empirical SaaS Application development experience, a typical Self-Signup flow in Multi-Tenant applications would be like the one given below

  1. User opts to self-signin
  2. Allow the user to pick a subscription plan (most likely a trial plan)
  3. Get the Company Name (tenant name) as part of the signup flow
  4. Create a new tenant that has the subscription (2)
  5. Add the signup user as the administrator for that tenant
  6. In case of a trial plan, set up the suitable request handler to keep validating if the tenant has crossed the subscribed number of trial days, in that case, force redirect to payment page or signout
  7. If the user has opted to Signup for a paid subscription (during signup), after provisioning the tenant go to the payment page. Once payment succeeds, capture the transactionid and allow the user to login and use the application.

The flow that you wanted to be using is straightforward

  1. Build a custom self-signup process, obtain the company name (Tenant Name)
  2. Also capture the emailid of the user that is performing the sign-up
  3. Create the tenant based on info from (1)
  4. Set the administrator for the tenant based on the info from (2)

All your API calls should be working fine.

Note

  • Have a separate Self-Signup Service like (TenantSelfRegistrationService) so that you can allow anonymous access to that service.
  • In terms of security, set captcha and set rate-limits or CSRF Tokens etc to enforce security in the signup process.

Hope this clarifies

Saravanan
  • 7,637
  • 5
  • 41
  • 72
0

I looked at the code and the documentation and I think you should never allow an unknown user to create new tenants. This should happen by a person who has the correct authorization to create tenants. This is a user that exists in the host tenant. You as admin in the host tenant need to create tenant for somebody else and add them as admin for that tenant.

Registering users is then done through the normal way with the register webpage running for that tenant.

How to do that, I leave to you to figure out with the documentation of boilerplate itself! Documentation

Schwarzie2478
  • 2,186
  • 26
  • 30
  • I dont know about this but i think that many big SaaS service such as Zoho,etc, offer "free trial" when user can just register their user and company (tenant) themself, without needing the host to create new tenant for them, is this a bad practice? – Nosferatu Mar 18 '19 at 11:34
  • You would have to register User with new Tenant name and setup an unauthorized ApiController class that is allowed to create Tenants.from this. An user would then create a login and and provide an Tenant name. in your code you would create the new tenant with the tenantService and create the user in that newly created tenant at the same time. – Schwarzie2478 Mar 18 '19 at 14:42
  • You should to try limit how many times this can be called then because somebody clicks create on this multiple times, this could become a disaster. Perhaps work with email validation to start creating the tenant. At least this prevents most automated attacks. – Schwarzie2478 Mar 18 '19 at 14:44
  • i think about that too, but the problem is that in ASP.NET boilerplate that im using, the 'User' entity is required to have a TenantId, while what i want is that the user is created first, but when they login, they must create tenant before doing anything. This cannot be accomplished due to the fact that i cant create user without a TenantId. Any ideas? – Nosferatu Mar 19 '19 at 03:47
  • You can't create an user outside of an tenant, that's just it. You need to create the tenant during the create process of the User if this user request an own tenant. – Schwarzie2478 Mar 19 '19 at 13:46