Giraffe
Giraffe copied to clipboard
Question: Authentication for the new Endpoint Routing
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!
Hi, yes you should still be able to use that handler for an endpoint.
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
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 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: 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 , 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.
Neither did I til trying to solve this, but it seems to work out pretty well! Glad I could be of help :bow:
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.