Giraffe
Giraffe copied to clipboard
authorizeRequest: Async or Task predicate
Yello.
Currently authorizeRequest expects a synchronous predicate : HttpContext -> bool. What do you think about adding an async version(s) of the predicate when we need to perform some IO in order to validate the request?
Hi, I think it is not needed, but because the authentication/authorization piece in ASP.NET Core is so fragmented it can be easily misunderstood so that one would like to have such a handler.
May I ask what is it that you'd be doing with authorizeRequestAsync?
Here is why I believe you might not need it:
- Use the policy based handlers to authorize a
ClaimsPrincipal:authorizeByPolicyNameandauthorizeByPolicyviaIAuthorizationService.AuthorizeAsyncwhich is alreadyasync - If you want to change how the principal is created in the first place (= authentication, not authorization) then you should create your own authentication handler which implements
IAuthenticationHandler. Check out this example.
My guess is that you probably want to do the latter. Unfortunately there is so much information scattered around the interent and ASP.NET (Core) that it can be hard to find one simple coherent example, if you struggle then let me know and I'll quickly knock out a very small example showing how it can be done with Giraffe!
I was trying to port some code from C#. The flow was: user makes a request to a service with his access token to access some resource, this service then delegates token validation to another service and then composes a response. I believe we had a custom IAuthenticationHandler in C#, but I wanted to simplify this flow as much as possible, so authorizeRequest seemed relevant (a couple of lines of code instead of creating a separate class, setting up the DI, etc.). Unfortunately I'm no longer involved in this project so this issue is no longer relevant for me.
I believe I may have found a use case for authorizeRequestAsync. We're using a custom implementation of it to do Google reCAPTCHA verification. Basically, this involves reading a token from the request (in our case, a query parameter) and POST-ing it to the reCAPTCHA service along with a secret key. If the reCAPTCHA service returns {"success": true , ...}, the request should be allowed.
Perhaps you're right @dustinmoris, that this would be better as an IAuthenticationHandler, but using authorizeRequestAsync feels more like staying in Giraffe land.
This is our implementation, in case it might be useful to someone:
let authorizeRequestAsync (predicate : HttpContext -> Async<bool>) (authFailedHandler : HttpHandler) : HttpHandler =
fun (next : HttpFunc) (ctx : HttpContext) ->
task {
let! isAuthorized = predicate ctx
return! (if isAuthorized then next else authFailedHandler earlyReturn) ctx
}
I have the same issue in the project I'm working on, the predicate function needs to access the DB and I want to do the DB stuff async, so I wrote something similar to what @jonekdahl wrote here. So +1 for this request. If it gets approved I can create a PR