5656import org .restlet .Component ;
5757import org .restlet .Context ;
5858import org .restlet .Server ;
59+ import org .restlet .data .ChallengeScheme ;
5960import org .restlet .data .Protocol ;
61+ import org .restlet .security .ChallengeAuthenticator ;
6062import org .restlet .security .MapVerifier ;
6163
6264
@@ -111,6 +113,13 @@ public class Heritrix {
111113 */
112114 private static final String STARTLOG = "heritrix_dmesg.log" ;
113115
116+ private enum AuthMode {
117+ DIGEST , BASIC ;
118+
119+ public String toString () {
120+ return name ().toLowerCase ();
121+ }
122+ }
114123
115124 private static void usage (PrintStream out , String [] args ) {
116125 HelpFormatter hf = new HelpFormatter ();
@@ -122,6 +131,8 @@ private static void usage(PrintStream out, String[] args) {
122131 private static Options options () {
123132 Options options = new Options ();
124133 options .addOption ("h" , "help" , true , "Usage information." );
134+ options .addOption (null , "web-auth" , true , "Authentication mode for the" +
135+ " web interface: " + Arrays .toString (AuthMode .values ()));
125136 options .addOption ("a" , "web-admin" , true , "REQUIRED. Specifies the " +
126137 "authorization username and password which must be supplied to " +
127138 "access the web interface. This may be of the form " +
@@ -237,6 +248,7 @@ public void instanceMain(String[] args)
237248 // DEFAULTS until changed by cmd-line options
238249 int port = 8443 ;
239250 Set <String > bindHosts = new HashSet <String >();
251+ AuthMode authMode = AuthMode .DIGEST ;
240252 String authLogin = "admin" ;
241253 String authPassword = null ;
242254 String keystorePath ;
@@ -330,6 +342,16 @@ public void instanceMain(String[] args)
330342 System .setProperty ("https.proxyPort" , proxyPort );
331343 }
332344
345+ if (cl .hasOption ("web-auth" )) {
346+ try {
347+ authMode = AuthMode .valueOf (cl .getOptionValue ("web-auth" ).toUpperCase ());
348+ } catch (IllegalArgumentException e ) {
349+ System .err .println ("Unsupported --web-auth value '" + cl .getOptionValue ("web-auth" ) +
350+ "' (must be one of " + Arrays .toString (AuthMode .values ()) + ")" );
351+ System .exit (1 );
352+ }
353+ }
354+
333355 // Restlet will reconfigure logging according to the system property
334356 // so we must set it for -l to work properly
335357 System .setProperty ("java.util.logging.config.file" , properties .getPath ());
@@ -373,9 +395,13 @@ public void instanceMain(String[] args)
373395 MapVerifier verifier = new MapVerifier ();
374396 verifier .getLocalSecrets ().put (authLogin , authPassword .toCharArray ());
375397
376- RateLimitGuard guard = new RateLimitGuard (component .getContext ().createChildContext (),
377- "Authentication Required" , UUID .randomUUID ().toString ());
378- guard .setWrappedVerifier (verifier );
398+ Context guardContext = component .getContext ().createChildContext ();
399+ ChallengeAuthenticator guard = switch (authMode ) {
400+ case BASIC -> new ChallengeAuthenticator (guardContext , false ,
401+ ChallengeScheme .HTTP_BASIC , "Authentication Required" , verifier );
402+ case DIGEST -> new RateLimitGuard (guardContext , "Authentication Required" ,
403+ UUID .randomUUID ().toString (), verifier );
404+ };
379405 guard .setNext (new EngineApplication (engine ));
380406
381407 component .getDefaultHost ().attach (guard );
0 commit comments