suave
suave copied to clipboard
Support for a user object in the authenticate methods?
Usually when authenticating, we care about who is authenticated!
However, the current methods in Authentication support this only via context, which has some issues:
- Lacks type-safety
- Lacks null-safety
I propose a new combinator like this:
let authenticateBasicUserAsync (tryAuthenticate : string * string -> Async<'user option>) (makeProtectedPart : 'user -> WebPart) : WebPart =
fun ctx ->
async {
let p = ctx.request
match p.header "authorization" with
| Choice1Of2 header ->
let (typ, username, password) = parseAuthenticationToken header
if (typ.Equals("basic")) then
let! maybeUser = tryAuthenticate (username, password)
match maybeUser with
| Some user ->
return! makeProtectedPart user (addUserName username ctx)
| None ->
return! challenge ctx
else
return! challenge ctx
| Choice2Of2 _ ->
return! challenge ctx
}
The existing combinators can be defined in terms of this:
let authenticateBasicAsync (f : string * string -> Async<bool>) (protectedPart : WebPart) : WebPart =
authenticateBasicUserAsync
(fun (username, password) ->
async {
let! isAuthenticated = f (username, password)
if isAuthenticated then
return Some ()
else
return None
})
(fun () -> protectedPart)