NIFI-655:
- Refactoring web security to use Spring Security Java Configuration.
- Introducing security in Web UI in order to get JWT.

NIFI-655:
- Setting up the resources (js/css) for the login page.

NIFI-655:
- Adding support for configuring anonymous roles.
- Addressing checkstyle violations.

NIFI-655:
- Moving to token api to web-api.
- Creating an LoginProvider API for user/pass based authentication.
- Creating a module for funneling access to the authorized useres.

NIFI-655:
- Moving away from usage of DN to identity throughout the application (from the 
user db to the authorization provider).
- Updating the authorized users schema to support login users.
- Creating an extension point for authentication of users based on 
username/password.


Project: http://git-wip-us.apache.org/repos/asf/nifi/repo
Commit: http://git-wip-us.apache.org/repos/asf/nifi/commit/a40e5a07
Tree: http://git-wip-us.apache.org/repos/asf/nifi/tree/a40e5a07
Diff: http://git-wip-us.apache.org/repos/asf/nifi/diff/a40e5a07

Branch: refs/heads/NIFI-655
Commit: a40e5a07ba29177ed22eb88751a8336ed59a7c25
Parents: 5cc2b04
Author: Matt Gilman <[email protected]>
Authored: Wed Oct 7 13:33:34 2015 -0400
Committer: Matt Gilman <[email protected]>
Committed: Fri Oct 30 10:17:28 2015 -0400

----------------------------------------------------------------------
 .../nifi/authentication/LoginCredentials.java   |  39 ++
 .../authentication/LoginIdentityProvider.java   |  70 +++
 ...ginIdentityProviderConfigurationContext.java |  48 ++
 ...inIdentityProviderInitializationContext.java |  27 +
 .../LoginIdentityProviderLookup.java            |  25 +
 .../LoginIdentityProviderContext.java           |  35 ++
 nifi-assembly/pom.xml                           |   3 +
 .../org/apache/nifi/util/NiFiProperties.java    |  64 ++-
 .../nifi-framework-nar/pom.xml                  |   4 +
 .../nifi-framework/nifi-administration/pom.xml  |   1 -
 .../nifi/admin/AuditDataSourceFactoryBean.java  |  33 +-
 .../nifi/admin/UserDataSourceFactoryBean.java   |  99 ++--
 .../nifi/admin/dao/impl/StandardActionDAO.java  |  10 +-
 .../nifi/admin/dao/impl/StandardUserDAO.java    |  38 +-
 .../nifi-authorized-users/pom.xml               |  75 +++
 .../nifi/authorized/users/AuthorizedUsers.java  | 376 +++++++++++++
 .../src/main/xsd/users.xsd                      |  96 ++++
 .../nifi/web/api/entity/IdentityEntity.java     |  52 ++
 .../nifi-file-authorization-provider/pom.xml    |  43 +-
 .../FileAuthorizationProvider.java              | 540 ++++++++-----------
 .../src/main/xsd/users.xsd                      |  64 ---
 .../nifi-file-identity-provider/pom.xml         |  39 ++
 .../FileLoginIdentityProvider.java              | 101 ++++
 ...he.nifi.authentication.LoginIdentityProvider |  15 +
 .../org/apache/nifi/nar/ExtensionManager.java   |   2 +
 .../resources/conf/login-identity-providers.xml |  27 +
 .../src/main/resources/conf/nifi.properties     |   3 +
 .../org/apache/nifi/web/server/JettyServer.java |   5 +-
 .../org/apache/nifi/web/NiFiServiceFacade.java  |   7 +
 .../nifi/web/NiFiWebApiConfiguration.java       |  40 ++
 .../web/NiFiWebApiSecurityConfiguration.java    | 192 +++++++
 .../nifi/web/StandardNiFiServiceFacade.java     |  21 +-
 .../nifi/web/api/ApplicationResource.java       |  10 +-
 .../apache/nifi/web/api/ControllerResource.java |  58 +-
 .../org/apache/nifi/web/api/UserResource.java   |  49 +-
 .../nifi/web/controller/ControllerFacade.java   |  13 +-
 .../src/main/webapp/WEB-INF/web.xml             |  13 +-
 .../nifi/integration/util/NiFiTestUser.java     |  21 +-
 .../resources/access-control/nifi.properties    |   1 +
 .../nifi-web/nifi-web-security/pom.xml          |  38 ++
 .../org/apache/nifi/web/security/DnUtils.java   |  85 ---
 .../security/NiFiAuthenticationEntryPoint.java  |  69 +++
 .../web/security/NiFiAuthenticationFilter.java  | 136 +++++
 .../security/NiFiAuthenticationProvider.java    |  78 +++
 .../nifi/web/security/ProxiedEntitiesUtils.java | 164 ++++++
 .../anonymous/NiFiAnonymousUserFilter.java      |  39 +-
 .../NiFiAuthenticationEntryPoint.java           |  69 ---
 .../authorization/NiFiAuthorizationService.java |  33 +-
 .../authorization/NodeAuthorizedUserFilter.java | 128 -----
 .../form/LoginAuthenticationFilter.java         | 131 +++++
 .../form/LoginAuthenticationProvider.java       |  53 ++
 .../security/jwt/JwtAuthenticationFilter.java   |  63 +++
 .../security/jwt/JwtAuthenticationProvider.java |  47 ++
 .../nifi/web/security/jwt/JwtService.java       |  51 ++
 .../security/node/NodeAuthorizedUserFilter.java | 127 +++++
 .../LoginIdentityProviderFactoryBean.java       | 334 ++++++++++++
 ...ginIdentityProviderConfigurationContext.java |  51 ++
 ...inIdentityProviderInitializationContext.java |  45 ++
 .../token/LoginAuthenticationRequestToken.java  |  37 ++
 .../token/LoginAuthenticationToken.java         |  48 ++
 .../NewAccountAuthenticationRequestToken.java   |  40 ++
 .../token/NewAccountAuthenticationToken.java    |  46 ++
 .../token/NiFiAuthenticationRequestToken.java   |  54 ++
 .../security/token/NiFiAuthorizationToken.java  |  50 ++
 .../web/security/user/NewAccountRequest.java    |  47 ++
 .../nifi/web/security/user/NiFiUserDetails.java |   1 -
 .../nifi/web/security/user/NiFiUserUtils.java   |  27 +-
 .../security/x509/X509AuthenticationFilter.java | 258 +--------
 .../x509/X509AuthenticationFilterOld.java       | 317 +++++++++++
 .../x509/X509AuthenticationProvider.java        |  47 ++
 .../resources/nifi-web-security-context.xml     |  67 ++-
 .../src/main/xsd/login-identity-providers.xsd   |  49 ++
 .../NiFiAuthorizationServiceTest.java           | 502 ++++++++---------
 .../nifi-framework/nifi-web/nifi-web-ui/pom.xml |  60 ++-
 .../apache/nifi/web/NiFiWebUiConfiguration.java |  35 ++
 .../web/NiFiWebUiSecurityConfiguration.java     |  69 +++
 .../main/resources/filters/login-min.properties |  18 +
 .../src/main/resources/filters/login.properties |  24 +
 .../src/main/webapp/WEB-INF/pages/login.jsp     |  49 ++
 .../WEB-INF/partials/canvas/canvas-header.jsp   |   3 +
 .../nifi-web-ui/src/main/webapp/WEB-INF/web.xml |  44 +-
 .../nifi-web-ui/src/main/webapp/css/login.css   |  20 +
 .../webapp/js/nf/canvas/nf-canvas-header.js     |   5 +
 .../src/main/webapp/js/nf/login/nf-login.js     |  41 ++
 .../nifi-framework/pom.xml                      |   2 +
 nifi-nar-bundles/nifi-framework-bundle/pom.xml  |  10 +
 pom.xml                                         |   2 +-
 87 files changed, 4640 insertions(+), 1432 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/nifi/blob/a40e5a07/nifi-api/src/main/java/org/apache/nifi/authentication/LoginCredentials.java
----------------------------------------------------------------------
diff --git 
a/nifi-api/src/main/java/org/apache/nifi/authentication/LoginCredentials.java 
b/nifi-api/src/main/java/org/apache/nifi/authentication/LoginCredentials.java
new file mode 100644
index 0000000..afb7827
--- /dev/null
+++ 
b/nifi-api/src/main/java/org/apache/nifi/authentication/LoginCredentials.java
@@ -0,0 +1,39 @@
+/*
+ * 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.authentication;
+
+/**
+ * Login credentials for a user.
+ */
+public class LoginCredentials {
+
+    private final String username;
+    private final String password;
+
+    public LoginCredentials(String username, String password) {
+        this.username = username;
+        this.password = password;
+    }
+
+    public String getUsername() {
+        return username;
+    }
+
+    public String getPassword() {
+        return password;
+    }
+}

http://git-wip-us.apache.org/repos/asf/nifi/blob/a40e5a07/nifi-api/src/main/java/org/apache/nifi/authentication/LoginIdentityProvider.java
----------------------------------------------------------------------
diff --git 
a/nifi-api/src/main/java/org/apache/nifi/authentication/LoginIdentityProvider.java
 
