% This LaTeX document was generated using the LaTeX backend of PlDoc,
% The SWI-Prolog documentation system



\subsection{library(http/http_authenticate): Authenticate HTTP connections using 401 headers}

\label{sec:httpauthenticate}

This module provides the basics to validate an HTTP \verb$Authorization$
header. User and password information are read from a Unix/Apache
compatible password file.

This library provides, in addition to the HTTP authentication,
predicates to read and write password files.\vspace{0.7cm}

\begin{description}
    \predicate{http_authenticate}{3}{+Type, +Request, -Fields}
True if \arg{Request} contains the information to continue according
to \arg{Type}. \arg{Type} identifies the required authentication technique:

\begin{description}
    \termitem{basic}{+PasswordFile}
Use HTTP \verb$Basic$ authetication and verify the password
from \arg{PasswordFile}. \arg{PasswordFile} is a file holding
usernames and passwords in a format compatible to
Unix and Apache. Each line is record with \verb$:$
separated fields. The first field is the username and
the second the password \textit{hash}. Password hashes are
validated using \predref{crypt}{2}.
\end{description}

Successful authorization is cached for 60 seconds to avoid
overhead of decoding and lookup of the user and password data.

\predref{http_authenticate}{3} just validates the header. If authorization
is not provided the browser must be challenged, in response to
which it normally opens a user-password dialogue. Example code
realising this is below. The exception causes the HTTP wrapper
code to generate an HTTP 401 reply.

\begin{code}
(   http_authenticate(basic(passwd), Request, Fields)
->  true
;   throw(http_reply(authorise(basic, Realm)))
).
\end{code}

\begin{arguments}
\arg{Fields} & is a list of fields from the password-file entry.
The first element is the user. The hash is skipped. \\
\end{arguments}

\begin{tags}
    \tag{To be done}
Should we also cache failures to reduce the risc of
DoS attacks?
\end{tags}

    \predicate[semidet]{http_authorization_data}{2}{+AuthorizeText, ?Data}
Decode the HTTP \verb$Authorization$ header. \arg{Data} is a term

\begin{code}
Method(User, Password)
\end{code}

where Method is the (downcased) authorization method (typically
\const{basic}), User is an atom holding the user name and Password is
a list of codes holding the password

    \predicate[nondet]{http_current_user}{3}{+File, ?User, ?Fields}
True when \arg{User} is present in the htpasswd file \arg{File} and \arg{Fields}
provides the additional fields.

\begin{arguments}
\arg{Fields} & are the fields from the password file \arg{File},
converted using \predref{name}{2}, which means that numeric values
are passed as numbers and other fields as atoms. The
password hash is the first element of \arg{Fields} and is
a string. \\
\end{arguments}

    \predicate[det]{http_read_passwd_file}{2}{+Path, -Data}
Read a password file. \arg{Data} is a list of terms of the format
below, where User is an atom identifying the user, Hash is a
string containing the salted password hash and Fields contain
additional fields. The string value of each field is converted
using \predref{name}{2} to either a number or an atom.

\begin{code}
passwd(User, Hash, Fields)
\end{code}

    \predicate[det]{http_write_passwd_file}{2}{+File, +Data:list}
Write password data \arg{Data} to \arg{File}. \arg{Data} is a list of entries as
below. See \predref{http_read_passwd_file}{2} for details.

\begin{code}
passwd(User, Hash, Fields)
\end{code}

\begin{tags}
    \tag{To be done}
Write to a new file and atomically replace the old one.
\end{tags}

\qpredicate[multifile]{http}{authenticate}{3}{+AuthData, +Request, -Fields}Plugin for \verb$library(http_dispatch)$ to perform basic HTTP
authentication.

This predicate throws \verb$http_reply(authorise(basic, Realm))$.

\begin{arguments}
\arg{AuthData} & must be a term \verb$basic(File, Realm)$ \\
\arg{Request} & is the HTTP request \\
\arg{Fields} & describes the authenticated user with the option
\verb$user(User)$ and with the option \verb$user_details(Fields)$ if
the password file contains additional fields after the
user and password. \\
\end{arguments}
\end{description}

