In AdminUI 6.3 we have made a considerable architectural change by enabling you to implement your own custom Identity store, allow support for fine grain access control and have merged the UI and API websites to make installation simpler.
- AdminUI now runs on a single site. Practically this means that the UI and API sites have been merged, simplifying configuration and installation.
- You are now able to extend or fully overwrite AdminUI's identity stores.
- You can now use Enforcer to write ALFA to enable fine-grain access control across AdminUI.
As part of AdminUI 6.3, we have made some changes to how AdminUI is hosted in IIS as well as how configuration is built.
We no longer have separate sites for the UI and API. Instead, these sites have been merged. We’ve made this decision to make it easier for us to componentise AdminUI into a NuGet package that will be covered later in this article.
One of the benefits of merging the sites is that we can centralise the configuration of AdminUI. Whereas before, you would have to update configuration values in configuration files (whether that be web.config or appsettings.json) in both the UI and API sites, as of AdminUI 6.3 configuration has been merged into a single appsettings.json file. You can still place your configuration in environment variables or the site’s web.config, however, going forward updating AdminUI via the installer will only carry over the configuration from your appsettings.json file.
If you install and update AdminUI via our installer, you can simply run the latest version of the installer.
If you're a Docker user, you will now only need to target the rocksolidknowledge/adminui image. You will need to merge any configuration from any uses of the rocksolidknowledge/adminui-api image.
If you use our .zips to install AdminUI you will need to grab the latest .zip file and merge the config from their previous UI and API installation files.
Custom Identity Store
Another major change in AdminUI 6.3 is the ability to replace AdminUI’s “Identity” layer with your own. Our intent is twofold:
- Provide customers who have Users, Roles or ClaimTypes that do not adhere to our usual Identity model the ability to write code that allows them to be managed via AdminUI.
- Allow extension of our existing Identity stores to allow for new fields or extension of functionality in the API
At the end of this article, there will be instructions on how to get started and code samples to kick you off.
What are the changes?
AdminUI’s idea of Identity has always been based on the ASP.NET Identity model provided by Microsoft. This means “Identity” is composed primarily of Users, Roles, Claims and their associated Claim Types. This includes using the UserManager and RoleManager provided with ASP.NET Identity
For this release we’ve created a group of abstractions that no longer tightly bind us to this model, these are all prefixed ISSO-.
The bulk of the work centres around 3 abstractions:
- ISSOUserStore - Handles user operations
- ISSORoleStore - Handles role operations
- ISSOClaimTypeStore - Handles claim type operations
To use these stores, you will need to write an implementation of ISSOStoreFactory. This implementation requires 3 methods:
These individual methods will return your concrete implementations of the previously described abstractions.
So, to fully implement your own Custom Identity Stores:
- If using new or extended models, write or update these models to implement our new interfaces. These can all be found in our Rsk.CustomIdentity NuGet package
- Write stores that implement the new store interfaces
- Write a factory that implements our ISSOStoreFactory interface
- Register and use AdminUI in your project
Use cases and implementation type
Described below are some use cases for both extending our Identity store and implementing your own so you can get an idea of how you can implement it for your use cases.
Additional fields on a user (partial implementation)
With the custom identity store, you can write code that enables additional columns to be managed via AdminUI as long as your base class implements ISSOUser. As claims are manageable on a user via the UI, you can write code in your custom store that maps columns to claims when getting a user and back to columns when updating a user. If you would rather manage your additional fields as you would any other field on a user, you can set IsRequired to true on your claims, otherwise, they will be manageable in the additional details tab of the UI.
Extending base functionality
If you didn’t want to make any changes to how the objects are handled but wanted to add your own notifiers or logging, for example, you can extend our existing stores to handle this. AdminUI's concrete implementation uses virtual methods, meaning they can be overridden and still call our class as a base - allowing you to put code before or after calling our concrete implementation.
Overriding certain calls
As AdminUI abstraction uses virtual methods you can pick and choose which methods you’d like to override.
Say, for example, you had already written code that updated a user, you can choose to only override the Update method from our store and call the code you have already written.
Non-ASP.NET Identity database objects
If you didn’t want to rely on any of our concrete implementations, then as long as your store implements any of our store classes and is created in the factory you can write that functionality yourself.
Because you do not have to use our existing concrete classes possible to write a store that uses a different ORM like Dapper or even a NoSql database like MongoDB to manage your Identity.
Customers had asked for ways to enable finer grain control to and within AdminUI and so as of AdminUI 6.2, we added support for the Enforcer Attribute-Based Access Control Engine.
AdminUI’s current model is centred around 4 control points:
- Identity/Identity Read Only
- Relates to User/Role/Claim resources
- IdentityServer/IdentityServer Read Only
- Relates to resources used by IdentityServer such as Clients/Claims/Api Resources
- The Audit view within AdminUI
- All/All Read Only
- All of the above
The primary example is the initial user in an AdminUI system will have the AdminUI Administrator role tied to the All Permission, you can view and configure this in the settings tab of AdminUI. AdminUI 6.2 added the EnableEnforcerAuthorization flag in the FeatureFlags section of config which when set to true will enable Enforcer. This is driven by an ALFA file that describes our current authorization policy which can be found in Site/policies/global.alfa. From here you can create an authorization policy as loose or as tight as possible.
If you have any questions on migrating to your own user store, leveraging Enforcer for fine grain access control or want to learn more about how the migration into a single site will affect your installation; please reach out to the AdminUI Dev team via [email protected]