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.