#!/usr/bin/env ruby # # httpd-auth.rb -- a sample of WEBrick::HTTPAuth::* # # SYNOPSIS # httpd-auth.rb [-p port] [--digest] [--hash_db] [--proxy] # # -p port specify the port number (default 8808). # --digest use digest access authentication. # --hash_db use a Hash as a user database. # --proxy testing proxy access authentication. # the proxy server will listen port+1. $:.unshift('../../lib') require 'webrick' require 'webrick/httpproxy' require 'getopts' getopts nil, 'p:8808', 'digest', 'hash_db', 'proxy' dir = File::dirname(File::expand_path(__FILE__)) def print_userdb(realm, userdb) puts "-- #{realm} --" p userdb userdb.each{|item| puts item.join(":") } end # choose authentication scheme if $OPT_digest Authenticator = WEBrick::HTTPAuth::DigestAuth ProxyAuthenticator = WEBrick::HTTPAuth::ProxyDigestAuth else Authenticator = WEBrick::HTTPAuth::BasicAuth ProxyAuthenticator = WEBrick::HTTPAuth::ProxyBasicAuth end if $OPT_hash_db # use a Hash as a UserDB. userdb = Hash.new userdb.extend(WEBrick::HTTPAuth::UserDB) userdb.auth_type = Authenticator else # use Apache compatible passwd database file if $OPT_digest UserDB = WEBrick::HTTPAuth::Htdigest filename = "htdigest" else UserDB = WEBrick::HTTPAuth::Htpasswd filename = "htpasswd" end path = File::join(dir, "conf", filename) userdb = UserDB.new(path) end # setup user/passwd info realm = "authtest" userdb.set_passwd(realm, "system", "manager") userdb.set_passwd(realm, "user", "passwd") userdb.set_passwd(realm, "guest", "guest") print_userdb(realm, userdb) # use group database file grpdb = WEBrick::HTTPAuth::Htgroup.new(File::join(dir, "/conf/htgroup")) grpdb.add("admin", [ "system", "user" ]) grpdb.add("guest", [ "guest" ]) grpdb.flush authenticator = Authenticator.new({ :Realm => realm, :UserDB => userdb, #:Algorithm => 'MD5', #:Algorithm => 'MD5-sess', #:Qop => [ 'auth' ], #:Qop => [ 'auth-int' ], #:Qop => [ 'auth', 'auth-int' ], # cannot use againt w3m. #:UseOpaque => false, #:CheckNc => true, #:UseNextNonce => true, #:UseAuthenticationInfoHeader => false, #:IntenetExplorerHack => false, #:OperaHack => false, :NonceExpirePeriod => 60, :NonceExpireDelta => 5, }) if $OPT_proxy require 'webrick/httpproxy' proxy_realm = "proxy_auth" proxy_userdb = { "qw" => "as" } proxy_userdb.extend(WEBrick::HTTPAuth::UserDB) proxy_userdb.auth_type = Authenticator print_userdb(proxy_realm, proxy_userdb) proxy_authenticator = ProxyAuthenticator.new( :Realm => proxy_realm, :UserDB => proxy_userdb ) ps = WEBrick::HTTPProxyServer.new( :Port => $OPT_p.to_i + 1, :ServerType => Thread, :ProxyAuthProc => lambda{|req, res| #p req['authorization'] #p req['proxy-authorization'] proxy_authenticator.authenticate(req, res) } ) ps.start end class Authlet < WEBrick::HTTPServlet::AbstractServlet def initialize(server, authenticator, groupdb) @a = authenticator @g = groupdb end def do_GET(req, res) @a.authenticate(req, res) unless @g.members('admin').member?(req.user) @a.logger.error("#{req.user} is unauthorized.") @a.challenge(req, res) end res['content-type'] = "text/html" res.body = "OK" end end s = WEBrick::HTTPServer.new( :BindAddress => "0.0.0.0", :Port => $OPT_p.to_i ) s.mount("/", Authlet, authenticator, grpdb) trap("INT"){ ps.shutdown if $OPT_proxy s.shutdown } s.start