Skip to content

Support for a user object in the authenticate methods? #779

Description

@njlr

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)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions