User Prefixes / Site Separation

Posted: 2/5/2019 3:32:42 PM by Chris Bass | with 0 comments

In Kentico, the User's username is a unique key. If you try to make another user with the same name, it'll reject it. 

Generally, this is exactly what you want - imagine a user logging in, and having to be asked '*Which* SportsFan42 are you?' 

But when you're running a multisite project, you might want it either way - you might want to let them create a user in one site, and have that user be shared across all sites - or you might want to have each site be its own monolith, and have completely separated accounts on each site.  While you can't have it both ways in a single Kentico instance, you can choose between those two options - it just happens that by default, that first (shared) option is how Kentico handles it.
Specifically, there is a setting in Settings => Membership -> Share user accounts on all sites.  All that setting does, technically, is that when a user is created, they're assigned to each site.  You can add/remove users from sites either via a global event on user creation, or manually, or by setting the Registration web part (in a Portal Engine implementation) to dictate what sites a user should be a part of. 

If you disable that setting, and enable 'Use site prefix for user names​', however, all of that changes. When a user is created, it'll only be added to one site, and you'll find that you can now create separate users with the 'same' username - one for each site. Those users will be completely independent, whole users, each only accessible from its own site. 
Observant readers may notice the 'quotes' in 'same' above... This is because technically what Kentico does, is on user creation, it adds the GUID of the site the account was created in, to the username. So your username will actually be 'site.asdf1234-1234-etc.SportsFan42'... Kentico's smart enough that with this setting enabled, you'll still be typing in SportsFan42 to log in, and you'll still see SportsFan42 if you query the username - at least, if you use myUser.GetUserName()  - myUser.UserName will get you the full internal string.  Kentico internally refers to this as a 'safe' username. 

All of this is useful, but it's not nearly as easy as it looks to set up:
If you're setting this up as you create a site, it'll be pretty simple: users that already exist, stay as they are, and any user without that prefix, is still considered 'unsafe' - as in, shared across sites - so your global Administrator is still global, for example. Any *new* users created after these settings are set will have the site-specific prefix, and thus, be limited to logging into one site. 

However, if you're setting this up on an existing site, you'll have extra work to do, for a few reasons:

  1. If you've got existing end-users, they will still be global - even if they're only assigned to one site, you won't be able to add their usernames as new users on other sites. To set them as 'safe' users, you'll actually have to go manually edit their usernames to the 'site.guid.username' format, and disconnect them from any sites that aren't 'theirs' anymore.
  2. If your users were previously allowed to use their usernames across multiple sites, you're going to have to either duplicate their user objects, which... good luck?  Or tell them that 'hey, your login now only works here, make a new one'... Or just accept that they're going to be global users - which is actually fine, but remember, they're either -safe- or -unsafe- users: if they aren't using that site.guid.username format, their username is still globally locked-in.
  3. You may have references to unsafe calls to UserName in your logic that you have to fix... you don't want your users to ever see 'site.guid.username'
And if you ever decide that you want to 'undo' this and rejoin your users, you've got even more work to do:
  1. If you have existing end-users who are set up with safe usernames, they're going to start seeing those again, and there's a few cleanup steps to do here:
    • Pick one user that's going to be their new 'global' user. 
    • Add any sites they're added to, to that user.
    • Move any data from other users onto that user that you want - including fixing up any data-integrity stuff of picking which data to keep
    • Come to terms with the fact that any associations with those other users - document edits, contacts, customers, anything you don't merge on your own - is going to be deleted in the next step.
    • Delete the other users except the one you want to keep as global
    • Remove the site.guid part of the username, which seals them in as 'global' users.
  2. Once you've done all that, you can flip those checkboxes in settings and they'll be back to being 'shared' across your sites.

It's definitely not a move to take lightly, but at least the global -> site-specific direction, is fairly straightforward, especially if your users were already meant to be site-specific and you don't have to duplicate them. 

But in any case, it's a tool worth knowing is in your belt if your client really needs it.

Blog post currently doesn't have any comments.
 Security code