Monday, 22 November 2010

EEE: erlang inets http authentication with mnesia

Again, I am using R13B04 (erts-5.7.5) on Fedora 13.

Unfortunately erlang's inets http server only performs Basic authentication.  So I would only authenticate over https, like I've shown here.  Setting up erlang inets for SSL can be tricky depending on what you want to do.  One important gotcha is detailed in this post.

Create Tables

First, your application must create some mnesia tables for authentication. For this you need the record definitions.  The documentation for mod_auth says to add the following line to your module.

-include("mod_auth.hrl").

erlc failed to find the file, so I found it in "/usr/lib64/erlang/lib/inets-5.3/src/" and copied it to my project manually.

Creating the tables is no different to the documentation

mnesia:create_schema([node()]),
    mnesia:start(),
    mnesia:create_table(httpd_user,
                        [{type, bag},
                         {disc_copies, [node()]},
                         {attributes, record_info(fields, 
                                                  httpd_user)}]),
    mnesia:create_table(httpd_group,
                        [{type, bag},
                         {disc_copies, [node()]},          
                         {attributes, record_info(fields, 
                                                  httpd_group)}]),
    mnesia:wait_for_tables([httpd_user, httpd_group], 60000).

The documentation says this is a naive implementation, a trick I have used is to catch the output of mnesia:create_schema.  Ok means that the schema didn't exist before and the tables have to be created.  If there is a better way, I'd like to hear it.

Add user and group

Next, adding a user and group to the database, I use the mod_auth functions

true = mod_auth:add_user("superuser", "password", "Super User", 443, "/test"),
true = mod_auth:add_group_member("users", "superuser", 443, "/test").

Configuring for Authentication

Below is the next version of my "443.conf" file which includes the necessary configuration for authentication.

[
 {modules, [
  mod_alias, 
  mod_auth, 
  mod_esi, 
  mod_actions, 
  mod_cgi, 
  mod_dir, 
  mod_get, 
  mod_head, 
  mod_log, 
  mod_disk_log
 ]},
 {port,443},
 {server_name,"localhost.localdomain"},
 {server_root,"log"},
 {document_root,"secure"},
 {erl_script_alias, {"/test", [test]}},
 {directory, 
  {"/test", [
   {auth_name, "Data Server"}, 
   {allow_from, all}, 
   {auth_type, mnesia},
   {require_group, ["users"]}
  ]}
 },
 {socket_type, ssl},
 {ssl_certificate_file, "localhost.pem"},
 {error_log, "error.log"},
 {security_log, "security.log"},
 {transfer_log, "transfer.log"},
 {mime_types,[
  {"html","text/html"},
  {"css","text/css"},
  {"js","application/x-javascript"}
 ]}
]. 

To access my test esi module, I now need a to use a password.

No comments: