Search code examples
owincustomizationbasic-authenticationnancy

How to replace NancyFx Basic Authentication with our Custom Authentication?


We are forced to use NancyFX, either 1.4.4 or 2.0.0. We are using .NET Framework 4.7.2 and Visual Studio 2019. The solution is self-hosted in OWIN and runs on Windows Server 2012 R2 or 2016.

The current source code uses Nancy.Authentication.Basic.1.4.1, and we are being forced to replace it with our own custom authentication (to bypass browser HTTP 401 handling, for example) that retrieves a custom security token from an external system after either a user enters their credentials on our new custom login View or an external app calls our API with their creds.

I have read various posts on the internet about stateless and token authentication in Nancy, and OWIN JWT, and also these SO posts:

I have also downloaded samples, but nothing seems to work right or easily.

The current code has this in the CustomBootstrapper:

pipelines.EnableBasicAuthentication(new BasicAuthenticationConfiguration(
                                    container.Resolve<IUserValidator>(),
                                    "OurRealm"));

Since the code is already set up to use this.RequiresAuthentication() and ICurrentUser, and I have successfully commented out the above code and temporarily placed UserValidator's code in one of my Module's Get (just to prove it works), now I need to remove my temporary call and replace the bootstrapper code to call UserValidator.

I was thinking of downloading the Nancy source code and adding our own CustomAuthentication, but I have the feeling that is not the best or easiest way. Any Nancy gurus out there who can answer this please?


Solution

  • I created a BaseViewerModule that inherits from NancyModule and changed all my modules to inherit the base. I then added a check to see if the user's request includes a security token, and if not, displays a login form, calls my authentication server, stores a UserIdentity in the cache with the security token as the key, and returns the token back to the requested module.

    I then added a hook into pipelines.BeforeRequest to check for the existence of the item in the cache and set the CurrentUser to it if found.