[
https://issues.apache.org/jira/browse/NIFIREG-9?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16190278#comment-16190278
]
ASF GitHub Bot commented on NIFIREG-9:
--------------------------------------
Github user bbende commented on a diff in the pull request:
https://github.com/apache/nifi-registry/pull/14#discussion_r142427496
--- Diff:
nifi-registry-framework/src/main/java/org/apache/nifi/registry/authorization/StandardAuthorizerFactory.java
---
@@ -0,0 +1,791 @@
+/*
+ * 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.nifi.registry.authorization;
+
+import org.apache.commons.lang3.StringUtils;
+import org.apache.nifi.registry.authorization.annotation.AuthorizerContext;
+import org.apache.nifi.registry.authorization.generated.Authorizers;
+import org.apache.nifi.registry.authorization.generated.Prop;
+import org.apache.nifi.registry.properties.NiFiRegistryProperties;
+import org.apache.nifi.registry.provider.StandardProviderFactory;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.xml.sax.SAXException;
+
+import javax.xml.XMLConstants;
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.JAXBElement;
+import javax.xml.bind.JAXBException;
+import javax.xml.bind.Unmarshaller;
+import javax.xml.transform.stream.StreamSource;
+import javax.xml.validation.Schema;
+import javax.xml.validation.SchemaFactory;
+import java.io.File;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * This implementation of AuthorizerFactory in NiFi Registry is based on a
combination of
+ * NiFi's AuthorizerFactory and AuthorizerFactoryBean.
+ */
+public class StandardAuthorizerFactory implements AuthorizerFactory,
UserGroupProviderLookup, AccessPolicyProviderLookup, AuthorizerLookup{
+
+ private static final Logger logger =
LoggerFactory.getLogger(StandardProviderFactory.class);
+
+ private static final String AUTHORIZERS_XSD = "/authorizers.xsd";
+ private static final String JAXB_GENERATED_PATH =
"org.apache.nifi.registry.authorization.generated";
+ private static final JAXBContext JAXB_CONTEXT =
initializeJaxbContext();
+
+ /**
+ * Load the JAXBContext.
+ */
+ private static JAXBContext initializeJaxbContext() {
+ try {
+ return JAXBContext.newInstance(JAXB_GENERATED_PATH,
StandardAuthorizerFactory.class.getClassLoader());
+ } catch (JAXBException e) {
+ throw new RuntimeException("Unable to create JAXBContext.", e);
+ }
+ }
+
+ private final NiFiRegistryProperties properties;
+ private Authorizer authorizer;
+ private final Map<String, UserGroupProvider> userGroupProviders = new
HashMap<>();
+ private final Map<String, AccessPolicyProvider> accessPolicyProviders
= new HashMap<>();
+ private final Map<String, Authorizer> authorizers = new HashMap<>();
+
+ public StandardAuthorizerFactory(final NiFiRegistryProperties
properties) {
+ this.properties = properties;
+
+ if (this.properties == null) {
+ throw new IllegalStateException("NiFiRegistryProperties cannot
be null");
+ }
+ }
+
+ /***** UserGroupProviderLookup *****/
+
+ @Override
+ public UserGroupProvider getUserGroupProvider(String identifier) {
+ return userGroupProviders.get(identifier);
+ }
+
+ /***** AccessPolicyProviderLookup *****/
+
+ @Override
+ public AccessPolicyProvider getAccessPolicyProvider(String identifier)
{
+ return accessPolicyProviders.get(identifier);
+ }
+
+
+ /***** AuthorizerLookup *****/
+
+ @Override
+ public Authorizer getAuthorizer(String identifier) {
+ return authorizers.get(identifier);
+ }
+
+
+ /***** AuthorizerFactory *****/
+
+ @Override
+ public void initialize() throws AuthorizerFactoryException {
+// if (authorizerHolder.get() == null) {
+// final File authorizersConfigFile =
properties.getAuthorizersConfigurationFile();
+// if (authorizersConfigFile.exists()) {
+// try {
+// // find the schema
+// final SchemaFactory schemaFactory =
SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
+// final Schema schema =
schemaFactory.newSchema(StandardProviderFactory.class.getResource(AUTHORIZERS_XSD));
+//
+// // attempt to unmarshal
+// final Unmarshaller unmarshaller =
JAXB_CONTEXT.createUnmarshaller();
+// unmarshaller.setSchema(schema);
+//
+// // set the holder for later use
+// final JAXBElement<Authorizers> element =
unmarshaller.unmarshal(new StreamSource(authorizersConfigFile),
Authorizers.class);
+// authorizerHolder.set(element.getValue());
+// } catch (SAXException | JAXBException e) {
+// throw new AuthorizerFactoryException("Unable to load
the authorizer configuration file at: " +
authorizersConfigFile.getAbsolutePath(), e);
+// }
+// } else {
+// throw new AuthorizerFactoryException("Unable to find the
providers configuration file at " + authorizersConfigFile.getAbsolutePath());
+// }
+// }
+ }
+
+ @Override
+ public Authorizer getAuthorizer() throws AuthorizerFactoryException {
+ if (authorizer == null) {
+ if (properties.getSslPort() == null) {
+ // use a default authorizer... only allowable when running
not securely
+ authorizer = createDefaultAuthorizer();
+ } else {
+ // look up the authorizer to use
+ final String authorizerIdentifier =
properties.getProperty(NiFiRegistryProperties.SECURITY_USER_AUTHORIZER);
+
+ // ensure the authorizer class name was specified
+ if (StringUtils.isBlank(authorizerIdentifier)) {
+ throw new AuthorizerFactoryException("When running
securely, the authorizer identifier must be specified in the nifi properties
file.");
+ } else {
+
+ try {
+ final Authorizers authorizerConfiguration =
loadAuthorizersConfiguration();
+
+ // create each user group provider
+ for (final
org.apache.nifi.registry.authorization.generated.UserGroupProvider
userGroupProvider : authorizerConfiguration.getUserGroupProvider()) {
+
userGroupProviders.put(userGroupProvider.getIdentifier(),
createUserGroupProvider(userGroupProvider.getIdentifier(),
userGroupProvider.getClazz()));
+ }
+
+ // configure each user group provider
+ for (final
org.apache.nifi.registry.authorization.generated.UserGroupProvider provider :
authorizerConfiguration.getUserGroupProvider()) {
+ final UserGroupProvider instance =
userGroupProviders.get(provider.getIdentifier());
+
instance.onConfigured(loadAuthorizerConfiguration(provider.getIdentifier(),
provider.getProperty()));
+ }
+
+ // create each access policy provider
+ for (final
org.apache.nifi.registry.authorization.generated.AccessPolicyProvider
accessPolicyProvider : authorizerConfiguration.getAccessPolicyProvider()) {
+
accessPolicyProviders.put(accessPolicyProvider.getIdentifier(),
createAccessPolicyProvider(accessPolicyProvider.getIdentifier(),
accessPolicyProvider.getClazz()));
+ }
+
+ // configure each access policy provider
+ for (final
org.apache.nifi.registry.authorization.generated.AccessPolicyProvider provider
: authorizerConfiguration.getAccessPolicyProvider()) {
+ final AccessPolicyProvider instance =
accessPolicyProviders.get(provider.getIdentifier());
+
instance.onConfigured(loadAuthorizerConfiguration(provider.getIdentifier(),
provider.getProperty()));
+ }
+
+ // create each authorizer
+ for (final
org.apache.nifi.registry.authorization.generated.Authorizer authorizer :
authorizerConfiguration.getAuthorizer()) {
+ authorizers.put(authorizer.getIdentifier(),
createAuthorizer(authorizer.getIdentifier(), authorizer.getClazz(),
authorizer.getClasspath()));
+ }
+
+ // configure each authorizer
+ for (final
org.apache.nifi.registry.authorization.generated.Authorizer provider :
authorizerConfiguration.getAuthorizer()) {
+ final Authorizer instance =
authorizers.get(provider.getIdentifier());
+
instance.onConfigured(loadAuthorizerConfiguration(provider.getIdentifier(),
provider.getProperty()));
+ }
+
+ // get the authorizer instance
+ authorizer = getAuthorizer(authorizerIdentifier);
+
+ // ensure it was found
+ if (authorizer == null) {
+ throw new
AuthorizerFactoryException(String.format("The specified authorizer '%s' could
not be found.", authorizerIdentifier));
+ }
+ } catch (Exception e) {
+ throw new AuthorizerFactoryException("Failed to
construct Authorizer.", e);
+ }
+ }
+ }
+ }
+ return authorizer;
+ }
+
+ private Authorizers loadAuthorizersConfiguration() throws Exception {
+ final File authorizersConfigurationFile =
properties.getAuthorizersConfigurationFile();
+
+ // load the authorizers from the specified file
+ if (authorizersConfigurationFile.exists()) {
+ try {
+ // find the schema
+ final SchemaFactory schemaFactory =
SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
+ final Schema schema =
schemaFactory.newSchema(Authorizers.class.getResource(AUTHORIZERS_XSD));
+
+ // attempt to unmarshal
+ final Unmarshaller unmarshaller =
JAXB_CONTEXT.createUnmarshaller();
+ unmarshaller.setSchema(schema);
+ final JAXBElement<Authorizers> element =
unmarshaller.unmarshal(new StreamSource(authorizersConfigurationFile),
Authorizers.class);
+ return element.getValue();
+ } catch (SAXException | JAXBException e) {
+ throw new Exception("Unable to load the authorizer
configuration file at: " + authorizersConfigurationFile.getAbsolutePath(), e);
+ }
+ } else {
+ throw new Exception("Unable to find the authorizer
configuration file at " + authorizersConfigurationFile.getAbsolutePath());
+ }
+ }
+
+ private AuthorizerConfigurationContext
loadAuthorizerConfiguration(final String identifier, final List<Prop>
properties) {
+ final Map<String, String> authorizerProperties = new HashMap<>();
+
+ for (final Prop property : properties) {
+ authorizerProperties.put(property.getName(),
property.getValue());
+ }
+ return new StandardAuthorizerConfigurationContext(identifier,
authorizerProperties);
+ }
+
+ private UserGroupProvider createUserGroupProvider(final String
identifier, final String userGroupProviderClassName) throws Exception {
+
+ final UserGroupProvider instance;
+
+ // attempt to load the class
+ Class<?> rawUserGroupProviderClass =
Class.forName(userGroupProviderClassName);
+ Class<? extends UserGroupProvider> userGroupProviderClass =
rawUserGroupProviderClass.asSubclass(UserGroupProvider.class);
+
+ // otherwise create a new instance
+ Constructor constructor = userGroupProviderClass.getConstructor();
+ instance = (UserGroupProvider) constructor.newInstance();
+
+ // method injection
+ performMethodInjection(instance, userGroupProviderClass);
+
+ // field injection
+ performFieldInjection(instance, userGroupProviderClass);
+
+ // call post construction lifecycle event
+ instance.initialize(new
StandardAuthorizerInitializationContext(identifier, this, this, this));
+
+ return instance;
+ }
+
+ private AccessPolicyProvider createAccessPolicyProvider(final String
identifier, final String accessPolicyProviderClassName) throws Exception {
+ final AccessPolicyProvider instance;
+
+ // attempt to load the class
+ Class<?> rawAccessPolicyProviderClass =
Class.forName(accessPolicyProviderClassName);
+ Class<? extends AccessPolicyProvider> accessPolicyClass =
rawAccessPolicyProviderClass.asSubclass(AccessPolicyProvider.class);
+
+ // otherwise create a new instance
+ Constructor constructor = accessPolicyClass.getConstructor();
+ instance = (AccessPolicyProvider) constructor.newInstance();
+
+ // method injection
+ performMethodInjection(instance, accessPolicyClass);
+
+ // field injection
+ performFieldInjection(instance, accessPolicyClass);
+
+ // call post construction lifecycle event
+ instance.initialize(new
StandardAuthorizerInitializationContext(identifier, this, this, this));
+
+ return instance;
+ }
+
+ private Authorizer createAuthorizer(final String identifier, final
String authorizerClassName, final String classpathResources) throws Exception {
+ final Authorizer instance;
+ // attempt to load the class
+ Class<?> rawAuthorizerClass = Class.forName(authorizerClassName);
+ Class<? extends Authorizer> authorizerClass =
rawAuthorizerClass.asSubclass(Authorizer.class);
+
+ // otherwise create a new instance
+ Constructor constructor = authorizerClass.getConstructor();
+ instance = (Authorizer) constructor.newInstance();
+
+ // method injection
+ performMethodInjection(instance, authorizerClass);
+
+ // field injection
+ performFieldInjection(instance, authorizerClass);
+
+ // call post construction lifecycle event
+ instance.initialize(new
StandardAuthorizerInitializationContext(identifier, this, this, this));
+
+// if (StringUtils.isNotEmpty(classpathResources)) {
--- End diff --
Should be fine to leave this out for now, but we may need to revisit this
if/when we add support for Ranger... this was done so someone can configure
additional libraries to be on the classpath of the authorizer, specifically for
Ranger to know where the Hadoop client JARs were if wanting to send audit logs
to HDFS.
> Define web REST API endpoints for user, group, and policy management
> --------------------------------------------------------------------
>
> Key: NIFIREG-9
> URL: https://issues.apache.org/jira/browse/NIFIREG-9
> Project: NiFi Registry
> Issue Type: New Feature
> Reporter: Kevin Doran
> Assignee: Kevin Doran
> Fix For: 0.0.1
>
>
> NIFIREG-8 defined web REST API endpoints for domain objects such as buckets
> and flows.
> This ticket scopes work to build on that by adding endpoints for additional
> resources to facilitate user, group, and policy management.
> The interface for user, group, and policy management will be based on the
> NiFi API so as to minimize the effort for NiFi API clients to be reused for
> NiFi Registry.
--
This message was sent by Atlassian JIRA
(v6.4.14#64029)