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)

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions