giraffe-fsharp / Giraffe

A native functional ASP.NET Core web framework for F# developers.
https://giraffe.wiki
Apache License 2.0
2.12k stars 266 forks source link

How to use multiple authentication schemes? #405

Open juselius opened 4 years ago

juselius commented 4 years ago

I need two different authentication schemes in one application. Some users are logged in via Kerberos using Negotiate, and some are authenticated using CookieAuthentication. If I set AuthenticationOptions.DefaultScheme <- "Negotiate", CookieAuthentication stops working (explicitly calling challenge "Cookies") and vice versa.

In C# there is an attribute [Authorize(AuthenticationSchemes ="Cookies")] which supposedly does the trick. I'm guessing the Giraffe equivalent should be requireAuthentication (challenge "Cookies"), without having looked at the C# code.

dustinmoris commented 4 years ago

Hi, quick question what do you want to happen when a user is not authentiated? Should your application challenge them to present a cookie or to log in via Kerberos? Or is it dependent which route they have tried to access?

juselius commented 4 years ago

Depending on the route (intranet or external), the application will either ask the user sign in, if they don't have a valid cookie or JWT, or automagically sign them in using a Kerberos negotiate challenge.

dustinmoris commented 4 years ago

In this case you have two options how to accomplish it:

Either way, you'll have to write a fairly simply logic yourself where you check an incoming HTTP request to have one of your accepted authentication methods and then validate that scheme accordingly.

baronfel commented 4 years ago

@juselius you can look at #394 for an example of enforcing multiple auth methods if you need some inspiration.

juselius commented 4 years ago

Thanks! I already had a look at #394. I think the gist can serve as a good starting point for a custom middleware. But it would be nice to get #394 into the mainline Giraffe. If I find the time, and can give it a shot.

dustinmoris commented 4 years ago

Agreed I think that would be a pretty common use case to want to support multiple auth schemes.

bsheldrick commented 2 years ago

Further to this it would be nice to support using AuthenticationProperties to the common authentication functions e.g. challenge, forbid, signIn, signOut.

Example for challenge:

let challengeWithProps scheme props : HttpHandler =
    fun next ctx ->
        task {
            do! ctx.ChallengeAsync(scheme, props)
            return! next ctx
        }