Built-In Identity Auth Admin UI

Lucy Bates

Lucy Bates

Works in software design, company building, and the aerospace industry.

Built-In Identity Auth Admin UI

With ServiceStack now deeply integrated into ASP.NET Core Apps we're back to refocusing on adding value-added features that can benefit all .NET Core Apps.

Registration

The new Identity Auth Admin UI is an example of this, which can be enabled when registering the AuthFeature Plugin:

public class ConfigureAuth : IHostingStartup
{
    public void Configure(IWebHostBuilder builder) => builder
        .ConfigureServices(services => {
            services.AddPlugin(new AuthFeature(IdentityAuth.For<ApplicationUser>(
                options => {
                    options.SessionFactory = () => new CustomUserSession();
                    options.CredentialsAuth();
                    options.AdminUsersFeature();
                })));
        });
}

Which just like the ServiceStack Auth Admin Users UI enables a Admin UI that's only accessible to Admin Users for managing Identity Auth users at /admin-ui/users.

User Search Results

Which displays a limited view due to the minimal properties on the default IdentityAuth model:

Custom Search Result Properties

These User's search results are customizable by specifying the ApplicationUser properties to display instead, e.g:

options.AdminUsersFeature(feature =>
{
    feature.QueryIdentityUserProperties =
    [
        nameof(ApplicationUser.Id),
        nameof(ApplicationUser.DisplayName),
        nameof(ApplicationUser.Email),
        nameof(ApplicationUser.UserName),
        nameof(ApplicationUser.LockoutEnd),
    ];
});

Custom Search Result Behavior

The default display Order of Users is also customizable:

feature.DefaultOrderBy = nameof(ApplicationUser.DisplayName);

As well as the Search behavior which can be replaced to search any custom fields, e.g:

feature.SearchUsersFilter = (q, query) =>
{
    var queryUpper = query.ToUpper();
    return q.Where(x =>
        x.DisplayName!.Contains(query) ||
        x.Id.Contains(queryUpper) ||
        x.NormalizedUserName!.Contains(queryUpper) ||
        x.NormalizedEmail!.Contains(queryUpper));
};

Default Create and Edit Users Forms

The default Create and Edit Admin Users UI are also limited to editing the minimal IdentityAuth properties:

Whilst the Edit page includes standard features to lockout users, change user passwords and manage their roles:

Custom Create and Edit Forms

By default Users are locked out indefinitely, but this can also be changed to lock users out to a specific date, e.g:

feature.ResolveLockoutDate = user => DateTimeOffset.Now.AddDays(7);

The forms editable fields can also be customized to include additional properties, e.g:

feature.FormLayout =
[
    Input.For<ApplicationUser>(x => x.UserName, c => c.FieldsPerRow(2)),
    Input.For<ApplicationUser>(x => x.Email, c => { 
        c.Type = Input.Types.Email;
        c.FieldsPerRow(2); 
    }),
    Input.For<ApplicationUser>(x => x.FirstName, c => c.FieldsPerRow(2)),
    Input.For<ApplicationUser>(x => x.LastName, c => c.FieldsPerRow(2)),
    Input.For<ApplicationUser>(x => x.DisplayName, c => c.FieldsPerRow(2)),
    Input.For<ApplicationUser>(x => x.PhoneNumber, c =>
    {
        c.Type = Input.Types.Tel;
        c.FieldsPerRow(2); 
    }),
];

That can override the new ApplicationUser Model that's created and any Validation:

Custom User Creation

feature.CreateUser = () => new ApplicationUser { EmailConfirmed = true };
feature.CreateUserValidation = async (req, createUser) =>
{
    await IdentityAdminUsers.ValidateCreateUserAsync(req, createUser);
    var displayName = createUser.GetUserProperty(nameof(ApplicationUser.DisplayName));
    if (string.IsNullOrEmpty(displayName))
        throw new ArgumentNullException(nameof(AdminUserBase.DisplayName));
    return null;
};

Admin User Events

Should you need to, Admin User Events can use used to execute custom logic before and after creating, updating and deleting users, e.g:

feature.OnBeforeCreateUser = (request, user) => { ... };
feature.OnAfterCreateUser  = (request, user) => { ... };
feature.OnBeforeUpdateUser = (request, user) => { ... };
feature.OnAfterUpdateUser  = (request, user) => { ... };
feature.OnBeforeDeleteUser = (request, userId) => { ... };
feature.OnAfterDeleteUser  = (request, userId) => { ... };

Boost your productivity. Start using our app today.

Incididunt sint fugiat pariatur cupidatat consectetur sit cillum anim id veniam aliqua proident excepteur commodo do ea.

Written by Lucy Bates
Works in software design, company building, and the aerospace industry.
More from Lucy Bates