From 073e6ccc7ba29e1391865107f105b8069352ee52 Mon Sep 17 00:00:00 2001 From: drbrain Date: Sat, 11 Sep 2010 06:21:51 +0000 Subject: Add documentation for WEBrick's DigestAuth git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@29224 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- lib/webrick/config.rb | 21 +++++++++++++++++ lib/webrick/httpauth/digestauth.rb | 48 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 69 insertions(+) (limited to 'lib') diff --git a/lib/webrick/config.rb b/lib/webrick/config.rb index 0fbb67f487..8c6427020d 100644 --- a/lib/webrick/config.rb +++ b/lib/webrick/config.rb @@ -82,6 +82,27 @@ module WEBrick :AutoReloadUserDB => true, } + ## + # Default configuration for WEBrick::HTTPAuth::DigestAuth. + # + # :Algorithm:: MD5, MD5-sess (default), SHA1, SHA1-sess + # :Domain:: An Array of URIs that define the protected space + # :Qop:: 'auth' for authentication, 'auth-int' for integrity protection or + # both + # :UseOpaque:: Should the server send opaque values to the client? This + # helps prevent replay attacks. + # :CheckNc:: Should the server check the nonce count? This helps the + # server detect replay attacks. + # :UseAuthenticationInfoHeader:: Should the server send an + # AuthenticationInfo header? + # :AutoReloadUserDB:: Reload the user database provided by :UserDB + # automatically? + # :NonceExpirePeriod:: How long should we store used nonces? Default is + # 30 minutes. + # :NonceExpireDelta:: How long is a nonce valid? Default is 1 minute + # :InternetExplorerHack:: Hack which allows Internet Explorer to work. + # :OperaHack:: Hack which allows Opera to work. + DigestAuth = { :Algorithm => 'MD5-sess', # or 'MD5' :Domain => nil, # an array includes domain names. diff --git a/lib/webrick/httpauth/digestauth.rb b/lib/webrick/httpauth/digestauth.rb index 1c6942be8b..3bae6f65e5 100644 --- a/lib/webrick/httpauth/digestauth.rb +++ b/lib/webrick/httpauth/digestauth.rb @@ -19,6 +19,30 @@ require 'digest/sha1' module WEBrick module HTTPAuth + + ## + # RFC 2617 Digest Access Authentication for WEBrick + # + # Use this class to add digest authentication to a WEBrick servlet. + # + # Here is an example of how to set up DigestAuth: + # + # config = { :Realm => 'DigestAuth example realm' } + # + # htpasswd = WEBrick::HTTPAuth::Htpasswd.new 'my_password_file' + # htpasswd.auth_type = WEBrick::HTTPAuth::DigestAuth + # htpasswd.set_passwd config[:Realm], 'username', 'password' + # htpasswd.flush + # + # config[:UserDB] = htpasswd + # + # digest_auth = WEBrick::HTTPAuth::DigestAuth.new config + # + # When using this as with a servlet be sure not to create a new DigestAuth + # object in the servlet's #initialize. By default WEBrick creates a new + # servlet instance for every request and the DigestAuth object must be + # used across requests. + class DigestAuth include Authenticator @@ -26,11 +50,27 @@ module WEBrick OpaqueInfo = Struct.new(:time, :nonce, :nc) attr_reader :algorithm, :qop + ## + # Used by UserDB to create a password entry + def self.make_passwd(realm, user, pass) pass ||= "" Digest::MD5::hexdigest([user, realm, pass].join(":")) end + ## + # Creates a new DigestAuth instance. Be sure to use the same DigestAuth + # instance for multiple requests as it saves state between requests in + # order to perform authentication. + # + # See WEBrick::Config::DigestAuth for default configuration entries + # + # You must supply the following configuration entries: + # + # :Realm:: The name of the realm being protected. + # :UserDB:: A database of usernames and passwords. See Htpasswd, + # Htdigest, Htgroup + def initialize(config, default=Config::DigestAuth) check_init(config) @config = default.dup.update(config) @@ -62,6 +102,10 @@ module WEBrick @mutex = Mutex.new end + ## + # Authenticates a +req+ and returns a 401 Unauthorized using +res+ if + # the authentication was not correct. + def authenticate(req, res) unless result = @mutex.synchronize{ _authenticate(req, res) } challenge(req, res) @@ -72,6 +116,10 @@ module WEBrick return true end + ## + # Returns a challenge response which asks for for authentication + # information + def challenge(req, res, stale=false) nonce = generate_next_nonce(req) if @use_opaque -- cgit v1.2.3