I was looking at idsrv4 and how to integrate it with a custom user store. In this case it was SQL Server.
idsrv4 uses .NET Core 2.2 but a lot of the samples I found were for earlier versions of .Net Core.
Some of the samples used IUserService but I couldn't find that.
So Mr Google to the rescue.
"In IdentityServer4. IUserService is not available anymore, now you have to use IResourceOwnerPasswordValidator to do the authentication and to use IProfileService to get the claims."
The problem I have with this is that Resource Owner Password is not just a random method name. It's the name of an OAuth flow! Most people don't realise this.
My client used implicit flow. Using IResourceOwnerPasswordValidator makes no sense.
So you can just use a controller to authenticate the user like the AccountController.