From 52ffc5a983f261570fd25f10f2f8fcf70d543c88 Mon Sep 17 00:00:00 2001 From: Furkan KAMACI Date: Sun, 19 Jun 2016 23:27:15 +0300 Subject: [PATCH 1/4] NUTCH-2284 Basic Authentication support for Nutch 2.X REST API. --- conf/nutch-default.xml | 26 ++++++++++++++++++ .../org/apache/nutch/api/NutchServer.java | 27 +++++++++++++++++-- 2 files changed, 51 insertions(+), 2 deletions(-) diff --git a/conf/nutch-default.xml b/conf/nutch-default.xml index 117737b373..f5111f7d77 100644 --- a/conf/nutch-default.xml +++ b/conf/nutch-default.xml @@ -1435,4 +1435,30 @@ + + restapi.auth + false + + Whether to enable HTTP basic authentication for communicating with RESTAPI. + Use the restapi.auth.username and restapi.auth.auth.password properties to configure + your credentials. + + + + + restapi.auth.username + login + + Username for HTTP basic authentication. restapi.auth should be true to use this property. + + + + + restapi.auth.password + secret1 + + Password for HTTP basic authentication. restapi.auth should be true to use this property. + + + diff --git a/src/java/org/apache/nutch/api/NutchServer.java b/src/java/org/apache/nutch/api/NutchServer.java index ea316a9b3a..3429beb2a6 100644 --- a/src/java/org/apache/nutch/api/NutchServer.java +++ b/src/java/org/apache/nutch/api/NutchServer.java @@ -45,10 +45,13 @@ import org.apache.nutch.api.resources.SeedResource; import org.restlet.Component; import org.restlet.Context; +import org.restlet.data.ChallengeScheme; import org.restlet.data.Protocol; import org.restlet.data.Reference; import org.restlet.ext.jaxrs.JaxRsApplication; import org.restlet.resource.ClientResource; +import org.restlet.security.ChallengeAuthenticator; +import org.restlet.security.MapVerifier; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -108,8 +111,28 @@ public NutchServer() { application.setStatusService(new ErrorStatusService()); childContext.getAttributes().put(NUTCH_SERVER, this); - // Attach the application. - component.getDefaultHost().attach(application); + boolean isSecure = configManager.get(ConfigResource.DEFAULT).getBoolean("restapi.auth", false); + + if (!isSecure) { + // Attach the application. + component.getDefaultHost().attach(application); + return; + } + + // Guard the restlet with BASIC authentication. + ChallengeAuthenticator guard = new ChallengeAuthenticator(null, ChallengeScheme.HTTP_BASIC, "testRealm"); + // Instantiates a Verifier of identifier/secret couples based on a simple Map. + MapVerifier mapVerifier = new MapVerifier(); + + // Load a single static login/secret pair. + String username = configManager.get(ConfigResource.DEFAULT).get("restapi.auth.username", "login"); + String password = configManager.get(ConfigResource.DEFAULT).get("restapi.auth.password", "secret"); + + mapVerifier.getLocalSecrets().put(username, password.toCharArray()); + guard.setVerifier(mapVerifier); + guard.setNext(application); + + component.getDefaultHost().attach(guard); } @Override From e147b43ac0551548acff14576e2156e3b5f7e9fa Mon Sep 17 00:00:00 2001 From: Furkan KAMACI Date: Sun, 26 Jun 2016 17:45:46 +0300 Subject: [PATCH 2/4] NUTCH-2285 Digest Authentication support for Nutch 2.X REST API. --- conf/nutch-default.xml | 17 ++++--- ivy/ivy.xml | 1 + .../org/apache/nutch/api/NutchServer.java | 46 +++++++++++++------ .../api/security/AuthenticationTypeEnum.java | 26 +++++++++++ 4 files changed, 70 insertions(+), 20 deletions(-) create mode 100644 src/java/org/apache/nutch/api/security/AuthenticationTypeEnum.java diff --git a/conf/nutch-default.xml b/conf/nutch-default.xml index f5111f7d77..6079343dc2 100644 --- a/conf/nutch-default.xml +++ b/conf/nutch-default.xml @@ -1437,27 +1437,30 @@ restapi.auth - false + NONE - Whether to enable HTTP basic authentication for communicating with RESTAPI. + Configures authentication type for communicating with RESTAPI. Valid values are BASIC, DIGEST and NONE. + When no authentication type is defined NONE will be used as default which does not provide security. Use the restapi.auth.username and restapi.auth.auth.password properties to configure - your credentials. + your credentials if security is used. restapi.auth.username - login + admin - Username for HTTP basic authentication. restapi.auth should be true to use this property. + Username for REST API authentication. restapi.auth property should be set to a valid authentication type use this property. + "nutch" is used for username as default. restapi.auth.password - secret1 + nutch - Password for HTTP basic authentication. restapi.auth should be true to use this property. + Password for REST API authentication. restapi.auth property should be set to a valid authentication type use this property. + "nutch" is used for password as default. diff --git a/ivy/ivy.xml b/ivy/ivy.xml index 5e2f5a3b78..db42162e90 100644 --- a/ivy/ivy.xml +++ b/ivy/ivy.xml @@ -79,6 +79,7 @@ + diff --git a/src/java/org/apache/nutch/api/NutchServer.java b/src/java/org/apache/nutch/api/NutchServer.java index 3429beb2a6..44bc2d5e3a 100644 --- a/src/java/org/apache/nutch/api/NutchServer.java +++ b/src/java/org/apache/nutch/api/NutchServer.java @@ -43,6 +43,7 @@ import org.apache.nutch.api.resources.DbResource; import org.apache.nutch.api.resources.JobResource; import org.apache.nutch.api.resources.SeedResource; +import org.apache.nutch.api.security.AuthenticationTypeEnum; import org.restlet.Component; import org.restlet.Context; import org.restlet.data.ChallengeScheme; @@ -51,6 +52,7 @@ import org.restlet.ext.jaxrs.JaxRsApplication; import org.restlet.resource.ClientResource; import org.restlet.security.ChallengeAuthenticator; +import org.restlet.ext.crypto.DigestAuthenticator; import org.restlet.security.MapVerifier; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -88,7 +90,12 @@ public class NutchServer extends Application { * well as the logging granularity. If the latter option is not provided via * {@link org.apache.nutch.api.NutchServer#main(String[])} then it defaults to * 'INFO' however best attempts should always be made to specify a logging - * level. + * level.
+ * {@link org.apache.nutch.api.NutchServer} can be run as secure. restapi.auth property + * should be set to BASIC or DIGEST at nutch-site.xml to enable HTTP basic authentication + * or digest authentication when communicating with RESTAPI. + * Use restapi.auth.username and restapi.auth.auth.password properties at nutch-site.xml to configure + * credentials when security is enabled with restapi.auth property. */ public NutchServer() { configManager = new RAMConfManager(); @@ -111,28 +118,41 @@ public NutchServer() { application.setStatusService(new ErrorStatusService()); childContext.getAttributes().put(NUTCH_SERVER, this); - boolean isSecure = configManager.get(ConfigResource.DEFAULT).getBoolean("restapi.auth", false); + AuthenticationTypeEnum authenticationType = configManager.get(ConfigResource.DEFAULT) + .getEnum("restapi.auth", AuthenticationTypeEnum.NONE); - if (!isSecure) { - // Attach the application. + if (authenticationType == AuthenticationTypeEnum.NONE) { + // Attach the application without security component.getDefaultHost().attach(application); return; } - // Guard the restlet with BASIC authentication. - ChallengeAuthenticator guard = new ChallengeAuthenticator(null, ChallengeScheme.HTTP_BASIC, "testRealm"); - // Instantiates a Verifier of identifier/secret couples based on a simple Map. MapVerifier mapVerifier = new MapVerifier(); - // Load a single static login/secret pair. - String username = configManager.get(ConfigResource.DEFAULT).get("restapi.auth.username", "login"); - String password = configManager.get(ConfigResource.DEFAULT).get("restapi.auth.password", "secret"); + String username = configManager.get(ConfigResource.DEFAULT).get("restapi.auth.username", "admin"); + String password = configManager.get(ConfigResource.DEFAULT).get("restapi.auth.password", "nutch"); mapVerifier.getLocalSecrets().put(username, password.toCharArray()); - guard.setVerifier(mapVerifier); - guard.setNext(application); - component.getDefaultHost().attach(guard); + if (authenticationType == AuthenticationTypeEnum.BASIC) { + ChallengeAuthenticator guard = new ChallengeAuthenticator(null, ChallengeScheme.HTTP_BASIC, "testRealm"); + + guard.setVerifier(mapVerifier); + guard.setNext(application); + // Attach the application with HTTP basic authentication security + component.getDefaultHost().attach(guard); + return; + } + + if (authenticationType == AuthenticationTypeEnum.DIGEST) { + DigestAuthenticator guard = new DigestAuthenticator(null, "Nutch REST API Realm", "NutchSecretKey"); + + guard.setWrappedVerifier(mapVerifier); + guard.setNext(application); + // Attach the application with digest authentication security + component.getDefaultHost().attachDefault(guard); + } + } @Override diff --git a/src/java/org/apache/nutch/api/security/AuthenticationTypeEnum.java b/src/java/org/apache/nutch/api/security/AuthenticationTypeEnum.java new file mode 100644 index 0000000000..cfbffea9a2 --- /dev/null +++ b/src/java/org/apache/nutch/api/security/AuthenticationTypeEnum.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + ******************************************************************************/ +package org.apache.nutch.api.security; + +/** + * Authentication enum which holds authentication types for NutchServer REST API. + */ +public enum AuthenticationTypeEnum { + BASIC, + DIGEST, + NONE +} From 38a636a190fc37051868f7ca101b3537057972ad Mon Sep 17 00:00:00 2001 From: Furkan KAMACI Date: Sun, 26 Jun 2016 20:49:31 +0300 Subject: [PATCH 3/4] NUTCH-2288 Upgrade Restlet to 2.3.7. --- ivy/ivy.xml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/ivy/ivy.xml b/ivy/ivy.xml index db42162e90..c909323d2a 100644 --- a/ivy/ivy.xml +++ b/ivy/ivy.xml @@ -76,10 +76,10 @@ - - - - + + + + From 65ba58276863d64bc679e2461a0c2d9a374f4c04 Mon Sep 17 00:00:00 2001 From: Furkan KAMACI Date: Mon, 4 Jul 2016 15:12:19 +0300 Subject: [PATCH 4/4] NUTCH-2288 Upgrade Restlet to 2.3.7. --- ivy/ivy.xml | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/ivy/ivy.xml b/ivy/ivy.xml index c909323d2a..5e2f5a3b78 100644 --- a/ivy/ivy.xml +++ b/ivy/ivy.xml @@ -76,10 +76,9 @@ - - - - + + +