Skip to content
Permalink
Browse files
Add Authorization Components to helix-rest (#1967) (#1981)
* Add Authorization Components to helix-rest

* Address some comments
  • Loading branch information
NealSun96 committed Mar 14, 2022
1 parent cbf35ba commit 54e25ce30b1de41a7b4299d35809961d5c962570
Showing 21 changed files with 443 additions and 0 deletions.
@@ -40,8 +40,12 @@
import org.apache.helix.rest.common.HelixRestNamespace;
import org.apache.helix.rest.common.ServletType;
import org.apache.helix.rest.server.auditlog.AuditLogger;
import org.apache.helix.rest.server.authValidator.AuthValidator;
import org.apache.helix.rest.server.authValidator.NoopAuthValidator;
import org.apache.helix.rest.server.filters.AuditLogFilter;
import org.apache.helix.rest.server.filters.CORSFilter;
import org.apache.helix.rest.server.filters.ClusterAuthFilter;
import org.apache.helix.rest.server.filters.NamespaceAuthFilter;
import org.eclipse.jetty.http.HttpVersion;
import org.eclipse.jetty.server.HttpConfiguration;
import org.eclipse.jetty.server.HttpConnectionFactory;
@@ -57,6 +61,7 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


public class HelixRestServer {
private static Logger LOG = LoggerFactory.getLogger(HelixRestServer.class);

@@ -73,6 +78,8 @@ public class HelixRestServer {
private List<HelixRestNamespace> _helixNamespaces;
private ServletContextHandler _servletContextHandler;
private List<AuditLogger> _auditLoggers;
private AuthValidator _clusterAuthValidator;
private AuthValidator _namespaceAuthValidator;

// Key is name of namespace, value of the resource config of that namespace
private Map<String, ResourceConfig> _resourceConfigMap;
@@ -94,8 +101,21 @@ public HelixRestServer(List<HelixRestNamespace> namespaces, int port, String url
init(namespaces, port, urlPrefix, auditLoggers);
}

public HelixRestServer(List<HelixRestNamespace> namespaces, int port, String urlPrefix,
List<AuditLogger> auditLoggers, AuthValidator clusterAuthValidator,
AuthValidator namespaceAuthValidator) {
init(namespaces, port, urlPrefix, auditLoggers, clusterAuthValidator, namespaceAuthValidator);
}

private void init(List<HelixRestNamespace> namespaces, int port, String urlPrefix,
List<AuditLogger> auditLoggers) {
init(namespaces, port, urlPrefix, auditLoggers, new NoopAuthValidator(),
new NoopAuthValidator());
}

private void init(List<HelixRestNamespace> namespaces, int port, String urlPrefix,
List<AuditLogger> auditLoggers, AuthValidator clusterAuthValidator,
AuthValidator namespaceAuthValidator) {
if (namespaces.size() == 0) {
throw new IllegalArgumentException(
"No namespace specified! Please provide ZOOKEEPER address or namespace manifest.");
@@ -108,6 +128,8 @@ private void init(List<HelixRestNamespace> namespaces, int port, String urlPrefi
_resourceConfigMap = new HashMap<>();
_servletContextHandler = new ServletContextHandler(_server, _urlPrefix);
_helixNamespaces = namespaces;
_clusterAuthValidator = clusterAuthValidator;
_namespaceAuthValidator = namespaceAuthValidator;

// Initialize all namespaces.
// If there is not a default namespace (namespace.isDefault() is false),
@@ -175,6 +197,8 @@ protected ResourceConfig getResourceConfig(HelixRestNamespace namespace, Servlet
cfg.register(new CORSFilter());
}
cfg.register(new AuditLogFilter(_auditLoggers));
cfg.register(new ClusterAuthFilter(_clusterAuthValidator));
cfg.register(new NamespaceAuthFilter(_namespaceAuthValidator));
return cfg;
}

@@ -0,0 +1,27 @@
package org.apache.helix.rest.server.authValidator;

/*
* 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.
*/

import javax.ws.rs.container.ContainerRequestContext;


public interface AuthValidator {
boolean validate(ContainerRequestContext request);
}
@@ -0,0 +1,29 @@
package org.apache.helix.rest.server.authValidator;

/*
* 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.
*/

import javax.ws.rs.container.ContainerRequestContext;


public class NoopAuthValidator implements AuthValidator {
public boolean validate(ContainerRequestContext request) {
return true;
}
}
@@ -0,0 +1,33 @@
package org.apache.helix.rest.server.filters;

/*
* 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.
*/

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import javax.ws.rs.NameBinding;


@NameBinding
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface ClusterAuth {
}
@@ -0,0 +1,46 @@
package org.apache.helix.rest.server.filters;

/*
* 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.
*/

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.helix.rest.server.authValidator.AuthValidator;


@ClusterAuth
@Provider
public class ClusterAuthFilter implements ContainerRequestFilter {

AuthValidator _authValidator;

public ClusterAuthFilter(AuthValidator authValidator) {
_authValidator = authValidator;
}

@Override
public void filter(ContainerRequestContext request) {
if (!_authValidator.validate(request)) {
request.abortWith(Response.status(Response.Status.FORBIDDEN).build());
}
}
}
@@ -0,0 +1,33 @@
package org.apache.helix.rest.server.filters;

/*
* 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.
*/

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import javax.ws.rs.NameBinding;


@NameBinding
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface NamespaceAuth {
}
@@ -0,0 +1,46 @@
package org.apache.helix.rest.server.filters;

/*
* 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.
*/

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.helix.rest.server.authValidator.AuthValidator;


@NamespaceAuth
@Provider
public class NamespaceAuthFilter implements ContainerRequestFilter {

AuthValidator _authValidator;

public NamespaceAuthFilter(AuthValidator authValidator) {
_authValidator = authValidator;
}

@Override
public void filter(ContainerRequestContext request) {
if (!_authValidator.validate(request)) {
request.abortWith(Response.status(Response.Status.FORBIDDEN).build());
}
}
}

0 comments on commit 54e25ce

Please sign in to comment.