HowTo setup Moin behind Apache with WSGI using HttpAuth for authentication and user creation

About this HowTo

MoinMoin versions
1.8
Platforms
Linux and other POSIX, Apache2

This summarizes some of my experiences.

Your wikiconfig.py

at the top (below the other import statements) add:

from MoinMoin.auth.http import HTTPAuth

in the security section set something like:

    user_autocreate = True  # this seems redundant -- yet i didn't test without it.
    auth = [HTTPAuth(autocreate=True)]  # important, without the True thingy it wont work.

Your apache setup

Put this in a VirtualHost directive:

     # use external authentication using "mod_authnz_external".
     # this method calls a script is wrote to authenticate agains gmails pop server.
     # every one with a valid @MYCOMPANY.COM gmail address is allowed access.
     # the (ruby) script takes care of the actual authentication process.

     AddExternalAuth googlepop /srv/ssmtp_gmail_auth/ssmtp_gmail_auth.rb
     SetExternalAuthMethod googlepop pipe
     <Location />
         AuthType Basic
         AuthName "This is shown in the users browser!"
         AuthBasicProvider external
         AuthExternal googlepop
         Require valid-user
     </Location>

     # the static files shipped with moin
     Alias /moin_static181 "/usr/local/share/moin/htdocs"
     <Directory /usr/local/share/moin/htdocs>
         Order allow,deny
         allow from all
     </Directory>

     # this directory i use for site specific static content (like the logo)
     Alias /static "/srv/MYCOMPANY_WIKI/static"
     <Directory /srv/MYCOMPANY_WIKI/static>
         Order allow,deny
         allow from all
     </Directory>

     # the wiki is on the root (/) so we have to do:
     Alias /robots.txt /usr/local/share/moin/htdocs/robots.txt
     Alias /favicon.ico /usr/local/share/moin/htdocs/favicon.ico
     WSGIScriptAlias / /srv/MYCOMPANY_WIKI/server/moin.wsgi
     # create some wsgi daemons - use someuser.somegroup same as your data_dir:
     WSGIDaemonProcess moin user=www-data group=www-data home=/srv/MYCOMPANY_WIKI processes=5 threads=10 maximum-requests=1000 umask=0007
     # for mod_wsgi >= 2.0 you can append this to have a nice ps aux display:
     #display-name=wsgi-moin

     # use the daemons we defined above to process requests!
     WSGIProcessGroup moin
     WSGIPassAuthorization On   # this is VERY important as without the username will not get passed to moin

You can use any 'auth' method that apache supplies. like mod_auth. i use this one because i like the fact that i don't have to create users.

The authentication scripts I used

You can use any method of authentication, but for the sake of completeness here the scripts I used with "mod_authnz_external". They're quite hackish and in ruby.

Using "mod_authnz_external" you can authenticate against anything.. like the weather forecasts of yahoo, or number of period characters on the slashdot.org page.

/srv/ssmtp_gmail_auth/ssmtp_gmail_auth.rb (see it on gist.github.com):

# author: Cies Breijs (cies on the kde.nl domain), 2009/jan, with ruby-1.8.7

# a simple authentication script to be used with some like mod_authnz_external
# auths a login/password pair against google's pop3 service

# many organizations use google (gmail) apps lately...
# why organize authentication for people if they can just use their
# google account credentials?

# # # authentication, done with an external script (authing against gmail)
# # AddExternalAuth googlepop /srv/ssmtp_gmail_auth/ssmtp_gmail_auth.rb
# # SetExternalAuthMethod googlepop pipe
# # <Location />
# # AuthType Basic
# # AuthName "Welcome to the authenticated domain"
# # AuthBasicProvider external
# # AuthExternal googlepop
# # Require valid-user
# # </Location>

# make sure you use SSL on the particular website you are securing
# otherwise your login info if flying plain text over the net

require 'rubygems'
require 'tlsmail' # install this: sudo gem install tlsmail

WHITELIST = [['cies', 'password']]
ACCEPTED_DOMAINS = ["blabla.net", "someotherdomain.co.com"]


# Get the login/password from the stdin
@login = STDIN.readline.strip.downcase
@pass = STDIN.readline.strip

# proper dieing with a message, from can be :success or :failed
def die(from, msg)
  STDERR.puts "[#{Time.now.to_s}] #{$0} #{(from == :success ? 'SUCCESS':'FAILED')} (#{@login}), #{msg}"
  exit 0 if from == :success # strange to have 0 for success, but ok
  exit 1
end

die(:success, 'whitelisted') if WHITELIST.include? [@login, @pass]

die(:failed, 'invalid domain') unless /(@#{ACCEPTED_DOMAINS.join('$|@')}$)/ =~ @login

begin
  Net::SMTP.enable_tls(OpenSSL::SSL::VERIFY_NONE)
  if s = Net::SMTP.start('smtp.gmail.com', 587, 'gmail.com', @login, @pass, :login)
    s.finish
    die(:success, 'authenticated against gmail')
  end
rescue # login errors always throw an exception
  die(:failed, "#{$!.class} -- #{$!.to_str[0..44]}")
end

die(:failed, 'UNDEFINED ERROR, should not happen...')

One could also make one using pythons 'ssmpt' library. But my python is rusty, and right now i just need to get it to work ;-)

Other things

I like moin, thanks to those who made it. Configuring is not too easy but that's okay with me.

Anyone who wants to contact me can sent me an email, im known as "cies" on the kde.nl domain.

MoinMoin: HowTo/Setup Moin with WSGI Apache HTTPAuth (last edited 2014-08-21 08:14:37 by sessfw99-sesbfw99-80)