AdminUI offers a couple of webhooks enabling it to tightly integrate with your own custom user onboard or password reset journies...
Currently, there are two webhook events available in AdminUI: User Registration and Password Reset. By enabling these webhooks you can implement a custom workflow instigated by AdminUI and implemented inside IdentityServer or any other application. Enabling custom code to be invoked when a user is created, to perhaps complete the onboarding process.
The webhook pattern is essentially the ability for code outside AdminUI to be triggered on an event inside AdminUI via HTTP. When an event occurs in AdminUI such as new user has been created, an HTTP request can be sent to another application informing it of the event inside AdminUI. The informed application can then perform additional steps, such as sending an email to the user to set their password to complete the registration process.
In this post, a password reset webhook is set up to use an API secured by IdentityServer4. Enabling a custom password reset flow within the AdminUI User Management screens. The necessary parts for this solution are IdentityServer4 implementation, AdminUI 2.x, and a protected resource (API) that will act as the webhook. The API could be part of your IdentityServer or an api implemented inside another web-hosted solution. In this article, I have created an API from scratch.
Setting up a Webhook Client within in IdentityServer
First, set up a client configuration in IdentityServer using AdminUI. This will be the client that will send notifications to the webhook.
This client is actually the AdminUI API. There are no users involved in the call, so you it will be a “Machine-to-Machine” Client.
The client needs access to the “adminuiwebhooks” Protected Resource. As this API will only be implementing the webhooks.
Completing the process, create a client secret, and record this for later use.
Creating an API to consume a Webhook
Once the IdentityServer side is set up create an endpoint to subscribe to the webhook. This endpoint could be anywhere. It could be within your IdentityServer code, or it could be on a separate system entirely.
For this example, we have created a simple ASP.Net Core web API application to handle these webhooks.
In order to secure this client using IdentityServer, Enable the IdentityServer Authorization pipeline in the startup.cs, available in the IdentityServer4.AccessTokenValidation
nuget library.
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc();
services.AddAuthentication("Bearer")
.AddIdentityServerAuthentication(options =>
{
options.Authority = "http://localhost:5003";
options.RequireHttpsMetadata = false;
options.ApiName = "admin_ui_webhooks";
});
}
The Authority field is the where your IdentityServer is hosted. In this case, I’m hosting it on http://localhost:5003
.
The API name admin_ui_webhooks
is needed as that’s the resource name that was assigned when setting up the Client in AdminUI.
Set up the Policy webhooks
inside Startup.cs in order to secure the controller so that only authorized clients can invoke it.
services.AddAuthorization(options =>
{
options.AddPolicy("webhook", builder =>
{
builder.AddAuthenticationSchemes("Bearer");
builder.RequireScope("admin_ui_webhooks");
});
});
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
app.UseAuthentication();
app.UseMvc();
}
Now the API security is setup create the endpoint to register to the webhook. Looking at the docs for the endpoints, we can see the endpoint needs to Accept POST, JSON, and an email within the body.
Now, create a controller and secure it as follows controller along with a DTO object for our API we now have a complete webhook.
[Route("api/[controller]")]
[ApiController]
public class PasswordResetController : ControllerBase
{
[Authorize("webhook")]
[HttpPost]
public IActionResult PasswordReset([FromBody]PasswordResetDTO dto)
{
if (string.IsNullOrEmpty(dto.email))
{
return BadRequest("Invalid email");
}
return Ok();
}
}
public class PasswordResetDTO
{
public string email;
}
Within this call, you can implement whatever code you need when a password reset is requested by AdminUI. For example, we would generate a password reset token and email the user a link to change their password; a useful option when on the phone to a customer. Likewise, with the registration webhook, we could send the user an email to set their password and confirm their email address.
Enabling the Webhook in AdminUI
Finally, in order to use this webhook in AdminUI, we’ll need to enable the webhooks in the config for AdminUI.
You can do this how you usually change the config files, either by IIS, modifying the appsettings.json file, or updating your docker container config settings.
The “PasswordResetEndpoint” and the “RegistrationConfirmationEndpoint” are the two fields that hold the respective endpoints. The ClientId and the ClientSecret are for the Client we created within AdminUI to retrieve an access token for authorization.
Configuring these settings will cause a password reset button to appear on the user details page, allowing us to trigger this webhook functionality (you may need to reload the app in your browser to see this).
Full source code for the implementation of the webhook API can be found here.