-
Notifications
You must be signed in to change notification settings - Fork 161
AuthUser admin service
The AuthP library contains a IAuthUsersAdminService
service that contains various admin features for managing AuthP's users. This page describes these admin features and give you some examples of how they might be used in an application.
NOTE: the code for the AuthUsersAdminService
can be found here and has plenty of comments.
There are many example of using AuthP's users admin:
- Example1's Pages/AuthUsers Razor Pages. NOTE: You do not need to log in to access the admin services.
- Example3, Example4 and Example6's
AuthUsersController
andTenantAdminController
. NOTE: You must log in as 'AppAdmin@g1.com' or 'Super@g1.com' to access all the admin features.
Here is a list of the various methods in the IAuthUsersAdminService
.
The IAuthUsersAdminService
service contains the method called QueryAuthUsers(string dataKey = null)
. This method returns an IQueryable<AuthUser>
query.
- If the
datakey
is null, then the query will include all theAuthUsers
in the AuthP's database, e.g.
var queryOfAllUsers = _authUsersAdmin.QueryAuthUsers();
var allAuthUser = queryOfAllUsers .OrderBy(x => x.Email).ToList();
- But if you provide a
datakey
that isn't null (i.e the user is linked to a tenant), it return just the users in the multi-tenant that matches thedatakey
, e.g.
var dataKey = User.GetAuthDataKeyFromUser();
var queryUsersYouControl = _authUsersAdmin.QueryAuthUsers(dataKey);
var theUsersYouControl = queryUsersYouControl .OrderBy(x => x.Email).ToList();
NOTE: Option 2 can be used allows you to create an admin user who can only manage users within a specific multi-tenant group (see the Index
method in Example4's AuthUsersController for an example of this approach). The nice part is that an app admin (i.e a user not linked to a tenant) will return a null DataKey, which means the QueryAuthUsers
will return all the users.
The IQueryable<AuthUser>
query allows you to select the specific parts of the AuthUser
and its relationships to display to the the admin user. In the Example4 application (which includes multi-tenant) I created a AuthUserDisplay
class which returned the user's info, roles and tenant name. The screenshot below shows this listing when logged in as the 'admin@4uInc.com', which is linked to the "4U Inc." tenant.
Things to point out in this screenshot:
- Example1's List Users uses the same code, but doesn't show the tenant because Example1 application doesn't use AuthP's multi-tenant feature.
- The Example4' example lists the email & username of each user
- The Example4' example lists all the Roles of each user
- Because Example4 is using hierarchical multi-tenant database I included the Tenant? column. It you hover / click the YES you get the full name of the tenant.
As you can see, this list of users also contains links to further admin features which are described below. NOTE: the admin links are only shown if your have the correct Role / Permissions.
Sometime you to need to find a user via a string, say for showing data about a specific user. The IAuthUsersAdminService
has two methods to do this, which are: FindAuthUserByUserIdAsync(string userId)
and FindAuthUserByEmailAsync(string email)
.
Both methods return a Task<IStatusGeneric<AuthUser>>
result. If there are no errors (such as can't find the user), then you get the AuthUser
with its UserRoles
and UserTenant
.
While you can't create a AuthUser directly (see next section why that is) you can update an existing user. You do this using the AuthUser admin method called UpdateUserAsync
. This method has parameter for UserId to find the user to change, plus multiple parameters to update the user's Email, Name, Role, and TenantName.
In AuthP version 3.2.0 allows you to select the properties you want to change, for instance if you want to just update the Roles you would use this call:
var newRoleNameList = new List<string> { "Role1", "Role2"};
var status = await _authUsersAdmin
.UpdateUserAsync(change.UserId, roleNames: newRoleNameList);
This works because any parameter that is null will keep the current setting. The only odd parameter settings are:
-
roleNames
- to remove all the roles you have to return a list with a single roleName of "< none >" (defined in theCommonConstants.EmptyTenantName
constant). -
tenantName
- to remove a tenant from the user you have to return the string "< none >" (defined in theCommonConstants.EmptyTenantName
constant).
You can see an example of using this method in Example's AuthUsersController and Example's TenantAdminController. The screenshot below shows this in action.
NOTE: To provide the list of Roles that a AuthUser can have you should call the GetRoleNamesForUsersAsync
method which returns a list of the RoleNames (and a "< none >") that can be applied to an AuthUser. If your application uses AuthP's multi-tenant feature you must provide the logged in user's userId to the GetRoleNamesForUsersAsync
method call, because the Roles a user can have can depend on the tenant Roles.
In multi-tenant applications which use the tenant admin concept
If you use the tenant admin concept in your multi-tenant application then the main job the tenant admin user can do is edit the AuthUser's Roles (and nothing else). This allows the tenant admin to change what features a user in their tenant can access. Because of the various changes to the Roles added by version 2 of this library this is now a safe feature to give to a tenant admin user (by 'safe' I mean only Roles that are suitable for user in their tenant are available to them).
NOTE: See articles Part 2 and 3 in the "Building ASP.NET Core and EF Core multi-tenant apps" series, which provide various tenant user extra features such as inviting a user to join their tenant, and setting up a new tenant using versioning.
In the AuthUser explained section authentication provider's users are the master list of users. This means AuthP' user admin doesn't have a 'create a new AuthUser' method, but a "sync user" feature.
This "sync user" feature has two sync methods in the IAuthUsersAdminService
service, and a ISyncAuthenticationUsers
that you need to register with AuthP on startup. There is a
- The
SyncAndShowChangesAsync
method that detects the differences between the authentication provider's users (see point 3) and the AuthP users and returns the recommended changes to make the AuthP's user match the authentication provider's users. - The
ApplySyncChangesAsync
method which can take the data from theSyncAndShowChangesAsync
method and applies the recommended changes to the AuthP's Users. - The
SyncAndShowChangesAsync
method relies on getting a list of all the users registered with your authentication provider. This requires you to build a service that implements theISyncAuthenticationUsers
and registering that service with AuthP using theRegisterAuthenticationProviderReader<TSync>
extension method. This is explained in the Startup code -> User Admin section.
NOTE: The AuthP library has a SyncIndividualAccountUsers
for synchronizing with the Individual Account authentication provider.
The IAuthRolesAdminService
service contains a method called SyncAndShowChangesAsync
. This compares the authentication provider's users and the AuthP users and returns a list of SyncAuthUserWithChange
classes which contains the differences. The possible differences are:
- Create: New users have been added in the authentication provider list of users.
- Update: Email or username has changed in the user in the authentication provider database.
- Delete: The AuthP users have a user that is (no longer) in the authentication provider database
NOTE: If the authentication UserName and Email are then same, then the sync code doesn't register a sync change if the AuthP's user has a different UserName. This allows you to provide useful UserNames in the AuthP users when the authentication provider doesn't have a useful username.
In the Example1 example the implementation of the "Sync Users" display is fairly simple to implement because there are no manual controls (see Example4's version of "Sync Users" display later). The only complication is returning a collection for a Razor page (see the AuthUser / SyncUsers.cshtml Razor page to see how to do that). The screenshot below is taken from Example1.
If the admin person clicks the "Apply sync changes", then the recommended changes shown on the "sync users" display are automatically applied to the AuthP's users.
Example4's "Sync Users" display has some useful extra features, like manual Create / Update / Delete and an "ignore" button. This makes the implementation a lot more complicated and needs extra JavaScript code (see end of the AuthUsers/SyncUsers.cshtml view). You will find a diagram of how the various parts work together to make this work.
The screenshot below is taken from Example4's AuthUser\SyncUsers page showing the three types of differences:
Things to point out in this screenshot:
- If the "Update all" button (bottom left) is clicked a method called
ApplySyncChangesAsync
is called, which automatically apply the recommended changes to the AuthP database. - To manually make a change, then click the "Create" / "Update" / "Delete" button next to each difference.
- To ignore a change, then click the "Ignore" button, which change the button to say "Ignored". This means this change entry will be ignored when the "Update all" button is clicked.
- The sync information finds any differences and in the Example4 implementation I used the BootStrap's bg-warning color to show the differences.
The manual "Create" / "Update" / "Delete" button is complicated because it has to take the recommended change to the Create, Edit or Delete display. This is done via an action method called EditFromSync
in the AuthUserController. The diagram shows how this is done.
The IAuthUsersAdminService
service contains the following method to create / alter an 'AuthUser`:
AddNewUserAsync(string userId, string email, string userName, List<string> roleNames, string tenantName = null)
UpdateUserAsync(string userId, string email, string userName, List<string> roleNames, string tenantName = null)
AddRoleToUser(AuthUser authUser, string roleName)
RemoveRoleToUser(AuthUser authUser, string roleName)
DeleteUserAsync(string userId)
Note that the AddNewUserAsync
can only be called when you have the userId of a user from the authentication provider. That's why only the "sync user", which uses the your ISyncAuthenticationUsers
service to get a list of all the authentication provider's users.
- 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