ashishkumar50 commented on code in PR #4523:
URL: https://github.com/apache/ozone/pull/4523#discussion_r1166352174
##########
hadoop-ozone/s3gateway/src/main/java/org/apache/hadoop/ozone/s3/S3GatewayHttpServer.java:
##########
@@ -18,29 +18,88 @@
package org.apache.hadoop.ozone.s3;
import java.io.IOException;
-
-import org.apache.hadoop.hdds.conf.MutableConfigurationSource;
-import org.apache.hadoop.hdds.server.http.BaseHttpServer;
-
+import java.util.HashMap;
+import java.util.Map;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
+import org.apache.hadoop.hdds.conf.MutableConfigurationSource;
+import org.apache.hadoop.hdds.server.http.BaseHttpServer;
+import org.apache.hadoop.hdds.server.http.ServletElementsFactory;
+import org.apache.hadoop.security.SecurityUtil;
+import org.apache.hadoop.security.UserGroupInformation;
+import org.apache.hadoop.security.authentication.server.AuthenticationFilter;
+import org.eclipse.jetty.servlet.FilterHolder;
+import org.eclipse.jetty.servlet.FilterMapping;
+import org.eclipse.jetty.servlet.ServletHandler;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import static
org.apache.hadoop.ozone.s3secret.S3SecretConfigKeys.OZONE_S3G_SECRET_HTTP_AUTH_TYPE;
+import static
org.apache.hadoop.ozone.s3secret.S3SecretConfigKeys.OZONE_S3G_SECRET_HTTP_BIND_HOST_KEY;
+import static
org.apache.hadoop.ozone.s3secret.S3SecretConfigKeys.OZONE_S3G_SECRET_HTTP_ENABLED_KEY;
+import static
org.apache.hadoop.ozone.s3secret.S3SecretConfigKeys.OZONE_S3G_SECRET_KEYTAB_FILE;
+import static
org.apache.hadoop.ozone.s3secret.S3SecretConfigKeys.OZONE_S3G_SECRET_WEB_AUTHENTICATION_KERBEROS_PRINCIPAL;
/**
- * S3 Gateway specific configuration keys.
+ * Http server to provide S3-compatible API.
*/
public class S3GatewayHttpServer extends BaseHttpServer {
+ private static final Logger LOG =
+ LoggerFactory.getLogger(S3GatewayHttpServer.class);
+
/**
* Default offset between two filters.
*/
public static final int FILTER_PRIORITY_DO_AFTER = 50;
public S3GatewayHttpServer(MutableConfigurationSource conf,
- String name) throws IOException {
+ String name) throws IOException {
super(conf, name);
addServlet("icon", "/favicon.ico", IconServlet.class);
+ addSecretAuthentication(conf);
+ }
+
+ private void addSecretAuthentication(MutableConfigurationSource conf)
+ throws IOException {
+
+ if (conf.getBoolean(OZONE_S3G_SECRET_HTTP_ENABLED_KEY, false)) {
+ String authType = conf.get(OZONE_S3G_SECRET_HTTP_AUTH_TYPE, "simple");
+
+ if (UserGroupInformation.isSecurityEnabled()
+ && authType.equals("kerberos")) {
+ ServletHandler handler = getWebAppContext().getServletHandler();
+ Map<String, String> params = new HashMap<>();
+
+ String principalInConf =
+ conf.get(OZONE_S3G_SECRET_WEB_AUTHENTICATION_KERBEROS_PRINCIPAL);
+ if (principalInConf != null && !principalInConf.isEmpty()) {
Review Comment:
nit: Better use Strings.isNullOrEmpty() instead of checking null and
isEmpty().
##########
hadoop-ozone/s3gateway/src/main/java/org/apache/hadoop/ozone/s3/S3GatewayHttpServer.java:
##########
@@ -18,29 +18,88 @@
package org.apache.hadoop.ozone.s3;
import java.io.IOException;
-
-import org.apache.hadoop.hdds.conf.MutableConfigurationSource;
-import org.apache.hadoop.hdds.server.http.BaseHttpServer;
-
+import java.util.HashMap;
+import java.util.Map;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
+import org.apache.hadoop.hdds.conf.MutableConfigurationSource;
+import org.apache.hadoop.hdds.server.http.BaseHttpServer;
+import org.apache.hadoop.hdds.server.http.ServletElementsFactory;
+import org.apache.hadoop.security.SecurityUtil;
+import org.apache.hadoop.security.UserGroupInformation;
+import org.apache.hadoop.security.authentication.server.AuthenticationFilter;
+import org.eclipse.jetty.servlet.FilterHolder;
+import org.eclipse.jetty.servlet.FilterMapping;
+import org.eclipse.jetty.servlet.ServletHandler;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import static
org.apache.hadoop.ozone.s3secret.S3SecretConfigKeys.OZONE_S3G_SECRET_HTTP_AUTH_TYPE;
+import static
org.apache.hadoop.ozone.s3secret.S3SecretConfigKeys.OZONE_S3G_SECRET_HTTP_BIND_HOST_KEY;
+import static
org.apache.hadoop.ozone.s3secret.S3SecretConfigKeys.OZONE_S3G_SECRET_HTTP_ENABLED_KEY;
+import static
org.apache.hadoop.ozone.s3secret.S3SecretConfigKeys.OZONE_S3G_SECRET_KEYTAB_FILE;
+import static
org.apache.hadoop.ozone.s3secret.S3SecretConfigKeys.OZONE_S3G_SECRET_WEB_AUTHENTICATION_KERBEROS_PRINCIPAL;
/**
- * S3 Gateway specific configuration keys.
+ * Http server to provide S3-compatible API.
*/
public class S3GatewayHttpServer extends BaseHttpServer {
+ private static final Logger LOG =
+ LoggerFactory.getLogger(S3GatewayHttpServer.class);
+
/**
* Default offset between two filters.
*/
public static final int FILTER_PRIORITY_DO_AFTER = 50;
public S3GatewayHttpServer(MutableConfigurationSource conf,
- String name) throws IOException {
+ String name) throws IOException {
super(conf, name);
addServlet("icon", "/favicon.ico", IconServlet.class);
+ addSecretAuthentication(conf);
+ }
+
+ private void addSecretAuthentication(MutableConfigurationSource conf)
+ throws IOException {
+
+ if (conf.getBoolean(OZONE_S3G_SECRET_HTTP_ENABLED_KEY, false)) {
+ String authType = conf.get(OZONE_S3G_SECRET_HTTP_AUTH_TYPE, "simple");
+
+ if (UserGroupInformation.isSecurityEnabled()
+ && authType.equals("kerberos")) {
+ ServletHandler handler = getWebAppContext().getServletHandler();
+ Map<String, String> params = new HashMap<>();
+
+ String principalInConf =
+ conf.get(OZONE_S3G_SECRET_WEB_AUTHENTICATION_KERBEROS_PRINCIPAL);
+ if (principalInConf != null && !principalInConf.isEmpty()) {
+ params.put("kerberos.principal", SecurityUtil.getServerPrincipal(
+ principalInConf, conf.get(OZONE_S3G_SECRET_HTTP_BIND_HOST_KEY)));
+ }
+ String httpKeytab = conf.get(OZONE_S3G_SECRET_KEYTAB_FILE);
+ if (httpKeytab != null && !httpKeytab.isEmpty()) {
Review Comment:
nit: Better use Strings.isNullOrEmpty() instead of checking null and
isEmpty().
##########
hadoop-ozone/s3gateway/src/main/java/org/apache/hadoop/ozone/s3secret/S3SecretEnabledEndpointRequestFilter.java:
##########
@@ -0,0 +1,56 @@
+/*
+ * 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
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * 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.hadoop.ozone.s3secret;
+
+import java.io.IOException;
+import javax.inject.Inject;
+import javax.ws.rs.container.ContainerRequestContext;
+import javax.ws.rs.container.ContainerRequestFilter;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.ext.Provider;
+import org.apache.hadoop.hdds.conf.OzoneConfiguration;
+
+import static
org.apache.hadoop.ozone.s3secret.S3SecretConfigKeys.OZONE_S3G_SECRET_HTTP_ENABLED_KEY;
+
+/**
+ * Filter that disables all endpoints annotated with {@link S3SecretEnabled}.
+ * Condition is based on the value of the configuration key
+ * ozone.s3g.secret.http.enabled.
+ */
+@S3SecretEnabled
+@Provider
+public class S3SecretEnabledEndpointRequestFilter
+ implements ContainerRequestFilter {
+
+ @Inject
+ private OzoneConfiguration ozoneConfiguration;
+
+ @Override
+ public void filter(ContainerRequestContext requestContext)
+ throws IOException {
+ boolean isSecretEnabled = ozoneConfiguration.getBoolean(
+ OZONE_S3G_SECRET_HTTP_ENABLED_KEY, false);
+ if (!isSecretEnabled) {
+ requestContext.abortWith(Response.status(Response.Status.CONFLICT)
Review Comment:
Instead of CONFLICT better to use Response.Status.BAD_REQUEST.
##########
hadoop-ozone/s3gateway/src/test/java/org/apache/hadoop/ozone/s3secret/TestSecretRevoke.java:
##########
@@ -0,0 +1,75 @@
+/*
+ * 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
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * 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.hadoop.ozone.s3secret;
+
+import java.io.IOException;
+import java.security.Principal;
+import javax.ws.rs.container.ContainerRequestContext;
+import javax.ws.rs.core.SecurityContext;
+import org.apache.hadoop.ozone.client.ObjectStoreStub;
+import org.apache.hadoop.ozone.client.OzoneClient;
+import org.apache.hadoop.ozone.client.OzoneClientStub;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.Mock;
+import org.mockito.junit.jupiter.MockitoExtension;
+
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+/**
+ * Test for S3 secret revoke endpoint.
+ */
+@ExtendWith(MockitoExtension.class)
+public class TestSecretRevoke {
+ private static final String USER_NAME = "test";
+
+ private S3SecretRevokeEndpoint endpoint;
+
+ @Mock
+ private ObjectStoreStub objectStore;
+ @Mock
+ private ContainerRequestContext context;
+ @Mock
+ private SecurityContext securityContext;
+ @Mock
+ private Principal principal;
+
+ @BeforeEach
+ void setUp() {
+ OzoneClient client = new OzoneClientStub(objectStore);
+
+ when(principal.getName()).thenReturn(USER_NAME);
+ when(securityContext.getUserPrincipal()).thenReturn(principal);
+ when(context.getSecurityContext()).thenReturn(securityContext);
+
+ endpoint = new S3SecretRevokeEndpoint();
+ endpoint.setClient(client);
+ endpoint.setContext(context);
+ }
+
+ @Test
+ void testSecretRevoke() throws IOException {
Review Comment:
Can you add some negative test case like revoke is called but no secret
present for the user.
##########
hadoop-ozone/s3gateway/src/main/java/org/apache/hadoop/ozone/s3secret/S3SecretGenerateEndpoint.java:
##########
@@ -0,0 +1,48 @@
+/*
+ * 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
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * 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.hadoop.ozone.s3secret;
+
+import org.apache.hadoop.ozone.om.helpers.S3SecretValue;
+
+import javax.ws.rs.GET;
+import javax.ws.rs.Path;
+import javax.ws.rs.core.Response;
+import java.io.IOException;
+
+/**
+ * Endpoint to generate and return S3 secret.
+ */
+@Path("/secret/generate")
+@S3SecretEnabled
+public class S3SecretGenerateEndpoint extends S3SecretEndpointBase {
+
+ @GET
+ public Response get() throws IOException {
+ S3SecretResponse s3SecretResponse = new S3SecretResponse();
+ S3SecretValue s3SecretValue = generateS3Secret();
+ s3SecretResponse.setAwsSecret(s3SecretValue.getAwsSecret());
Review Comment:
s3SecretValue here returned from interface, check here before accessing it
or else there is chances of NPE.
##########
hadoop-ozone/s3gateway/src/main/java/org/apache/hadoop/ozone/s3/S3GatewayHttpServer.java:
##########
@@ -18,29 +18,88 @@
package org.apache.hadoop.ozone.s3;
import java.io.IOException;
-
-import org.apache.hadoop.hdds.conf.MutableConfigurationSource;
-import org.apache.hadoop.hdds.server.http.BaseHttpServer;
-
+import java.util.HashMap;
+import java.util.Map;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
+import org.apache.hadoop.hdds.conf.MutableConfigurationSource;
+import org.apache.hadoop.hdds.server.http.BaseHttpServer;
+import org.apache.hadoop.hdds.server.http.ServletElementsFactory;
+import org.apache.hadoop.security.SecurityUtil;
+import org.apache.hadoop.security.UserGroupInformation;
+import org.apache.hadoop.security.authentication.server.AuthenticationFilter;
+import org.eclipse.jetty.servlet.FilterHolder;
+import org.eclipse.jetty.servlet.FilterMapping;
+import org.eclipse.jetty.servlet.ServletHandler;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import static
org.apache.hadoop.ozone.s3secret.S3SecretConfigKeys.OZONE_S3G_SECRET_HTTP_AUTH_TYPE;
+import static
org.apache.hadoop.ozone.s3secret.S3SecretConfigKeys.OZONE_S3G_SECRET_HTTP_BIND_HOST_KEY;
+import static
org.apache.hadoop.ozone.s3secret.S3SecretConfigKeys.OZONE_S3G_SECRET_HTTP_ENABLED_KEY;
+import static
org.apache.hadoop.ozone.s3secret.S3SecretConfigKeys.OZONE_S3G_SECRET_KEYTAB_FILE;
+import static
org.apache.hadoop.ozone.s3secret.S3SecretConfigKeys.OZONE_S3G_SECRET_WEB_AUTHENTICATION_KERBEROS_PRINCIPAL;
/**
- * S3 Gateway specific configuration keys.
+ * Http server to provide S3-compatible API.
*/
public class S3GatewayHttpServer extends BaseHttpServer {
+ private static final Logger LOG =
+ LoggerFactory.getLogger(S3GatewayHttpServer.class);
+
/**
* Default offset between two filters.
*/
public static final int FILTER_PRIORITY_DO_AFTER = 50;
public S3GatewayHttpServer(MutableConfigurationSource conf,
- String name) throws IOException {
+ String name) throws IOException {
Review Comment:
nit: Correct the indentation.
##########
hadoop-ozone/s3gateway/src/main/java/org/apache/hadoop/ozone/s3/S3GatewayHttpServer.java:
##########
@@ -18,29 +18,88 @@
package org.apache.hadoop.ozone.s3;
import java.io.IOException;
-
-import org.apache.hadoop.hdds.conf.MutableConfigurationSource;
-import org.apache.hadoop.hdds.server.http.BaseHttpServer;
-
+import java.util.HashMap;
+import java.util.Map;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
+import org.apache.hadoop.hdds.conf.MutableConfigurationSource;
+import org.apache.hadoop.hdds.server.http.BaseHttpServer;
+import org.apache.hadoop.hdds.server.http.ServletElementsFactory;
+import org.apache.hadoop.security.SecurityUtil;
+import org.apache.hadoop.security.UserGroupInformation;
+import org.apache.hadoop.security.authentication.server.AuthenticationFilter;
+import org.eclipse.jetty.servlet.FilterHolder;
+import org.eclipse.jetty.servlet.FilterMapping;
+import org.eclipse.jetty.servlet.ServletHandler;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import static
org.apache.hadoop.ozone.s3secret.S3SecretConfigKeys.OZONE_S3G_SECRET_HTTP_AUTH_TYPE;
+import static
org.apache.hadoop.ozone.s3secret.S3SecretConfigKeys.OZONE_S3G_SECRET_HTTP_BIND_HOST_KEY;
+import static
org.apache.hadoop.ozone.s3secret.S3SecretConfigKeys.OZONE_S3G_SECRET_HTTP_ENABLED_KEY;
+import static
org.apache.hadoop.ozone.s3secret.S3SecretConfigKeys.OZONE_S3G_SECRET_KEYTAB_FILE;
+import static
org.apache.hadoop.ozone.s3secret.S3SecretConfigKeys.OZONE_S3G_SECRET_WEB_AUTHENTICATION_KERBEROS_PRINCIPAL;
/**
- * S3 Gateway specific configuration keys.
+ * Http server to provide S3-compatible API.
*/
public class S3GatewayHttpServer extends BaseHttpServer {
+ private static final Logger LOG =
+ LoggerFactory.getLogger(S3GatewayHttpServer.class);
+
/**
* Default offset between two filters.
*/
public static final int FILTER_PRIORITY_DO_AFTER = 50;
public S3GatewayHttpServer(MutableConfigurationSource conf,
- String name) throws IOException {
+ String name) throws IOException {
super(conf, name);
addServlet("icon", "/favicon.ico", IconServlet.class);
+ addSecretAuthentication(conf);
+ }
+
+ private void addSecretAuthentication(MutableConfigurationSource conf)
+ throws IOException {
+
+ if (conf.getBoolean(OZONE_S3G_SECRET_HTTP_ENABLED_KEY, false)) {
+ String authType = conf.get(OZONE_S3G_SECRET_HTTP_AUTH_TYPE, "simple");
+
+ if (UserGroupInformation.isSecurityEnabled()
Review Comment:
I think UserGroupInformation.isSecurityEnabled() check required along with
conf.getBoolean(OZONE_S3G_SECRET_HTTP_ENABLED_KEY, false) similar as we do in
BaseHttpServer. Or else it throws here "Secret Endpoint should be secured with
Kerberos" but actually usergroup security is not enabled.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]