Giraffe icon indicating copy to clipboard operation
Giraffe copied to clipboard

Question: Authentication for the new Endpoint Routing

Open nasko90 opened this issue 4 years ago • 7 comments

Hello guys, I failed to find any information/documentation about how one could implement the Authentication with ASP.NET Core's Endpoint Routing. Is it possible to use the requiresAuthentication (authFailedHandler : HttpHandler) http handler. Thanks!

nasko90 avatar May 26 '21 09:05 nasko90

Hi, yes you should still be able to use that handler for an endpoint.

dustinmoris avatar May 28 '21 07:05 dustinmoris

Hello, would you mind to give an example? Let's imagine this router

open Giraffe
open Giraffe.EndpointRouting

module Router =
    let endpoints : Endpoint list = [
        route "/ping" (text "pong")
        route "/"     (text "index")
        subRoute "/protected" [
            GET [
                route "/hello" (text "hello")
            ]
        ]
    ]

How can I use requiresAuthentication on protected sub-route?

ilog2000 avatar Jun 27 '22 22:06 ilog2000

@ilog2000

You can compose it into the route list similar to other handlers:

let webApp =
    choose [
        route "/ping"   >=> text "pong"
        route "/"       >=> htmlView indexView
        requiresAuthentication (text "failed") >=>
            subRoute "/protected"
                (choose [
                    GET >=> choose [
                        route "/hello" >=> text "hello" ]])]

Banashek avatar Jul 03 '22 21:07 Banashek

@Banashek thank you for the tip. My question is about the latest EndpointRouting. I know that it works this way:

        subRoute "/restricted" [
            route "/test" (requiresAuthentication (text "failed") >=> handler1)
        ]

But I should repeat it for every protected route handler. So I wonder how to do this for subRoute? This code doesn't work

    requiresAuthentication (text "failed") >=>
        subRoute "/protected" [
            route "/test" handler1
        ]

ilog2000 avatar Jul 07 '22 08:07 ilog2000

@ilog2000: very sorry, I did misunderstand your question.

I think that using applyBefore (which composes an HttpHandler into the subsequent route) could help in this scenario. I've created a more drawn out example with different subroutes protected by either api key or authentication.


let validateApiKey (ctx : HttpContext) =
    match ctx.TryGetRequestHeader "X-API-Key" with
    | Some key -> "super-sercret-key".Equals key
    | None     -> false

let accessDenied   = setStatusCode 401 >=> text "Access Denied"
let requiresApiKey =
    authorizeRequest validateApiKey accessDenied

let protectedByApiKeyList : Endpoint list =
    let addApiKeyCheck = applyBefore requiresApiKey
    [
        route "/test1" (text "test1")
        route "/test2" (text "test2")
    ] |> List.map addApiKeyCheck

let protectedByAuthList : Endpoint list =
    let addAuthenticationCheck = applyBefore (requiresAuthentication (text "auth failed"))
    [
        route "/test1" (text "test1")
        route "/test2" (text "test2")
    ] |> List.map addAuthenticationCheck

let endpoints : Endpoint list =
    [
        GET [
            route "/ping" (text "pong")
            route "/"     (htmlView <| Views.index { Text = "foo" })
            subRoute "/protectedByApiKey" protectedByApiKeyList
            subRoute "/protectedByAuth" protectedByAuthList ]]

Let me know if that helps, or if there is another aspect of it that I may be missing.

Banashek avatar Jul 07 '22 18:07 Banashek

@Banashek , thank you very much. I really like this solution - it's clear and well separated into specific areas. And I did not know about applyBefore.

ilog2000 avatar Jul 07 '22 22:07 ilog2000

Neither did I til trying to solve this, but it seems to work out pretty well! Glad I could be of help :bow:

Banashek avatar Jul 07 '22 23:07 Banashek

Hey people, I'm considering that @dustinmoris and @Banashek already answered this issue, so I'll close it with this comment. If you think there's still something lacking, please open a new issue so we can investigate it properly.

64J0 avatar Apr 04 '24 21:04 64J0