Skip to content

API Authentication methods

Erik Huelsmann edited this page May 14, 2017 · 3 revisions

Goal

This document lays out the various planned types of authentication for both the web application and the web services. While the web services will have to service the existing web application (to provide data sources for the Dojo widgets), it will also be used to integrate with other applications.

Current design

The LedgerSMB web application forwards authentication as well as authorization to the database backend. In order to do so, it creates a user-specific connection to the database. To that extent, it needs to have the user's database credentials available. As HTTP is stateless, these credentials need to be available on each request.

With that requirement, the following authorization schemes can be implemented with LedgerSMB:

  1. Basic authentication
  2. TLS client-side certificates
  3. Kerberos/GSSAPI

Each of these methods directly maps to the authentication options in PostgreSQL. Digest AUTH can't be supported because the user credentials aren't accessible at any point during the authentication process.

Sessions

Upon successful authentication, a session is created. Session state is stored in a cookie; the company database maintains the session token as a means for verification. The primary piece of information stored in the session is the name of the company which was last logged into successfully.

Problems to be resolved

With the current design, most users end up using Basic AUTH from the web UI. There are three problems due to the use of Basic AUTH which want to be reconsidered when redesigning:

  1. Basic AUTH requires returning 404 responses; the web application can't prevent the browser from popping up the auth dialog
  2. Issuing a successful password change request requires the Basic AUTH creds being sent to be changed -- on some browsers the auth dialog popup can't be prevented/suppressed
  3. Logging out is being achieved by removing the session cookie and returning a 404 response to clear the browser creds; again, there's no control over the popup being shown

Target design

Requirements

The authentication scheme used for the API needs to fit two needs:

  1. Support for the (pre-authenticated, cookie-session based) web UI
  2. Support for per-request (ad-hoc) authentication

The latter requirement stems from the requirement to support non-cookie-based single-shot API calls from (non-UI) clients.

Ideally, the design would allow circumventing the problems listed above.

Proposed solution for cookie-session based auth (no Basic AUTH)

The API can provide an entrypoint /api/<company-name>/session/ which the session-based software can issue a POST request to in order to log in at the specified company. The response will be a redirect to a session object for the specified user/company combination in case the provided password has been accepted. The response will include a session-state cookie. The cookie will be encrypted session state using Session::Storage::Secure. The encrypted session state includes the (encrypted) username and (encrypted) password. Plack::Middleware::Session::SerializedCookie can be used to integrate this scheme into Plack's middlewares.

Upon logout, the client can issue a DELETE request to delete the session resource from the server. The response from the server issues a cookie clean-up action (valid-until date/time before the current date/time).

No other API entry-point under this scheme accepts requests without pre-authenticated session cookie.

This scheme prevents the problems with the Basic AUTH popup, because the server isn't forced to issue 404 responses in order to make the client authenticate.

Proposed solution for session-less ad-hoc authentication (incl Basic AUTH)

Under this scheme, there is no pre-authenticated cookie (not even an expired one). Additionally, there must be a header X-LedgerSMB-API with the value REQUEST. In this case the following authentication methods will be accepted:

  1. Basic AUTH
  2. TLS Client certificate
  3. Kerberos AUTH

The additional header exists to prevent CSRF (cross site request forgery) requests from being issued by malicious parties who injected JS in the client browser, but do not control the server domain.