Multiple instances of Auth Repository

We have an existing service stack web api that utilises credentials auth provider and the OrmLiteAuthRepository registered in our IoC container for the usual UserAuth and UserAuthDetails poco types.

We now have a requirement to use apiKeys that do not associate with a user record but rather a custom company record. The reasons for this are many and complex but ultimately it is due to legacy code that would be prohibitively expensive to rework. Once the api keys are validated, and the client authenticated, a user record would then be dynamically created (for that company), a token generated and returned to the client for subsequent request authentication.

Ideally, I would like to create another OrmLiteAuthRepository targeting the Company (and CompanyAuthDetails) poco so that the apiKey(s) can be associated with them. I would then implement a custom “Company” ApiKeyAuthProvider that validates the keys. However, I’m not certain how to differentiate one AuthRepository from another even though I can register them in the IoC container. The ServiceStackHost (and thus AppHost) looks up the IAuthRepository interface in the container (via GetAuthRepository()) and the caller casts the returned object to the appropriate interface (e.g. IUserAuthRepository or IManageApiKeys) in the relevant auth provider. This (perhaps wrongly) suggests to me that expected/standard use would be to have one AuthRepository registered.

It seems that I could attain what I want by overriding the Auth Provider (and associated services - *ApiKeysService) methods that call ServiceStackHost.GetAuthRepository() (e.g. for ApiKeyAuthProvider - Register(), IsAuthorized(), Authenticate(), etc.) and but I’m wondering if that’s a reasonable approach or if there’s a better solution. Any advice appreciated.

You can only have 1 IAuthRepository registered in the IOC but you could change which IAuthRepository gets used (e.g. IAuthRepository or your 2nd Auth Provider registered against its concrete class) by overriding GetAuthRepositoryAsync() in your IAppHost and inspecting the incoming IRequest. Note: you can access the Request DTO for that request from IRequest.Dto.

Although given your custom API Key requirements I’d probably recommend using a local modified copy of ApiKeyAuthProvider.cs customized to support your specific requirements.

The other customization option would be to register a custom IAuthRepository adapter implementation where each API does a check to delegate between forwarding the request to 2 different AuthProvider implementations but I’d suspect that would be a lot more work, for your use-case with custom API Key requirements I’d likely go with a local modified copy of ApiKeyAuthProvider.

Thanks @mythz, those suggestions were very helpful. I think you might be right about the local “copy/fork” of the ApiKeyAuthProvider.

1 Like