Posts Tagged ‘Python’

CherryPy Digest and Basic Authentication Tutorial

Monday, July 21st, 2008

Many applications require the use of password based authentication. In many web applications, this is done using cookies/sessions, and the login mechanism is an HTML form that is submitted to the application. If you are trying to build a RESTful web service, or any service where this client may be automated, It becomes useful to utilize HTTP authentication.

It may not be immediately obvious from the CherryPy documentation, but CherryPy includes all the tools needed to implement HTTP authentication, both Digest and Basic. You can see what the CherryPy website has documented about authentication at the CherryPy Builtin Tools Page. The best documentation for this is available in the book: CherryPy Essentials: Rapid Python Web Application Development

Basic vs Digest

HTTP supports two types of authentication, basic and digest. To a user accessing a protected page through a web browser, both types look the same. The browser will prompt the user for a username and password. The difference is how the client (browser) sends the password to the server.

With basic authentication, the client sends the password in clear-text, so any malicious attacker who can see the request can see the password. With digest authentication, the client does not send the password, but rather a digest based on the password and other factors. The server will also compute the digest using the known correct password. If the digest sent by the client matches the one calculated by the server, authentication succeeds.

The catch with digest authentication is the users’ passwords must be stored stored in clear-text on the server** in order to calculate the digest. On the flipside, basic authentication must send the password in clear-text through the network. If you are going to use basic authentication, it is recommended you use SSL to prevent the password from being sniffed.

** This is not entirely true, The digest algorithm allows you to store a partially digested password on the server side, however CherryPy has no easy way to specify this.

Digest Authentication

The following code creates a simple application with a public page and a secure page using digest authentication. The server configuration defines that the /secure url is to be protected with digest authentication (via the tools.digest_auth Tool available in CherryPy)

(more…)

Cherrypy Digest Auth POST problem (and solution!)

Friday, July 18th, 2008

When using Digest Authentication with Cherrypy, if a client tries to authenticate a session from a page with a POST body, the credentials will be rejected even if they are correct. This is due to how Cherrypy’s digest_auth tool handles the initial request and request body.

The Problem

In Cherrypy 3, when utlizing Digest Authentication (via tools.digest_auth), if the first request to a protected area comes from a POST request (with HTTP body), the client will not be able to authenticate properly.

Example: Posting from an HTML form to a protected action, the client will be prompted for credentials. After supplying a good username and password, Cherrypy will reject and the request and ask for credentials again.

The Cause

First a primer on Digest Authentication:

The Process

  1. The client requests a protected url URL (eg: /secret)
  2. The server tries to authenticate the request from the HTTP headers for the URL. There are not credentials, so this fails. The server replies with an HTTP Status code of 401: Not Authorized
  3. The client recieves this requests and gets a username and password (from an operator or database or other source)
  4. The client requests the URL again, but adds the credentials to the “Authorization” HTTP Header.
  5. The server tries again to authenticate. If the credentials are good, the resource at /secret is served. If authentication fails, The server responds with 401 …
  6. rinse and repeat..

(more…)