b/nifi-api/src/main/java/org/apache/nifi/authentication/LoginIdentityProvider.java
new file mode 100644
index 0000000..919d5b5
--- /dev/null
+++ 
b/nifi-api/src/main/java/org/apache/nifi/authentication/LoginIdentityProvider.java
@@ -0,0 +1,70 @@
+/*
+ * 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.authentication;
+
+import org.apache.nifi.authorization.exception.ProviderCreationException;
+import org.apache.nifi.authorization.exception.ProviderDestructionException;
+
+/**
+ * Identity provider that is able to authentication a user with 
username/password credentials.
+ */
+public interface LoginIdentityProvider {
+
+    /**
+     * Returns whether this provider supports user registration.
+     *
+     * @return whether user registration is supported
+     */
+    boolean supportsRegistration();
+
+    /**
+     * Invoked to register the user with the specified login credentials.
+     *
+     * @param credentials the login credentials
+     */
+    void register(LoginCredentials credentials);
+
+    /**
+     * Authenticates the specified login credentials.
+     *
+     * @param credentials the credentials
+     * @return whether the user was authenticated
+     */
+    boolean authenticate(LoginCredentials credentials);
+
+    /**
+     * Called immediately after instance creation for implementers to perform 
additional setup
+     *
+     * @param initializationContext in which to initialize
+     */
+    void initialize(LoginIdentityProviderInitializationContext 
initializationContext) throws ProviderCreationException;
+
+    /**
+     * Called to configure the AuthorityProvider.
+     *
+     * @param configurationContext at the time of configuration
+     * @throws ProviderCreationException for any issues configuring the 
provider
+     */
+    void onConfigured(LoginIdentityProviderConfigurationContext 
configurationContext) throws ProviderCreationException;
+
+    /**
+     * Called immediately before instance destruction for implementers to 
release resources.
+     *
+     * @throws ProviderDestructionException If pre-destruction fails.
+     */
+    void preDestruction() throws ProviderDestructionException;
+}

http://git-wip-us.apache.org/repos/asf/nifi/blob/a40e5a07/nifi-api/src/main/java/org/apache/nifi/authentication/LoginIdentityProviderConfigurationContext.java
----------------------------------------------------------------------
diff --git 
a/nifi-api/src/main/java/org/apache/nifi/authentication/LoginIdentityProviderConfigurationContext.java
 
b/nifi-api/src/main/java/org/apache/nifi/authentication/LoginIdentityProviderConfigurationContext.java
new file mode 100644
index 0000000..6fe61fc
--- /dev/null
+++ 
b/nifi-api/src/main/java/org/apache/nifi/authentication/LoginIdentityProviderConfigurationContext.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
+ *
+ *     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.authentication;
+
+import java.util.Map;
+
+/**
+ *
+ */
+public interface LoginIdentityProviderConfigurationContext {
+
+    /**
+     * @return identifier for the authority provider
+     */
+    String getIdentifier();
+
+    /**
+     * Retrieves all properties the component currently understands regardless
+     * of whether a value has been set for them or not. If no value is present
+     * then its value is null and thus any registered default for the property
+     * descriptor applies.
+     *
+     * @return Map of all properties
+     */
+    Map<String, String> getProperties();
+
+    /**
+     * @param property to lookup the descriptor and value of
+     * @return the value the component currently understands for the given
+     * PropertyDescriptor. This method does not substitute default
+     * PropertyDescriptor values, so the value returned will be null if not set
+     */
+    String getProperty(String property);
+}

http://git-wip-us.apache.org/repos/asf/nifi/blob/a40e5a07/nifi-api/src/main/java/org/apache/nifi/authentication/LoginIdentityProviderInitializationContext.java
----------------------------------------------------------------------
diff --git 
a/nifi-api/src/main/java/org/apache/nifi/authentication/LoginIdentityProviderInitializationContext.java
 
b/nifi-api/src/main/java/org/apache/nifi/authentication/LoginIdentityProviderInitializationContext.java
new file mode 100644
index 0000000..7aa72a7
--- /dev/null
+++ 
b/nifi-api/src/main/java/org/apache/nifi/authentication/LoginIdentityProviderInitializationContext.java
@@ -0,0 +1,27 @@
+/*
+ * 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.authentication;
+
+/**
+ *
+ */
+public interface LoginIdentityProviderInitializationContext {
+
+    public String getIdentifier();
+
+    public LoginIdentityProviderLookup getAuthorityProviderLookup();
+}

http://git-wip-us.apache.org/repos/asf/nifi/blob/a40e5a07/nifi-api/src/main/java/org/apache/nifi/authentication/LoginIdentityProviderLookup.java
----------------------------------------------------------------------
diff --git 
a/nifi-api/src/main/java/org/apache/nifi/authentication/LoginIdentityProviderLookup.java
 
b/nifi-api/src/main/java/org/apache/nifi/authentication/LoginIdentityProviderLookup.java
new file mode 100644
index 0000000..3cd0ba7
--- /dev/null
+++ 
b/nifi-api/src/main/java/org/apache/nifi/authentication/LoginIdentityProviderLookup.java
@@ -0,0 +1,25 @@
+/*
+ * 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.authentication;
+
+/**
+ *
+ */
+public interface LoginIdentityProviderLookup {
+
+    LoginIdentityProvider getLoginIdentityProvider(String identifier);
+}

http://git-wip-us.apache.org/repos/asf/nifi/blob/a40e5a07/nifi-api/src/main/java/org/apache/nifi/authentication/annotation/LoginIdentityProviderContext.java
----------------------------------------------------------------------
diff --git 
a/nifi-api/src/main/java/org/apache/nifi/authentication/annotation/LoginIdentityProviderContext.java
 
b/nifi-api/src/main/java/org/apache/nifi/authentication/annotation/LoginIdentityProviderContext.java
new file mode 100644
index 0000000..88df259
--- /dev/null
+++ 
b/nifi-api/src/main/java/org/apache/nifi/authentication/annotation/LoginIdentityProviderContext.java
@@ -0,0 +1,35 @@
+/*
+ * 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.authentication.annotation;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Inherited;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ *
+ *
+ */
+@Documented
+@Target({ElementType.FIELD, ElementType.METHOD})
+@Retention(RetentionPolicy.RUNTIME)
+@Inherited
+public @interface LoginIdentityProviderContext {
+}

http://git-wip-us.apache.org/repos/asf/nifi/blob/a40e5a07/nifi-assembly/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-assembly/pom.xml b/nifi-assembly/pom.xml
index de4fdcb..ed44ae6 100644
--- a/nifi-assembly/pom.xml
+++ b/nifi-assembly/pom.xml
@@ -253,6 +253,7 @@ language governing permissions and limitations under the 
License. -->
 
         
<nifi.flow.configuration.file>./conf/flow.xml.gz</nifi.flow.configuration.file>
         
<nifi.flow.configuration.archive.dir>./conf/archive/</nifi.flow.configuration.archive.dir>
+        
<nifi.login.identity.provider.configuration.file>./conf/login-identity-providers.xml</nifi.login.identity.provider.configuration.file>
         
<nifi.authority.provider.configuration.file>./conf/authority-providers.xml</nifi.authority.provider.configuration.file>
         <nifi.templates.directory>./conf/templates</nifi.templates.directory>
         
<nifi.database.directory>./database_repository</nifi.database.directory>
@@ -338,8 +339,10 @@ language governing permissions and limitations under the 
License. -->
         
<nifi.security.authorizedUsers.file>./conf/authorized-users.xml</nifi.security.authorizedUsers.file>
         <nifi.security.user.credential.cache.duration>24 
hours</nifi.security.user.credential.cache.duration>
         
<nifi.security.user.authority.provider>file-provider</nifi.security.user.authority.provider>
+        
<nifi.security.user.login.identity.provider>file-provider</nifi.security.user.login.identity.provider>
         <nifi.security.x509.principal.extractor />
         <nifi.security.support.new.account.requests />
+        
<nifi.security.anonymous.authorities>ROLE_MONITOR,ROLE_DFM,ROLE_ADMIN,ROLE_PROVENANCE,ROLE_NIFI</nifi.security.anonymous.authorities>
         <nifi.security.ocsp.responder.url />
         <nifi.security.ocsp.responder.certificate />
 

http://git-wip-us.apache.org/repos/asf/nifi/blob/a40e5a07/nifi-commons/nifi-properties/src/main/java/org/apache/nifi/util/NiFiProperties.java
----------------------------------------------------------------------
diff --git 
a/nifi-commons/nifi-properties/src/main/java/org/apache/nifi/util/NiFiProperties.java
 
b/nifi-commons/nifi-properties/src/main/java/org/apache/nifi/util/NiFiProperties.java
index a51d9be..32ed663 100644
--- 
a/nifi-commons/nifi-properties/src/main/java/org/apache/nifi/util/NiFiProperties.java
+++ 
b/nifi-commons/nifi-properties/src/main/java/org/apache/nifi/util/NiFiProperties.java
@@ -25,10 +25,14 @@ import java.nio.file.InvalidPathException;
 import java.nio.file.Path;
 import java.nio.file.Paths;
 import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Properties;
