-
Notifications
You must be signed in to change notification settings - Fork 161
How AuthP handles sharding
This document tells you how the AuthP's sharding feature works internally, updated to AuthP version 6 and above. You don't need to read this to create a sharding multi-tenant application, but knowing how sharding works inside might help you build a better app.
Once you add the SetupMultiTenantSharding
method to the registering of the AuthP, then you are some from of sharding multi-tenant application. At this point (irrespective of whether its hybrid or sharding-only) accessing a tenant's data is a lot more complex over the default "all tenants share one database" approach.
The "all tenants share one database" approach uses a connection string that provides all the information to access a database. But a sharding multi-tenant app needs to creates a connection string by combining:
dynamically create a connection string to get the a) the correct database server, and b) the correct database on that database server. This creates the complete connection string by combining the two parts:
- The database server from a named "ConnectionStrings" in the appsettings file (See note later about using Azure databases)
- The database name from the sharding entries.
The the name of the connection string and the database name are supplied by an ShardingEntry
which contains the following data.
Name | What is contains |
---|---|
DatabaseName |
The name of the database |
ConnectionName |
The name of the connection string defining the server |
DatabaseType |
Short name of the database provider (e.g. SqlServer). Used to select the correct connection string builder. |
Name |
This is the unique key to this entry |
An AuthP's Tenant
using sharding has an properly that holds the Name
of the ShardingEntry
, which a tenant user (i.e. a AuthUser
linked to a tenant) is linked to. When a tenant user logs in the Name
of the ShardingEntry
is turned into a claim (for performance reasons). The diagram below shows the four steps that are executed every time a tenant user makes a HTTP request.
This might things this process will be slow, but in fact its very fast. That because each three lookups below each take less that 100 nanoseconds:
- Get sharding name from the user's claims - very fast.
- The sharding entries are handled by my Net.DistributedFileStoreCache, which takes about ~25 ns to an entry.
- Reading the connection string is fast too, maybe in the range ~25 ns.
To form the final connection string you need to use the correct connection string builder, and its done via various classes that implement the IDatabaseSpecificMethods
interface. This interface has two key parts:
- A string property called
DatabaseProviderShortName
, which contains the key (e.g. "SqlServer") - A method called
FormShardingConnectionString
which will use the connection string builder for the database provider defined by theDatabaseProviderShortName
This allows the code that needs the final connection string can select the correct IDatabaseSpecificMethods
implementation for the database provider defined in the sharding entry.
There are built-in implementations:
- SqlServerDatabaseSpecificMethods
- PostgresDatabaseSpecificMethods
- SqliteInMemorySpecificMethods (only used in unit tests)
And the SetupMultiTenantSharding
extension method selects the correct implementation based on what database type you have selected.
If you want to use another database (see custom database feature), then you would:
- Create an implementation of the
IDatabaseSpecificMethods
for your database type. - Copy the
SetupMultiTenantSharding
extension method and register yourIDatabaseSpecificMethods
instead of the built-in implementation.
One of the jobs of the appsettings file is hold the connection strings to access the database(s) your application uses. These connection strings contain parts like username / password which must be kept secret. There are various ways to hide connection strings, such as ASP.NET Core secrets and have Azure can override your connection strings. Therefore the appsettings file is a great place to hold your connection strings.
AuthP in AddSharding
mode the appsettings file holds the AuthP's database (which in hybrid mode can be used for shard tenants) via the "DefaultConnection" entry. If you want to provide extra connection strings they SHOULD NOT have a database name. That's because these connection strings are defining the server, with the database part updated later by the sharding process. The json below shows an example multiple connection strings linked to Azure databases.
{
"ConnectionStrings": {
"DefaultConnection": "Server=tcp:CentralServer.database.windows.net,1433;Database=AuthPDatabase;User ID...",
"WestCoastServer": "Server=tcp:WestCoastServer.database.windows.net,1433;User ID...",
"CentralServer": "Server=tcp:CentralServer.database.windows.net,1433;User ID=...",
"EastCoastServer": "Server=tcp:EastCoastServer.database.windows.net,1433;User ID=..."
},
}
When using Azure you can override the connection strings via the App Service -> Configuration tab. This overrides any value the ConnectionStrings" section of the appsettings file - see this Azure document which shows how you can configure connections strings (NOTE: Its even easier by using Visual Studio's Publish feature).
IMPORTANT NOTE: Do NOT use Azure Key Vault provider if you have a high activity because it has a limit of 200 requests / second. Because each tenant user accessing the data has to read the connection string every time, which means if your have lots of simultaneous users that would slow down your application.
- Intro to multi-tenants (ASP.NET video)
- Articles in date order:
- 0. Improved Roles/Permissions
- 1. Setting up the database
- 2. Admin: adding users and tenants
- 3. Versioning your app
- 4. Hierarchical multi-tenant
- 5. Advanced technique with claims
- 6. Sharding multi-tenant setup
- 7. Three ways to add new users
- 8. The design of the sharding data
- 9. Down for maintenance article
- 10: Three ways to refresh claims
- 11. Features of Multilingual service
- 12. Custom databases - Part1
- Videos (old)
- Authentication explained
- Permissions explained
- Roles explained
- AuthUser explained
- Multi tenant explained
- Sharding explained
- How AuthP handles sharding
- How AuthP handles errors
- Languages & cultures explained
- JWT Token refresh explained
- Setup Permissions
- Setup Authentication
- Startup code
- Setup the custom database feature
- JWT Token configuration
- Multi tenant configuration
- Using Permissions
- Using JWT Tokens
- Creating a multi-tenant app
- Supporting multiple languages
- Unit Test your AuthP app