+import java.util.Set;
 
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -45,6 +49,7 @@ public class NiFiProperties extends Properties {
     public static final String FLOW_CONFIGURATION_FILE = 
"nifi.flow.configuration.file";
     public static final String FLOW_CONFIGURATION_ARCHIVE_FILE = 
"nifi.flow.configuration.archive.file";
     public static final String AUTHORITY_PROVIDER_CONFIGURATION_FILE = 
"nifi.authority.provider.configuration.file";
+    public static final String LOGIN_IDENTITY_PROVIDER_CONFIGURATION_FILE = 
"nifi.login.identity.provider.configuration.file";
     public static final String REPOSITORY_DATABASE_DIRECTORY = 
"nifi.database.directory";
     public static final String RESTORE_DIRECTORY = "nifi.restore.directory";
     public static final String VERSION = "nifi.version";
@@ -126,11 +131,12 @@ public class NiFiProperties extends Properties {
     public static final String SECURITY_TRUSTSTORE_PASSWD = 
"nifi.security.truststorePasswd";
     public static final String SECURITY_NEED_CLIENT_AUTH = 
"nifi.security.needClientAuth";
     public static final String SECURITY_USER_AUTHORITY_PROVIDER = 
"nifi.security.user.authority.provider";
+    public static final String SECURITY_USER_LOGIN_IDENTITY_PROVIDER = 
"nifi.security.user.login.identity.provider";
     public static final String SECURITY_CLUSTER_AUTHORITY_PROVIDER_PORT = 
"nifi.security.cluster.authority.provider.port";
     public static final String SECURITY_CLUSTER_AUTHORITY_PROVIDER_THREADS = 
"nifi.security.cluster.authority.provider.threads";
     public static final String SECURITY_USER_CREDENTIAL_CACHE_DURATION = 
"nifi.security.user.credential.cache.duration";
     public static final String SECURITY_SUPPORT_NEW_ACCOUNT_REQUESTS = 
"nifi.security.support.new.account.requests";
-    public static final String SECURITY_DEFAULT_USER_ROLES = 
"nifi.security.default.user.roles";
+    public static final String SECURITY_ANONYMOUS_AUTHORITIES = 
"nifi.security.anonymous.authorities";
     public static final String SECURITY_OCSP_RESPONDER_URL = 
"nifi.security.ocsp.responder.url";
     public static final String SECURITY_OCSP_RESPONDER_CERTIFICATE = 
"nifi.security.ocsp.responder.certificate";
 
@@ -187,6 +193,7 @@ public class NiFiProperties extends Properties {
     public static final String DEFAULT_TITLE = "NiFi";
     public static final Boolean DEFAULT_AUTO_RESUME_STATE = true;
     public static final String DEFAULT_AUTHORITY_PROVIDER_CONFIGURATION_FILE = 
"conf/authority-providers.xml";
+    public static final String 
DEFAULT_LOGIN_IDENTITY_PROVIDER_CONFIGURATION_FILE = 
"conf/login-identity-providers.xml";
     public static final String DEFAULT_USER_CREDENTIAL_CACHE_DURATION = "24 
hours";
     public static final Integer DEFAULT_REMOTE_INPUT_PORT = null;
     public static final Path DEFAULT_TEMPLATE_DIRECTORY = Paths.get("conf", 
"templates");
@@ -234,8 +241,7 @@ public class NiFiProperties extends Properties {
     }
 
     /**
-     * This is the method through which the NiFiProperties object should be
-     * obtained.
+     * This is the method through which the NiFiProperties object should be 
obtained.
      *
      * @return the NiFiProperties object to use
      * @throws RuntimeException if unable to load properties file
@@ -424,8 +430,7 @@ public class NiFiProperties extends Properties {
     }
 
     /**
-     * Returns whether the processors should be started automatically when the
-     * application loads.
+     * Returns whether the processors should be started automatically when the 
application loads.
      *
      * @return Whether to auto start the processors or not
      */
@@ -436,8 +441,7 @@ public class NiFiProperties extends Properties {
     }
 
     /**
-     * Returns the number of partitions that should be used for the FlowFile
-     * Repository
+     * Returns the number of partitions that should be used for the FlowFile 
Repository
      *
      * @return the number of partitions
      */
@@ -448,8 +452,7 @@ public class NiFiProperties extends Properties {
     }
 
     /**
-     * Returns the number of milliseconds between FlowFileRepository
-     * checkpointing
+     * Returns the number of milliseconds between FlowFileRepository 
checkpointing
      *
      * @return the number of milliseconds between checkpoint events
      */
@@ -481,6 +484,18 @@ public class NiFiProperties extends Properties {
             return new File(value);
         }
     }
+    
+    /**
+     * @return the user authorities file
+     */
+    public File getLoginIdentityProviderConfiguraitonFile() {
+        final String value = 
getProperty(LOGIN_IDENTITY_PROVIDER_CONFIGURATION_FILE);
+        if (StringUtils.isBlank(value)) {
+            return new 
File(DEFAULT_LOGIN_IDENTITY_PROVIDER_CONFIGURATION_FILE);
+        } else {
+            return new File(value);
+        }
+    }
 
     /**
      * Will default to true unless the value is explicitly set to false.
@@ -510,6 +525,19 @@ public class NiFiProperties extends Properties {
         return shouldSupport;
     }
 
+    public Set<String> getAnonymousAuthorities() {
+        final Set<String> authorities;
+
+        final String rawAnonymousAuthorities = 
getProperty(SECURITY_ANONYMOUS_AUTHORITIES);
+        if (!StringUtils.isEmpty(rawAnonymousAuthorities)) {
+            authorities = new 
HashSet<>(Arrays.asList(rawAnonymousAuthorities.split(",")));
+        } else {
+            authorities = Collections.EMPTY_SET;
+        }
+
+        return authorities;
+    }
+
     // getters for web properties //
     public Integer getPort() {
         Integer port = null;
@@ -851,8 +879,7 @@ public class NiFiProperties extends Properties {
     }
 
     /**
-     * Returns the database repository path. It simply returns the value
-     * configured. No directories will be created as a result of this 
operation.
+     * Returns the database repository path. It simply returns the value 
configured. No directories will be created as a result of this operation.
      *
      * @return database repository path
      * @throws InvalidPathException If the configured path is invalid
@@ -862,8 +889,7 @@ public class NiFiProperties extends Properties {
     }
 
     /**
-     * Returns the flow file repository path. It simply returns the value
-     * configured. No directories will be created as a result of this 
operation.
+     * Returns the flow file repository path. It simply returns the value 
configured. No directories will be created as a result of this operation.
      *
      * @return database repository path
      * @throws InvalidPathException If the configured path is invalid
@@ -873,10 +899,8 @@ public class NiFiProperties extends Properties {
     }
 
     /**
-     * Returns the content repository paths. This method returns a mapping of
-     * file repository name to file repository paths. It simply returns the
-     * values configured. No directories will be created as a result of this
-     * operation.
+     * Returns the content repository paths. This method returns a mapping of 
file repository name to file repository paths. It simply returns the values 
configured. No directories will be created as
+     * a result of this operation.
      *
      * @return file repositories paths
      * @throws InvalidPathException If any of the configured paths are invalid
@@ -900,10 +924,8 @@ public class NiFiProperties extends Properties {
     }
 
     /**
-     * Returns the provenance repository paths. This method returns a mapping 
of
-     * file repository name to file repository paths. It simply returns the
-     * values configured. No directories will be created as a result of this
-     * operation.
+     * Returns the provenance repository paths. This method returns a mapping 
of file repository name to file repository paths. It simply returns the values 
configured. No directories will be created
+     * as a result of this operation.
      *
      * @return the name and paths of all provenance repository locations
      */

http://git-wip-us.apache.org/repos/asf/nifi/blob/a40e5a07/nifi-nar-bundles/nifi-framework-bundle/nifi-framework-nar/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework-nar/pom.xml 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework-nar/pom.xml
index fcfcfe7..3773ac7 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework-nar/pom.xml
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework-nar/pom.xml
@@ -35,6 +35,10 @@
             <groupId>org.apache.nifi</groupId>
             <artifactId>nifi-file-authorization-provider</artifactId>
         </dependency>
+        <dependency>
+            <groupId>org.apache.nifi</groupId>
+            <artifactId>nifi-file-identity-provider</artifactId>
+        </dependency>
 
         <!-- mark these nifi artifacts as provided since it is included in the 
lib -->
         <dependency>

http://git-wip-us.apache.org/repos/asf/nifi/blob/a40e5a07/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/pom.xml
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/pom.xml
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/pom.xml
index ad2d2f0..b8f3e98 100644
--- 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/pom.xml
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/pom.xml
@@ -53,7 +53,6 @@
                     <excludes>**/authorization/generated/*.java,</excludes>
                 </configuration>
             </plugin>            
-
         </plugins>
     </build>
     <dependencies>

http://git-wip-us.apache.org/repos/asf/nifi/blob/a40e5a07/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/java/org/apache/nifi/admin/AuditDataSourceFactoryBean.java
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/java/org/apache/nifi/admin/AuditDataSourceFactoryBean.java
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/java/org/apache/nifi/admin/AuditDataSourceFactoryBean.java
index aeb2755..7e68799 100644
--- 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/java/org/apache/nifi/admin/AuditDataSourceFactoryBean.java
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/java/org/apache/nifi/admin/AuditDataSourceFactoryBean.java
@@ -19,6 +19,7 @@ package org.apache.nifi.admin;
 import java.io.File;
 import java.sql.Connection;
 import java.sql.ResultSet;
+import java.sql.ResultSetMetaData;
 import java.sql.SQLException;
 import java.sql.Statement;
 import org.apache.commons.lang3.StringUtils;
@@ -45,8 +46,8 @@ public class AuditDataSourceFactoryBean implements 
FactoryBean {
     // ------------
     private static final String CREATE_ACTION_TABLE = "CREATE TABLE ACTION ("
             + "ID INT NOT NULL PRIMARY KEY AUTO_INCREMENT, "
-            + "USER_DN VARCHAR2(255) NOT NULL, "
-            + "USER_NAME VARCHAR2(100) NOT NULL, "
+            + "IDENTITY VARCHAR2(4096) NOT NULL, "
+            + "USER_NAME VARCHAR2(4096) NOT NULL, "
             + "SOURCE_ID VARCHAR2(100) NOT NULL, "
             + "SOURCE_NAME VARCHAR2(1000) NOT NULL, "
             + "SOURCE_TYPE VARCHAR2(1000) NOT NULL, "
@@ -107,6 +108,10 @@ public class AuditDataSourceFactoryBean implements 
FactoryBean {
             + "FOREIGN KEY (ACTION_ID) REFERENCES ACTION(ID)"
             + ")";
 
+    private static final String RENAME_DN_COLUMN = "ALTER TABLE ACTION ALTER 
COLUMN USER_DN RENAME TO IDENTITY";
+    private static final String RESIZE_IDENTITY_COLUMN = "ALTER TABLE ACTION 
MODIFY IDENTITY VARCHAR(4096)";
+    private static final String RESIZE_USER_NAME_COLUMN = "ALTER TABLE ACTION 
MODIFY USER_NAME VARCHAR(4096)";
+
     private JdbcConnectionPool connectionPool;
 
     private NiFiProperties properties;
@@ -148,15 +153,15 @@ public class AuditDataSourceFactoryBean implements 
FactoryBean {
                 connection = connectionPool.getConnection();
                 connection.setAutoCommit(false);
 
+                // create a statement for initializing the database
+                statement = connection.createStatement();
+
                 // determine if the tables need to be created
                 rs = connection.getMetaData().getTables(null, null, "ACTION", 
null);
                 if (!rs.next()) {
                     logger.info("Database not built for repository: " + 
databaseUrl + ".  Building now...");
                     RepositoryUtils.closeQuietly(rs);
 
-                    // create a statement for initializing the database
-                    statement = connection.createStatement();
-
                     // action table
                     statement.execute(CREATE_ACTION_TABLE);
 
@@ -171,6 +176,14 @@ public class AuditDataSourceFactoryBean implements 
FactoryBean {
                     statement.execute(CREATE_PURGE_DETAILS_TABLE);
                 } else {
                     logger.info("Existing database found and connected to at: 
" + databaseUrl);
+
+                    // get the RS metadata to see if we need to transform the 
table
+                    final ResultSetMetaData rsMetadata = rs.getMetaData();
+                    if (hasDnColumn(rsMetadata)) {
+                        statement.execute(RENAME_DN_COLUMN);
+                        statement.execute(RESIZE_IDENTITY_COLUMN);
+                        statement.execute(RESIZE_USER_NAME_COLUMN);
+                    }
                 }
 
                 // commit any changes
@@ -188,6 +201,16 @@ public class AuditDataSourceFactoryBean implements 
FactoryBean {
         return connectionPool;
     }
 
+    private boolean hasDnColumn(final ResultSetMetaData rsMetadata) throws 
SQLException {
+        boolean hasDn = false;
+        for (int i = 1; i <= rsMetadata.getColumnCount() && !hasDn; i++) {
+            if ("USER_DN".equals(rsMetadata.getColumnName(i))) {
+                hasDn = true;
+            }
+        }
+        return hasDn;
+    }
+
     @Override
     public Class getObjectType() {
         return JdbcConnectionPool.class;

http://git-wip-us.apache.org/repos/asf/nifi/blob/a40e5a07/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/java/org/apache/nifi/admin/UserDataSourceFactoryBean.java
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/java/org/apache/nifi/admin/UserDataSourceFactoryBean.java
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/java/org/apache/nifi/admin/UserDataSourceFactoryBean.java
index ebcf574..f30bfc7 100644
--- 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/java/org/apache/nifi/admin/UserDataSourceFactoryBean.java
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/java/org/apache/nifi/admin/UserDataSourceFactoryBean.java
@@ -19,10 +19,14 @@ package org.apache.nifi.admin;
 import java.io.File;
 import java.sql.Connection;
 import java.sql.ResultSet;
+import java.sql.ResultSetMetaData;
 import java.sql.SQLException;
 import java.sql.Statement;
+import java.util.HashSet;
+import java.util.Set;
 import java.util.UUID;
 import org.apache.commons.lang3.StringUtils;
+import org.apache.nifi.authorization.Authority;
 import org.h2.jdbcx.JdbcConnectionPool;
 import org.apache.nifi.user.NiFiUser;
 import org.apache.nifi.util.NiFiProperties;
@@ -41,8 +45,8 @@ public class UserDataSourceFactoryBean implements FactoryBean 
{
 
     private static final String CREATE_USER_TABLE = "CREATE TABLE USER ("
             + "ID VARCHAR2(100) NOT NULL PRIMARY KEY, "
-            + "DN VARCHAR2(255) NOT NULL UNIQUE, "
-            + "USER_NAME VARCHAR2(100) NOT NULL, "
+            + "IDENTITY VARCHAR2(4096) NOT NULL UNIQUE, "
+            + "USER_NAME VARCHAR2(4096) NOT NULL, "
             + "USER_GROUP VARCHAR2(100), "
             + "CREATION TIMESTAMP NOT NULL, "
             + "LAST_ACCESSED TIMESTAMP, "
@@ -60,7 +64,7 @@ public class UserDataSourceFactoryBean implements FactoryBean 
{
             + ")";
 
     private static final String INSERT_ANONYMOUS_USER = "INSERT INTO USER ("
-            + "ID, DN, USER_NAME, CREATION, LAST_VERIFIED, JUSTIFICATION, 
STATUS"
+            + "ID, IDENTITY, USER_NAME, CREATION, LAST_VERIFIED, 
JUSTIFICATION, STATUS"
             + ") VALUES ("
             + "'" + UUID.randomUUID().toString() + "', "
             + "'" + NiFiUser.ANONYMOUS_USER_DN + "', "
@@ -71,46 +75,19 @@ public class UserDataSourceFactoryBean implements 
FactoryBean {
             + "'ACTIVE'"
             + ")";
 
-    private static final String INSERT_ANONYMOUS_MONITOR_AUTHORITY = "INSERT 
INTO AUTHORITY ("
+    private static final String INSERT_ANONYMOUS_AUTHORITY = "INSERT INTO 
AUTHORITY ("
             + "USER_ID, ROLE"
             + ") VALUES ("
-            + "(SELECT ID FROM USER WHERE DN = '" + NiFiUser.ANONYMOUS_USER_DN 
+ "'), "
-            + "'ROLE_MONITOR'"
+            + "(SELECT ID FROM USER WHERE IDENTITY = '" + 
NiFiUser.ANONYMOUS_USER_DN + "'), "
+            + "'%s'"
             + ")";
 
-    private static final String INSERT_ANONYMOUS_DFM_AUTHORITY = "INSERT INTO 
AUTHORITY ("
-            + "USER_ID, ROLE"
-            + ") VALUES ("
-            + "(SELECT ID FROM USER WHERE DN = '" + NiFiUser.ANONYMOUS_USER_DN 
+ "'), "
-            + "'ROLE_DFM'"
-            + ")";
-
-    private static final String INSERT_ANONYMOUS_ADMIN_AUTHORITY = "INSERT 
INTO AUTHORITY ("
-            + "USER_ID, ROLE"
-            + ") VALUES ("
-            + "(SELECT ID FROM USER WHERE DN = '" + NiFiUser.ANONYMOUS_USER_DN 
+ "'), "
-            + "'ROLE_ADMIN'"
-            + ")";
+    private static final String DELETE_ANONYMOUS_AUTHORITIES = "DELETE FROM 
AUTHORITY "
+            + "WHERE USER_ID = (SELECT ID FROM USER WHERE IDENTITY = '" + 
NiFiUser.ANONYMOUS_USER_DN + "')";
 
-    private static final String INSERT_ANONYMOUS_NIFI_AUTHORITY = "INSERT INTO 
AUTHORITY ("
-            + "USER_ID, ROLE"
-            + ") VALUES ("
-            + "(SELECT ID FROM USER WHERE DN = '" + NiFiUser.ANONYMOUS_USER_DN 
+ "'), "
-            + "'ROLE_NIFI'"
-            + ")";
-
-    private static final String INSERT_ANONYMOUS_PROVENANCE_AUTHORITY = 
"INSERT INTO AUTHORITY ("
-            + "USER_ID, ROLE"
-            + ") VALUES ("
-            + "(SELECT ID FROM USER WHERE DN = '" + NiFiUser.ANONYMOUS_USER_DN 
+ "'), "
-            + "'ROLE_PROVENANCE'"
-            + ")";
-
-    private static final String SELECT_ANONYMOUS_PROVENANCE_AUTHORITY = 
"SELECT * FROM AUTHORITY "
-            + "WHERE "
-            + "USER_ID = (SELECT ID FROM USER WHERE DN = '" + 
NiFiUser.ANONYMOUS_USER_DN + "') "
-            + "AND "
-            + "ROLE = 'ROLE_PROVENANCE'";
+    private static final String RENAME_DN_COLUMN = "ALTER TABLE USER ALTER 
COLUMN DN RENAME TO IDENTITY";
+    private static final String RESIZE_IDENTITY_COLUMN = "ALTER TABLE USER 
MODIFY IDENTITY VARCHAR(4096)";
+    private static final String RESIZE_USER_NAME_COLUMN = "ALTER TABLE USER 
MODIFY USER_NAME VARCHAR(4096)";
 
     private JdbcConnectionPool connectionPool;
 
@@ -128,6 +105,17 @@ public class UserDataSourceFactoryBean implements 
FactoryBean {
                 throw new NullPointerException("Database directory must be 
specified.");
             }
 
+            // get the roles being granted to anonymous users
+            final Set<String> rawAnonymousAuthorities = new 
HashSet<>(properties.getAnonymousAuthorities());
+            final Set<Authority> anonymousAuthorities = 
Authority.convertRawAuthorities(rawAnonymousAuthorities);
+
+            // ensure every authorities was recognized
+            if (rawAnonymousAuthorities.size() != anonymousAuthorities.size()) 
{
+                final Set<String> validAuthorities = 
Authority.convertAuthorities(anonymousAuthorities);
+                rawAnonymousAuthorities.removeAll(validAuthorities);
+                throw new IllegalStateException("Invalid authorities 
specified: " + StringUtils.join(rawAnonymousAuthorities, ", "));
+            }
+
             // create a handle to the repository directory
             File repositoryDirectory = new File(repositoryDirectoryPath);
 
@@ -161,21 +149,24 @@ public class UserDataSourceFactoryBean implements 
FactoryBean {
 
                     // seed the anonymous user
                     statement.execute(INSERT_ANONYMOUS_USER);
-                    statement.execute(INSERT_ANONYMOUS_MONITOR_AUTHORITY);
-                    statement.execute(INSERT_ANONYMOUS_DFM_AUTHORITY);
-                    statement.execute(INSERT_ANONYMOUS_ADMIN_AUTHORITY);
-                    statement.execute(INSERT_ANONYMOUS_NIFI_AUTHORITY);
                 } else {
                     logger.info("Existing database found and connected to at: 
" + databaseUrl);
-                }
 
-                // close the previous result set
-                RepositoryUtils.closeQuietly(rs);
+                    // get the RS metadata to see if we need to transform the 
table
+                    final ResultSetMetaData rsMetadata = rs.getMetaData();
+                    if (hasDnColumn(rsMetadata)) {
+                        statement.execute(RENAME_DN_COLUMN);
+                        statement.execute(RESIZE_IDENTITY_COLUMN);
+                        statement.execute(RESIZE_USER_NAME_COLUMN);
+                    }
 
-                // merge in the provenance role to handle existing databases
-                rs = 
statement.executeQuery(SELECT_ANONYMOUS_PROVENANCE_AUTHORITY);
-                if (!rs.next()) {
-                    statement.execute(INSERT_ANONYMOUS_PROVENANCE_AUTHORITY);
+                    // remove all authorities for the anonymous user
+                    statement.execute(DELETE_ANONYMOUS_AUTHORITIES);
+                }
+
+                // add all authorities for the anonymous user
+                for (final Authority authority : anonymousAuthorities) {
+                    
statement.execute(String.format(INSERT_ANONYMOUS_AUTHORITY, authority.name()));
                 }
 
                 // commit any changes
@@ -193,6 +184,16 @@ public class UserDataSourceFactoryBean implements 
FactoryBean {
         return connectionPool;
     }
 
+    private boolean hasDnColumn(final ResultSetMetaData rsMetadata) throws 
SQLException {
+        boolean hasDn = false;
+        for (int i = 1; i <= rsMetadata.getColumnCount() && !hasDn; i++) {
+            if ("DN".equals(rsMetadata.getColumnName(i))) {
+                hasDn = true;
+            }
+        }
+        return hasDn;
+    }
+
     private String getDatabaseUrl(File databaseFile) {
         String databaseUrl = "jdbc:h2:" + databaseFile + 
";AUTOCOMMIT=OFF;DB_CLOSE_ON_EXIT=FALSE;LOCK_MODE=3";
         String databaseUrlAppend = 
properties.getProperty(NiFiProperties.H2_URL_APPEND);

http://git-wip-us.apache.org/repos/asf/nifi/blob/a40e5a07/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/java/org/apache/nifi/admin/dao/impl/StandardActionDAO.java
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/java/org/apache/nifi/admin/dao/impl/StandardActionDAO.java
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/java/org/apache/nifi/admin/dao/impl/StandardActionDAO.java
index fe693e1..8fdfd34 100644
--- 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/java/org/apache/nifi/admin/dao/impl/StandardActionDAO.java
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/java/org/apache/nifi/admin/dao/impl/StandardActionDAO.java
@@ -63,7 +63,7 @@ public class StandardActionDAO implements ActionDAO {
     // action table
     // ------------
     private static final String INSERT_ACTION = "INSERT INTO ACTION ("
-            + "USER_DN, USER_NAME, SOURCE_ID, SOURCE_NAME, SOURCE_TYPE, 
OPERATION, ACTION_TIMESTAMP"
+            + "IDENTITY, USER_NAME, SOURCE_ID, SOURCE_NAME, SOURCE_TYPE, 
OPERATION, ACTION_TIMESTAMP"
             + ") VALUES ("
             + "?, "
             + "?, "
@@ -216,8 +216,8 @@ public class StandardActionDAO implements ActionDAO {
         try {
             // obtain a statement to insert to the action table
             statement = connection.prepareStatement(INSERT_ACTION, 
Statement.RETURN_GENERATED_KEYS);
-            statement.setString(1, StringUtils.left(action.getUserIdentity(), 
255));
-            statement.setString(2, StringUtils.left(action.getUserName(), 
100));
+            statement.setString(1, StringUtils.left(action.getUserIdentity(), 
4096));
+            statement.setString(2, StringUtils.left(action.getUserName(), 
4096));
             statement.setString(3, action.getSourceId());
             statement.setString(4, StringUtils.left(action.getSourceName(), 
1000));
             statement.setString(5, action.getSourceType().toString());
@@ -561,7 +561,7 @@ public class StandardActionDAO implements ActionDAO {
 
                 FlowChangeAction action = new FlowChangeAction();
                 action.setId(actionId);
-                action.setUserIdentity(rs.getString("USER_DN"));
+                action.setUserIdentity(rs.getString("IDENTITY"));
                 action.setUserName(rs.getString("USER_NAME"));
                 
action.setOperation(Operation.valueOf(rs.getString("OPERATION")));
                 action.setTimestamp(new 
Date(rs.getTimestamp("ACTION_TIMESTAMP").getTime()));
@@ -635,7 +635,7 @@ public class StandardActionDAO implements ActionDAO {
                 // populate the action
                 action = new FlowChangeAction();
                 action.setId(rs.getInt("ID"));
-                action.setUserIdentity(rs.getString("USER_DN"));
+                action.setUserIdentity(rs.getString("IDENTITY"));
                 action.setUserName(rs.getString("USER_NAME"));
                 action.setOperation(operation);
                 action.setTimestamp(new 
Date(rs.getTimestamp("ACTION_TIMESTAMP").getTime()));

http://git-wip-us.apache.org/repos/asf/nifi/blob/a40e5a07/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/java/org/apache/nifi/admin/dao/impl/StandardUserDAO.java
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/java/org/apache/nifi/admin/dao/impl/StandardUserDAO.java
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/java/org/apache/nifi/admin/dao/impl/StandardUserDAO.java
index f6a62df..807f87a 100644
--- 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/java/org/apache/nifi/admin/dao/impl/StandardUserDAO.java
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/java/org/apache/nifi/admin/dao/impl/StandardUserDAO.java
@@ -45,9 +45,9 @@ public class StandardUserDAO implements UserDAO {
             + "FROM USER U "
             + "WHERE U.STATUS = 'PENDING'";
 
-    private static final String SELECT_USER_BY_DN = "SELECT "
+    private static final String SELECT_USER_BY_USER = "SELECT "
             + "U.ID, "
-            + "U.DN, "
+            + "U.IDENTITY, "
             + "U.USER_NAME, "
             + "U.USER_GROUP, "
             + "U.CREATION, "
@@ -59,11 +59,11 @@ public class StandardUserDAO implements UserDAO {
             + "FROM USER U "
             + "LEFT JOIN AUTHORITY A " // ensures that users without 
authorities are still matched
             + "ON U.ID = A.USER_ID "
-            + "WHERE U.DN = ?";
+            + "WHERE U.IDENTITY = ?";
 
     private static final String SELECT_USER_BY_ID = "SELECT "
             + "U.ID, "
-            + "U.DN, "
+            + "U.IDENTITY, "
             + "U.USER_NAME, "
             + "U.USER_GROUP, "
             + "U.CREATION, "
@@ -79,7 +79,7 @@ public class StandardUserDAO implements UserDAO {
 
     private static final String SELECT_USERS = "SELECT "
             + "U.ID, "
-            + "U.DN, "
+            + "U.IDENTITY, "
             + "U.USER_NAME, "
             + "U.USER_GROUP, "
             + "U.CREATION, "
@@ -91,7 +91,7 @@ public class StandardUserDAO implements UserDAO {
             + "FROM USER U "
             + "LEFT JOIN AUTHORITY A " // ensures that users without 
authorities are still matched
             + "ON U.ID = A.USER_ID "
-            + "WHERE U.DN <> ?";
+            + "WHERE U.IDENTITY <> ?";
 
     private static final String SELECT_USER_GROUPS = "SELECT DISTINCT "
             + "U.USER_GROUP "
@@ -99,7 +99,7 @@ public class StandardUserDAO implements UserDAO {
 
     private static final String SELECT_USER_GROUP = "SELECT "
             + "U.ID, "
-            + "U.DN, "
+            + "U.IDENTITY, "
             + "U.USER_NAME, "
             + "U.USER_GROUP, "
             + "U.CREATION, "
@@ -111,10 +111,10 @@ public class StandardUserDAO implements UserDAO {
             + "FROM USER U "
             + "LEFT JOIN AUTHORITY A " // ensures that users without 
authorities are still matched
             + "ON U.ID = A.USER_ID "
-            + "WHERE U.DN <> ? AND U.USER_GROUP = ?";
+            + "WHERE U.IDENTITY <> ? AND U.USER_GROUP = ?";
 
     private static final String INSERT_USER = "INSERT INTO USER ("
-            + "ID, DN, USER_NAME, USER_GROUP, CREATION, LAST_VERIFIED, 
JUSTIFICATION, STATUS"
+            + "ID, IDENTITY, USER_NAME, USER_GROUP, CREATION, LAST_VERIFIED, 
JUSTIFICATION, STATUS"
             + ") VALUES ("
             + "?, "
             + "?, "
@@ -127,7 +127,7 @@ public class StandardUserDAO implements UserDAO {
             + ")";
 
     private static final String UPDATE_USER = "UPDATE USER SET "
-            + "DN = ?, "
+            + "IDENTITY = ?, "
             + "USER_NAME = ?, "
             + "USER_GROUP = ?, "
             + "LAST_ACCESSED = ?, "
@@ -211,7 +211,7 @@ public class StandardUserDAO implements UserDAO {
                 if (user == null || !userId.equals(user.getId())) {
                     user = new NiFiUser();
                     user.setId(userId);
-                    user.setDn(rs.getString("DN"));
+                    user.setDn(rs.getString("IDENTITY"));
                     user.setUserName(rs.getString("USER_NAME"));
                     user.setUserGroup(rs.getString("USER_GROUP"));
                     user.setJustification(rs.getString("JUSTIFICATION"));
@@ -305,7 +305,7 @@ public class StandardUserDAO implements UserDAO {
                 if (user == null || !userId.equals(user.getId())) {
                     user = new NiFiUser();
                     user.setId(userId);
-                    user.setDn(rs.getString("DN"));
+                    user.setDn(rs.getString("IDENTITY"));
                     user.setUserName(rs.getString("USER_NAME"));
                     user.setUserGroup(rs.getString("USER_GROUP"));
                     user.setJustification(rs.getString("JUSTIFICATION"));
@@ -366,7 +366,7 @@ public class StandardUserDAO implements UserDAO {
                 if (user == null) {
                     user = new NiFiUser();
                     user.setId(rs.getString("ID"));
-                    user.setDn(rs.getString("DN"));
+                    user.setDn(rs.getString("IDENTITY"));
                     user.setUserName(rs.getString("USER_NAME"));
                     user.setUserGroup(rs.getString("USER_GROUP"));
                     user.setJustification(rs.getString("JUSTIFICATION"));
@@ -409,7 +409,7 @@ public class StandardUserDAO implements UserDAO {
         ResultSet rs = null;
         try {
             // create the connection and obtain a statement
-            statement = connection.prepareStatement(SELECT_USER_BY_DN);
+            statement = connection.prepareStatement(SELECT_USER_BY_USER);
             statement.setString(1, dn);
 
             // execute the query
@@ -424,7 +424,7 @@ public class StandardUserDAO implements UserDAO {
                 if (user == null) {
                     user = new NiFiUser();
                     user.setId(rs.getString("ID"));
-                    user.setDn(rs.getString("DN"));
+                    user.setDn(rs.getString("IDENTITY"));
                     user.setUserName(rs.getString("USER_NAME"));
                     user.setUserGroup(rs.getString("USER_GROUP"));
                     user.setJustification(rs.getString("JUSTIFICATION"));
@@ -475,8 +475,8 @@ public class StandardUserDAO implements UserDAO {
             // create a statement
             statement = connection.prepareStatement(INSERT_USER, 
Statement.RETURN_GENERATED_KEYS);
             statement.setString(1, id);
-            statement.setString(2, StringUtils.left(user.getDn(), 255));
-            statement.setString(3, StringUtils.left(user.getUserName(), 100));
+            statement.setString(2, StringUtils.left(user.getDn(), 4096));
+            statement.setString(3, StringUtils.left(user.getUserName(), 4096));
             statement.setString(4, StringUtils.left(user.getUserGroup(), 100));
             if (user.getLastVerified() != null) {
                 statement.setTimestamp(5, new 
java.sql.Timestamp(user.getLastVerified().getTime()));
@@ -531,8 +531,8 @@ public class StandardUserDAO implements UserDAO {
         try {
             // create a statement
             statement = connection.prepareStatement(UPDATE_USER);
-            statement.setString(1, StringUtils.left(user.getDn(), 255));
-            statement.setString(2, StringUtils.left(user.getUserName(), 100));
+            statement.setString(1, StringUtils.left(user.getDn(), 4096));
+            statement.setString(2, StringUtils.left(user.getUserName(), 4096));
             statement.setString(3, StringUtils.left(user.getUserGroup(), 100));
             statement.setString(6, StringUtils.left(user.getJustification(), 
500));
             statement.setString(7, user.getStatus().toString());

http://git-wip-us.apache.org/repos/asf/nifi/blob/a40e5a07/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-authorized-users/pom.xml
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-authorized-users/pom.xml
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-authorized-users/pom.xml
new file mode 100644
index 0000000..6ec8236
--- /dev/null
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-authorized-users/pom.xml
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  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.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0"; 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"; 
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
http://maven.apache.org/xsd/maven-4.0.0.xsd";>
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>org.apache.nifi</groupId>
+        <artifactId>nifi-framework</artifactId>
+        <version>0.3.1-SNAPSHOT</version>
+    </parent>
+    <artifactId>nifi-authorized-users</artifactId>
+    <build>
+        <resources>
+            <resource>
+                <directory>src/main/resources</directory>
+            </resource>
+            <resource>
+                <directory>src/main/xsd</directory>
+            </resource>
+        </resources>
+        <plugins>
+            <plugin>
+                <groupId>org.codehaus.mojo</groupId>
+                <artifactId>jaxb2-maven-plugin</artifactId>
+                <executions>
+                    <execution>
+                        <id>xjc</id>
+                        <goals>
+                            <goal>xjc</goal>
+                        </goals>
+                        <configuration>
+                            
<packageName>org.apache.nifi.user.generated</packageName>
+                        </configuration>
+                    </execution>
+                </executions>
+                <configuration>
+                    
<generateDirectory>${project.build.directory}/generated-sources/jaxb</generateDirectory>
+                </configuration>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-checkstyle-plugin</artifactId>
+                <configuration>
+                    <excludes>**/user/generated/*.java</excludes>
+                </configuration>
+            </plugin>            
+        </plugins>
+    </build>
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.nifi</groupId>
+            <artifactId>nifi-api</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.nifi</groupId>
+            <artifactId>nifi-properties</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.nifi</groupId>
+            <artifactId>nifi-utils</artifactId>
+        </dependency>
+    </dependencies>
+</project>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/nifi/blob/a40e5a07/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-authorized-users/src/main/java/org/apache/nifi/authorized/users/AuthorizedUsers.java
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-authorized-users/src/main/java/org/apache/nifi/authorized/users/AuthorizedUsers.java
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-authorized-users/src/main/java/org/apache/nifi/authorized/users/AuthorizedUsers.java
new file mode 100644
index 0000000..e4be3f7
--- /dev/null
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-authorized-users/src/main/java/org/apache/nifi/authorized/users/AuthorizedUsers.java
@@ -0,0 +1,376 @@
+/*
+ * 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.authorized.users;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import javax.xml.XMLConstants;
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.JAXBElement;
+import javax.xml.bind.JAXBException;
+import javax.xml.bind.Marshaller;
+import javax.xml.bind.Unmarshaller;
+import javax.xml.transform.stream.StreamSource;
+import javax.xml.validation.Schema;
+import javax.xml.validation.SchemaFactory;
+import org.apache.nifi.authorization.exception.AuthorityAccessException;
+import org.apache.nifi.authorization.exception.ProviderCreationException;
+import org.apache.nifi.authorization.exception.UnknownIdentityException;
+import org.apache.nifi.user.generated.LoginUser;
+import org.apache.nifi.user.generated.NiFiUser;
+import org.apache.nifi.user.generated.User;
+import org.apache.nifi.user.generated.Users;
+import org.apache.nifi.util.NiFiProperties;
+import org.apache.nifi.util.file.FileUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.xml.sax.SAXException;
+
+/**
+ * Access to the configured Authorized Users.
+ */
+public final class AuthorizedUsers {
+
+    private static final Logger logger = 
LoggerFactory.getLogger(AuthorizedUsers.class);
+
+    private static final String USERS_XSD = "/users.xsd";
+    private static final String JAXB_GENERATED_PATH = 
"org.apache.nifi.user.generated";
+    private static final JAXBContext JAXB_CONTEXT = initializeJaxbContext();
+
+    private static final Map<String, AuthorizedUsers> instances = new 
HashMap<>();
+
+    private File usersFile;
+    private File restoreFile;
+
+    /**
+     * Load the JAXBContext.
+     */
+    private static JAXBContext initializeJaxbContext() {
+        try {
+            return JAXBContext.newInstance(JAXB_GENERATED_PATH, 
AuthorizedUsers.class.getClassLoader());
+        } catch (JAXBException e) {
+            throw new RuntimeException("Unable to create JAXBContext.");
+        }
+    }
+
+    private AuthorizedUsers(final File usersFile, final NiFiProperties 
properties) throws IOException, IllegalStateException {
+        this.usersFile = usersFile;
+
+        // the restore directory is optional and may be null
+        final File restoreDirectory = properties.getRestoreDirectory();
+        if (restoreDirectory != null) {
+
+            // sanity check that restore directory is a directory, creating it 
if necessary
+            FileUtils.ensureDirectoryExistAndCanAccess(restoreDirectory);
+
+            // check that restore directory is not the same as the primary 
directory
+            final File usersFileDirectory = usersFile.getParentFile();
+            if 
(usersFileDirectory.getAbsolutePath().equals(restoreDirectory.getAbsolutePath()))
 {
+                throw new IllegalStateException(String.format("Directory of 
users file '%s' is the same as restore directory '%s' ",
+                        usersFileDirectory.getAbsolutePath(), 
restoreDirectory.getAbsolutePath()));
+            }
+
+            // the restore copy will have same file name, but reside in a 
different directory
+            restoreFile = new File(restoreDirectory, usersFile.getName());
+
+            // sync the primary copy with the restore copy
+            try {
+                FileUtils.syncWithRestore(usersFile, restoreFile, logger);
+            } catch (final IOException | IllegalStateException ioe) {
+                throw new ProviderCreationException(ioe);
+            }
+        }
+    }
+
+    public static AuthorizedUsers getInstance(final String usersFilePath, 
final NiFiProperties properties) throws IOException, IllegalStateException {
+        final File usersFile = new File(usersFilePath);
+
+        // see if an authorizedUsers has already been created using this 
filename
+        AuthorizedUsers authorizedUsers = instances.get(usersFile.getName());
+
+        if (authorizedUsers == null) {
+            // create a new authorizedUsers
+            authorizedUsers = new AuthorizedUsers(usersFile, properties);
+
+            // store it for later
+            instances.put(usersFile.getName(), authorizedUsers);
+        } else {
+            // ensure the file paths are the same, the restore capability 
cannot support different files with the same name
+            if (!authorizedUsers.usersFile.equals(usersFile)) {
+                throw new IllegalStateException(String.format("A users file 
with this name has already been initialized. The name must be unique given the 
constraints of "
+                        + "the restore directory. The paths in question are 
'%s' and '%s'", authorizedUsers.usersFile.getAbsolutePath(), 
usersFile.getAbsolutePath()));
+            }
+        }
+
+        return authorizedUsers;
+    }
+
+    public String getUserIdentity(final NiFiUser user) {
+        if (User.class.isAssignableFrom(user.getClass())) {
+            return ((User) user).getDn();
+        } else {
+            return ((LoginUser) user).getUsername();
+        }
+    }
+
+    public synchronized Users getUsers() {
+        try {
+            // ensure the directory exists and it can be created
+            if (!usersFile.exists() && !usersFile.mkdirs()) {
+                throw new IllegalStateException("The users file does not exist 
and could not be created.");
+            }
+
+            // find the schema
+            final SchemaFactory schemaFactory = 
SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
+            final Schema schema = 
schemaFactory.newSchema(AuthorizedUsers.class.getResource(USERS_XSD));
+
+            // attempt to unmarshal
+            final Unmarshaller unmarshaller = 
JAXB_CONTEXT.createUnmarshaller();
+            unmarshaller.setSchema(schema);
+            final JAXBElement<Users> element = unmarshaller.unmarshal(new 
StreamSource(usersFile), Users.class);
+            return element.getValue();
+        } catch (SAXException | JAXBException e) {
+            throw new AuthorityAccessException(e.getMessage(), e);
+        }
+    }
+
+    public synchronized boolean hasUser(final HasUser finder) {
+        // load the users
+        final Users users = getUsers();
+
+        // combine the user lists
+        final List<NiFiUser> nifiUsers = new ArrayList<>();
+        nifiUsers.addAll(users.getUser());
+        nifiUsers.addAll(users.getLoginUser());
+
+        // find the desired user
+        return finder.hasUser(nifiUsers);
+    }
+
+    public synchronized NiFiUser getUser(final FindUser finder) {
+        // load the users
+        final Users users = getUsers();
+
+        // combine the user lists
+        final List<NiFiUser> nifiUsers = new ArrayList<>();
+        nifiUsers.addAll(users.getUser());
+        nifiUsers.addAll(users.getLoginUser());
+
+        // find the desired user
+        return finder.findUser(nifiUsers);
+    }
+
+    public synchronized List<NiFiUser> getUsers(final FindUsers finder) {
+        // load the users
+        final Users users = getUsers();
+
+        // combine the user lists
+        final List<NiFiUser> nifiUsers = new ArrayList<>();
+        nifiUsers.addAll(users.getUser());
+        nifiUsers.addAll(users.getLoginUser());
+
+        // find the desired user
+        return finder.findUsers(nifiUsers);
+    }
+
+    public synchronized void createUser(final CreateUser creator) {
+        // add the user
+        final Users users = getUsers();
+
+        // create the user
+        final NiFiUser newUser = creator.createUser();
+        if (User.class.isAssignableFrom(newUser.getClass())) {
+            users.getUser().add((User) newUser);
+        } else {
+            users.getLoginUser().add((LoginUser) newUser);
+        }
+
+        // save the users
+        saveUsers(users);
+    }
+
+    public synchronized void updateUser(final FindUser finder, final 
UpdateUser updater) {
+        // update the user
+        final Users users = getUsers();
+
+        // combine the user lists
+        final List<NiFiUser> nifiUsers = new ArrayList<>();
+        nifiUsers.addAll(users.getUser());
+        nifiUsers.addAll(users.getLoginUser());
+
+        // find the user to update
+        final NiFiUser user = finder.findUser(nifiUsers);
+
+        // update the user
+        updater.updateUser(user);
+
+        // save the users
+        saveUsers(users);
+    }
+
+    public synchronized void updateUsers(final FindUsers finder, final 
UpdateUsers updater) {
+        // update the user
+        final Users users = getUsers();
+
+        // combine the user lists
+        final List<NiFiUser> nifiUsers = new ArrayList<>();
+        nifiUsers.addAll(users.getUser());
+        nifiUsers.addAll(users.getLoginUser());
+
+        final List<NiFiUser> userToUpdate = finder.findUsers(nifiUsers);
+
+        // update the user
+        updater.updateUsers(userToUpdate);
+
+        // save the users
+        saveUsers(users);
+    }
+
+    public synchronized Users removeUser(final FindUser finder) {
+        // load the users
+        final Users users = getUsers();
+
+        // combine the user lists
+        final List<NiFiUser> nifiUsers = new ArrayList<>();
+        nifiUsers.addAll(users.getUser());
+        nifiUsers.addAll(users.getLoginUser());
+
+        // find the desired user
+        final NiFiUser user = finder.findUser(nifiUsers);
+        if (User.class.isAssignableFrom(user.getClass())) {
+            users.getUser().remove((User) user);
+        } else {
+            users.getLoginUser().remove((LoginUser) user);
+        }
+
+        // save the users
+        saveUsers(users);
+
+        return users;
+    }
+
+    public synchronized Users removeUsers(final FindUsers finder) {
+        // load the users
+        final Users users = getUsers();
+
+        // combine the user lists
+        final List<NiFiUser> nifiUsers = new ArrayList<>();
+        nifiUsers.addAll(users.getUser());
+        nifiUsers.addAll(users.getLoginUser());
+
+        // find the desired user
+        final List<NiFiUser> usersToRemove = finder.findUsers(nifiUsers);
+        for (final NiFiUser user : usersToRemove) {
+            if (User.class.isAssignableFrom(user.getClass())) {
+                users.getUser().remove((User) user);
+            } else {
+                users.getLoginUser().remove((LoginUser) user);
+            }
+        }
+
+        // save the users
+        saveUsers(users);
+
+        return users;
+    }
+
+    private synchronized void saveUsers(final Users users) {
+        try {
+            final Marshaller marshaller = JAXB_CONTEXT.createMarshaller();
+            marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, 
Boolean.TRUE);
+
+            // save users to restore directory before primary directory
+            if (restoreFile != null) {
+                marshaller.marshal(users, restoreFile);
+            }
+
+            // save users to primary directory
+            marshaller.marshal(users, usersFile);
+        } catch (JAXBException e) {
+            throw new AuthorityAccessException(e.getMessage(), e);
+        }
+    }
+
+    public static interface HasUser {
+
+        /**
+         * Determines if a user exists. Returns whether this user exists and 
will never through an UnknownIdentityException.
+         *
+         * @param users the users
+         * @return whether the desired user exists
+         */
+        boolean hasUser(List<NiFiUser> users);
+    }
+
+    public static interface FindUser {
+
+        /**
+         * Finds the desired user. If the user cannot be found throws an 
UnknownIdentityException. Never returns null.
+         *
+         * @param users the users
+         * @return the desired user
+         * @throws UnknownIdentityException if the user cannot be found
+         */
+        NiFiUser findUser(List<NiFiUser> users) throws 
UnknownIdentityException;
+    }
+
+    public static interface FindUsers {
+
+        /**
+         * Finds the specified users.
+         *
+         * @param users the userss
+         * @return the desired users
+         * @throws UnknownIdentityException if the users cannot be found
+         */
+        List<NiFiUser> findUsers(List<NiFiUser> users) throws 
UnknownIdentityException;
+    }
+
+    public static interface CreateUser {
+
+        /**
+         * Creates the user to add.
+         *
+         * @return the users to add
+         */
+        NiFiUser createUser();
+    }
+
+    public static interface UpdateUser {
+
+        /**
+         * Updates the specified user.
+         *
+         * @param user the user
+         */
+        void updateUser(NiFiUser user);
+    }
+
+    public static interface UpdateUsers {
+
+        /**
+         * Updates the specified users.
+         *
+         * @param users the users to update
+         */
+        void updateUsers(List<NiFiUser> users);
+    }
+}

http://git-wip-us.apache.org/repos/asf/nifi/blob/a40e5a07/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-authorized-users/src/main/xsd/users.xsd
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-authorized-users/src/main/xsd/users.xsd
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-authorized-users/src/main/xsd/users.xsd
new file mode 100644
index 0000000..b06ebc8
--- /dev/null
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-authorized-users/src/main/xsd/users.xsd
@@ -0,0 +1,96 @@
+<?xml version="1.0"?>
+<!--
+  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.
+-->
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema";>
+    <!-- role -->
+    <xs:complexType name="Role">
+        <xs:attribute name="name">
+            <xs:simpleType>
+                <xs:restriction base="xs:string">
+                    <xs:enumeration value="ROLE_MONITOR"/>
+                    <xs:enumeration value="ROLE_PROVENANCE"/>
+                    <xs:enumeration value="ROLE_DFM"/>
+                    <xs:enumeration value="ROLE_ADMIN"/>
+                    <xs:enumeration value="ROLE_PROXY"/>
+                    <xs:enumeration value="ROLE_NIFI"/>
+                </xs:restriction>
+            </xs:simpleType>
+        </xs:attribute>
+    </xs:complexType>
+
+    <xs:complexType name="NiFiUser">
+        <xs:sequence>
+            <xs:element name="role" type="Role" minOccurs="0" 
maxOccurs="unbounded"/>
+        </xs:sequence>
+        <xs:attribute name="group">
+            <xs:simpleType>
+                <xs:restriction base="xs:string">
+                    <xs:minLength value="1"/>
+                    <xs:pattern value=".*[^\s].*"/>
+                </xs:restriction>
+            </xs:simpleType>
+        </xs:attribute>
+    </xs:complexType>
+
+    <!-- preauthenticated user -->
+    <xs:complexType name="User">
+        <xs:complexContent>
+            <xs:extension base="NiFiUser">
+                <xs:attribute name="dn">
+                    <xs:simpleType>
+                        <xs:restriction base="xs:string">
+                            <xs:minLength value="1"/>
+                            <xs:pattern value=".*[^\s].*"/>
+                        </xs:restriction>
+                    </xs:simpleType>
+                </xs:attribute>
+            </xs:extension>
+        </xs:complexContent>
+    </xs:complexType>
+    
+    <!-- login user -->
+    <xs:complexType name="LoginUser">
+        <xs:complexContent>
+            <xs:extension base="NiFiUser">
+                <xs:attribute name="username">
+                    <xs:simpleType>
+                        <xs:restriction base="xs:string">
+                            <xs:minLength value="1"/>
+                            <xs:pattern value=".*[^\s].*"/>
+                        </xs:restriction>
+                    </xs:simpleType>
+                </xs:attribute>
+                <xs:attribute name="password">
+                    <xs:simpleType>
+                        <xs:restriction base="xs:string">
+                            <xs:minLength value="1"/>
+                            <xs:pattern value=".*[^\s].*"/>
+                        </xs:restriction>
+                    </xs:simpleType>
+                </xs:attribute>
+            </xs:extension>
+        </xs:complexContent>
+    </xs:complexType>
+
+    <!-- users -->
+    <xs:element name="users">
+        <xs:complexType>
+            <xs:sequence>
+                <xs:element name="user" type="User" minOccurs="0" 
maxOccurs="unbounded"/>
+                <xs:element name="loginUser" type="LoginUser" minOccurs="0" 
maxOccurs="unbounded"/>
+            </xs:sequence>
+        </xs:complexType>
+    </xs:element>
+</xs:schema>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/nifi/blob/a40e5a07/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/IdentityEntity.java
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/IdentityEntity.java
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/IdentityEntity.java
new file mode 100644
index 0000000..02991c7
--- /dev/null
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/IdentityEntity.java
@@ -0,0 +1,52 @@
+/*
+ * 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.web.api.entity;
+
+import javax.xml.bind.annotation.XmlRootElement;
+
+/**
+ * A serialized representation of this class can be placed in the entity body 
of a response to the API. This particular entity holds the users identity.
+ */
+@XmlRootElement(name = "identityEntity")
+public class IdentityEntity extends Entity {
+
+    private String userId;
+    private String identity;
+
+    /**
+     * @return current user id
+     */
+    public String getUserId() {
+        return userId;
+    }
+
+    public void setUserId(String userId) {
+        this.userId = userId;
+    }
+
+    /**
+     * @return the user identity being serialized
+     */
+    public String getIdentity() {
+        return identity;
+    }
+
+    public void setIdentity(String identity) {
+        this.identity = identity;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/nifi/blob/a40e5a07/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-file-authorization-provider/pom.xml
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-file-authorization-provider/pom.xml
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-file-authorization-provider/pom.xml
index d014262..50fa105 100644
--- 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-file-authorization-provider/pom.xml
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-file-authorization-provider/pom.xml
@@ -21,44 +21,6 @@
         <version>0.3.1-SNAPSHOT</version>
     </parent>
     <artifactId>nifi-file-authorization-provider</artifactId>
-    <build>
-        <resources>
-            <resource>
-                <directory>src/main/resources</directory>
-            </resource>
-            <resource>
-                <directory>src/main/xsd</directory>
-            </resource>
-        </resources>
-        <plugins>
-            <plugin>
-                <groupId>org.codehaus.mojo</groupId>
-                <artifactId>jaxb2-maven-plugin</artifactId>
-                <executions>
-                    <execution>
-                        <id>xjc</id>
-                        <goals>
-                            <goal>xjc</goal>
-                        </goals>
-                        <configuration>
-                            
<packageName>org.apache.nifi.user.generated</packageName>
-                        </configuration>
-                    </execution>
-                </executions>
-                <configuration>
-                    
<generateDirectory>${project.build.directory}/generated-sources/jaxb</generateDirectory>
-                </configuration>
-            </plugin>
-            <plugin>
-                <groupId>org.apache.maven.plugins</groupId>
-                <artifactId>maven-checkstyle-plugin</artifactId>
-                <configuration>
-                    <excludes>**/user/generated/*.java</excludes>
-                </configuration>
-            </plugin>            
-
-        </plugins>
-    </build>
     <dependencies>
         <dependency>
             <groupId>org.apache.nifi</groupId>
@@ -66,7 +28,12 @@
         </dependency>
         <dependency>
             <groupId>org.apache.nifi</groupId>
+            <artifactId>nifi-authorized-users</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.nifi</groupId>
             <artifactId>nifi-utils</artifactId>
+            <scope>test</scope>
         </dependency>
         <dependency>
             <groupId>org.apache.nifi</groupId>

Reply via email to