You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nifi.apache.org by mc...@apache.org on 2016/04/07 22:23:37 UTC

[9/9] nifi git commit: Revert "NIFI-1551:"

Revert "NIFI-1551:"

This reverts commit c4d06f203d204d4a3128e1b997144edcd82e48a5. Accidently merged wrong branch.


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

Branch: refs/heads/master
Commit: 3f4ac3156cbf7573a2f8c3a042d9a57469518b57
Parents: c4d06f2
Author: Matt Gilman <ma...@gmail.com>
Authored: Thu Apr 7 16:22:35 2016 -0400
Committer: Matt Gilman <ma...@gmail.com>
Committed: Thu Apr 7 16:22:35 2016 -0400

----------------------------------------------------------------------
 .../authentication/LoginIdentityProvider.java   |   4 +-
 .../exception/ProviderCreationException.java    |  39 --
 .../exception/ProviderDestructionException.java |  39 --
 .../apache/nifi/authorization/Authority.java    |  93 +++
 .../nifi/authorization/AuthorityProvider.java   | 182 ++++++
 .../AuthorityProviderConfigurationContext.java  |  48 ++
 .../AuthorityProviderInitializationContext.java |  27 +
 .../authorization/AuthorityProviderLookup.java  |  25 +
 .../authorization/AuthorizationRequest.java     |   3 +-
 .../apache/nifi/authorization/Authorizer.java   |   3 +-
 .../authorization/DownloadAuthorization.java    |  83 +++
 .../annotation/AuthorityProviderContext.java    |  35 +
 .../exception/AuthorityAccessException.java     |  33 +
 .../IdentityAlreadyExistsException.java         |  32 +
 .../exception/ProviderCreationException.java    |  39 ++
 .../exception/ProviderDestructionException.java |  39 ++
 .../exception/UnknownIdentityException.java     |  32 +
 nifi-assembly/pom.xml                           |   5 +-
 .../org/apache/nifi/util/NiFiProperties.java    |  10 +-
 .../cassandra/AbstractCassandraProcessor.java   |   2 +-
 .../AbstractCassandraProcessorTest.java         |   2 +-
 .../nifi/admin/KeyDataSourceFactoryBean.java    | 147 -----
 .../nifi/admin/UserDataSourceFactoryBean.java   | 244 +++++++
 .../org/apache/nifi/admin/dao/AuthorityDAO.java |  59 ++
 .../org/apache/nifi/admin/dao/DAOFactory.java   |   4 +
 .../java/org/apache/nifi/admin/dao/UserDAO.java | 128 ++++
 .../nifi/admin/dao/impl/DAOFactoryImpl.java     |  12 +
 .../admin/dao/impl/StandardAuthorityDAO.java    | 172 +++++
 .../nifi/admin/dao/impl/StandardUserDAO.java    | 641 +++++++++++++++++++
 .../admin/service/AccountDisabledException.java |  40 ++
 .../admin/service/AccountPendingException.java  |  41 ++
 .../apache/nifi/admin/service/UserService.java  | 133 +++-
 .../service/action/AbstractUserAction.java      |  97 +++
 .../admin/service/action/AddActionsAction.java  |   3 +-
 .../service/action/AdministrationAction.java    |   4 +-
 .../service/action/AuthorizeDownloadAction.java |  54 ++
 .../service/action/AuthorizeUserAction.java     | 173 +++++
 .../admin/service/action/CreateUserAction.java  |  53 ++
 .../admin/service/action/DeleteKeysAction.java  |   3 +-
 .../admin/service/action/DeleteUserAction.java  |  73 +++
 .../admin/service/action/DisableUserAction.java |  81 +++
 .../service/action/DisableUserGroupAction.java  |  78 +++
 .../service/action/FindUserByDnAction.java      |  49 ++
 .../service/action/FindUserByIdAction.java      |  46 ++
 .../admin/service/action/GetActionAction.java   |   3 +-
 .../admin/service/action/GetActionsAction.java  |   6 +-
 .../admin/service/action/GetKeyByIdAction.java  |   4 +-
 .../service/action/GetKeyByIdentityAction.java  |   4 +-
 .../service/action/GetOrCreateKeyAction.java    |   4 +-
 .../admin/service/action/GetPreviousValues.java |   8 +-
 .../service/action/GetUserGroupAction.java      |  50 ++
 .../admin/service/action/GetUsersAction.java    |  39 ++
 .../service/action/HasPendingUserAccounts.java  |  34 +
 .../action/InvalidateUserAccountAction.java     |  58 ++
 .../InvalidateUserGroupAccountsAction.java      |  45 ++
 .../service/action/PurgeActionsAction.java      |   3 +-
 .../action/RequestUserAccountAction.java        |  67 ++
 .../service/action/SeedUserAccountsAction.java  | 164 +++++
 .../admin/service/action/UngroupUserAction.java |  69 ++
 .../service/action/UngroupUserGroupAction.java  |  57 ++
 .../admin/service/action/UpdateUserAction.java  | 124 ++++
 .../UpdateUserAuthoritiesCacheAction.java       |  73 +++
 .../service/action/UpdateUserCacheAction.java   |  47 ++
 .../service/action/UpdateUserGroupAction.java   | 171 +++++
 .../admin/service/impl/StandardUserService.java | 582 ++++++++++++++++-
 .../transaction/impl/StandardTransaction.java   |  16 +-
 .../impl/StandardTransactionBuilder.java        |   8 +-
 .../AuthorityProviderFactoryBean.java           | 491 ++++++++++++++
 .../authorization/AuthorizerFactoryBean.java    |  11 +-
 ...rdAuthorityProviderConfigurationContext.java |  51 ++
 ...dAuthorityProviderInitializationContext.java |  42 ++
 .../org/apache/nifi/user/AccountStatus.java     |  47 ++
 .../java/org/apache/nifi/user/NiFiUser.java     | 101 ++-
 .../resources/nifi-administration-context.xml   |  33 +-
 .../src/main/xsd/authority-providers.xsd        |  49 ++
 .../service/action/AuthorizeUserActionTest.java | 433 +++++++++++++
 .../service/action/CreateUserActionTest.java    | 144 +++++
 .../service/action/DisableUserActionTest.java   | 176 +++++
 .../action/InvalidateUserAccountActionTest.java | 126 ++++
 .../action/RequestUserAccountActionTest.java    | 127 ++++
 .../action/SeedUserAccountsActionTest.java      | 262 ++++++++
 .../action/SetUserAuthoritiesActionTest.java    | 223 +++++++
 .../web/api/dto/status/ControllerStatusDTO.java |  15 +
 .../.gitignore                                  |   1 +
 .../nifi-cluster-authorization-provider/pom.xml |  46 ++
 .../ClusterManagerAuthorizationProvider.java    | 225 +++++++
 .../NodeAuthorizationProvider.java              | 389 +++++++++++
 .../protocol/message/DoesDnExistMessage.java    |  55 ++
 .../protocol/message/GetAuthoritiesMessage.java |  57 ++
 .../message/GetGroupForUserMessage.java         |  54 ++
 .../protocol/message/ProtocolMessage.java       |  56 ++
 .../message/jaxb/JaxbProtocolUtils.java         |  41 ++
 .../protocol/message/jaxb/ObjectFactory.java    |  44 ++
 ....apache.nifi.authorization.AuthorityProvider |  16 +
 .../nifi-file-authorization-provider/pom.xml    |  85 +++
 .../FileAuthorizationProvider.java              | 496 ++++++++++++++
 ....apache.nifi.authorization.AuthorityProvider |  15 +
 .../src/main/xsd/users.xsd                      |  64 ++
 .../FileAuthorizationProviderTest.java          | 128 ++++
 .../org/apache/nifi/nar/ExtensionManager.java   |  19 +-
 .../nifi/nar/NarThreadContextClassLoader.java   |  20 +-
 .../main/resources/conf/authority-providers.xml |  43 ++
 .../main/resources/conf/authorized-users.xml    |   2 +-
 .../src/main/resources/conf/authorizers.xml     |  28 -
 .../src/main/resources/conf/nifi.properties     |   4 +-
 .../nifi/remote/StandardRootGroupPort.java      | 105 ++-
 .../org/apache/nifi/web/NiFiServiceFacade.java  |  81 +++
 .../web/NiFiWebApiSecurityConfiguration.java    |  60 +-
 .../nifi/web/StandardNiFiContentAccess.java     |  18 +-
 .../nifi/web/StandardNiFiServiceFacade.java     | 234 ++++++-
 .../StandardNiFiWebConfigurationContext.java    |   4 +-
 .../apache/nifi/web/StandardNiFiWebContext.java |   4 +-
 .../org/apache/nifi/web/api/AccessResource.java |  68 +-
 .../apache/nifi/web/api/ControllerResource.java |  35 +-
 .../apache/nifi/web/api/UserGroupResource.java  | 465 ++++++++++++++
 .../org/apache/nifi/web/api/UserResource.java   | 617 ++++++++++++++++++
 .../config/AccountNotFoundExceptionMapper.java  |  47 ++
 .../org/apache/nifi/web/api/dto/DtoFactory.java |  99 ++-
 .../nifi/web/controller/ControllerFacade.java   |  12 +-
 .../web/dao/impl/StandardConnectionDAO.java     |  12 +-
 .../src/main/resources/nifi-web-api-context.xml |  12 +
 .../accesscontrol/AccessTokenEndpointTest.java  |   2 -
 .../accesscontrol/AdminAccessControlTest.java   |   2 -
 .../accesscontrol/DfmAccessControlTest.java     |   1 -
 .../ReadOnlyAccessControlTest.java              |   2 -
 .../util/NiFiTestAuthorizationProvider.java     | 180 ++++++
 .../integration/util/NiFiTestAuthorizer.java    |  56 --
 .../util/NiFiTestLoginIdentityProvider.java     |   9 +-
 ....apache.nifi.authorization.AuthorityProvider |  15 +
 .../org.apache.nifi.authorization.Authorizer    |  15 -
 .../access-control/authority-providers.xml      |   2 +-
 .../web/security/NiFiAuthenticationFilter.java  | 105 ++-
 .../security/NiFiAuthenticationProvider.java    |  73 +++
 .../anonymous/NiFiAnonymousUserFilter.java      |  39 +-
 .../authorization/NiFiAuthorizationService.java | 171 +++++
 .../security/jwt/JwtAuthenticationFilter.java   |  34 +-
 .../security/jwt/JwtAuthenticationProvider.java |  56 --
 .../jwt/JwtAuthenticationRequestToken.java      |  58 --
 .../kerberos/KerberosServiceFactoryBean.java    |  74 +++
 .../security/node/NodeAuthorizedUserFilter.java |   4 +-
 .../security/otp/OtpAuthenticationFilter.java   |  41 +-
 .../security/otp/OtpAuthenticationProvider.java |  60 --
 .../otp/OtpAuthenticationRequestToken.java      |  64 --
 .../spring/KerberosServiceFactoryBean.java      |  76 ---
 .../LoginIdentityProviderFactoryBean.java       |  35 +-
 .../NewAccountAuthorizationRequestToken.java    |  40 ++
 .../token/NewAccountAuthorizationToken.java     |  46 ++
 .../security/token/NiFiAuthenticationToken.java |  50 --
 .../token/NiFiAuthorizationRequestToken.java    |  54 ++
 .../security/token/NiFiAuthorizationToken.java  |  50 ++
 .../web/security/user/NewAccountRequest.java    |  47 ++
 .../nifi/web/security/user/NiFiUserDetails.java |  17 +-
 .../nifi/web/security/user/NiFiUserUtils.java   |  21 +
 .../security/x509/X509AuthenticationFilter.java |  36 +-
 .../x509/X509AuthenticationProvider.java        |  78 ---
 .../x509/X509AuthenticationRequestToken.java    |  75 ---
 .../resources/nifi-web-security-context.xml     |  19 +-
 .../NiFiAuthorizationServiceTest.java           | 249 +++++++
 .../otp/OtpAuthenticationFilterTest.java        |  91 ++-
 .../otp/OtpAuthenticationProviderTest.java      | 102 ---
 .../nifi-framework/pom.xml                      |   2 +
 .../apache/nifi/kerberos/KerberosProvider.java  |   4 +-
 .../java/org/apache/nifi/ldap/LdapProvider.java |   4 +-
 163 files changed, 11725 insertions(+), 1272 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/nifi/blob/3f4ac315/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
index 145bdb4..54becb3 100644
--- a/nifi-api/src/main/java/org/apache/nifi/authentication/LoginIdentityProvider.java
+++ b/nifi-api/src/main/java/org/apache/nifi/authentication/LoginIdentityProvider.java
@@ -18,8 +18,8 @@ package org.apache.nifi.authentication;
 
 import org.apache.nifi.authentication.exception.IdentityAccessException;
 import org.apache.nifi.authentication.exception.InvalidLoginCredentialsException;
-import org.apache.nifi.authentication.exception.ProviderCreationException;
-import org.apache.nifi.authentication.exception.ProviderDestructionException;
+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.

http://git-wip-us.apache.org/repos/asf/nifi/blob/3f4ac315/nifi-api/src/main/java/org/apache/nifi/authentication/exception/ProviderCreationException.java
----------------------------------------------------------------------
diff --git a/nifi-api/src/main/java/org/apache/nifi/authentication/exception/ProviderCreationException.java b/nifi-api/src/main/java/org/apache/nifi/authentication/exception/ProviderCreationException.java
deleted file mode 100644
index b352787..0000000
--- a/nifi-api/src/main/java/org/apache/nifi/authentication/exception/ProviderCreationException.java
+++ /dev/null
@@ -1,39 +0,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.
- */
-package org.apache.nifi.authentication.exception;
-
-/**
- * Represents the exceptional case when an AuthorityProvider fails instantiated.
- *
- */
-public class ProviderCreationException extends RuntimeException {
-
-    public ProviderCreationException() {
-    }
-
-    public ProviderCreationException(String msg) {
-        super(msg);
-    }
-
-    public ProviderCreationException(Throwable cause) {
-        super(cause);
-    }
-
-    public ProviderCreationException(String msg, Throwable cause) {
-        super(msg, cause);
-    }
-}

http://git-wip-us.apache.org/repos/asf/nifi/blob/3f4ac315/nifi-api/src/main/java/org/apache/nifi/authentication/exception/ProviderDestructionException.java
----------------------------------------------------------------------
diff --git a/nifi-api/src/main/java/org/apache/nifi/authentication/exception/ProviderDestructionException.java b/nifi-api/src/main/java/org/apache/nifi/authentication/exception/ProviderDestructionException.java
deleted file mode 100644
index 1e12146..0000000
--- a/nifi-api/src/main/java/org/apache/nifi/authentication/exception/ProviderDestructionException.java
+++ /dev/null
@@ -1,39 +0,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.
- */
-package org.apache.nifi.authentication.exception;
-
-/**
- * Represents the exceptional case when an AuthorityProvider fails destruction.
- *
- */
-public class ProviderDestructionException extends RuntimeException {
-
-    public ProviderDestructionException() {
-    }
-
-    public ProviderDestructionException(String msg) {
-        super(msg);
-    }
-
-    public ProviderDestructionException(Throwable cause) {
-        super(cause);
-    }
-
-    public ProviderDestructionException(String msg, Throwable cause) {
-        super(msg, cause);
-    }
-}

http://git-wip-us.apache.org/repos/asf/nifi/blob/3f4ac315/nifi-api/src/main/java/org/apache/nifi/authorization/Authority.java
----------------------------------------------------------------------
diff --git a/nifi-api/src/main/java/org/apache/nifi/authorization/Authority.java b/nifi-api/src/main/java/org/apache/nifi/authorization/Authority.java
new file mode 100644
index 0000000..4502c11
--- /dev/null
+++ b/nifi-api/src/main/java/org/apache/nifi/authorization/Authority.java
@@ -0,0 +1,93 @@
+/*
+ * 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.authorization;
+
+import java.util.EnumSet;
+import java.util.HashSet;
+import java.util.LinkedHashSet;
+import java.util.Set;
+
+/**
+ * Authorities that can be assigned to NiFi users.
+ */
+public enum Authority {
+
+    ROLE_MONITOR,
+    ROLE_DFM,
+    ROLE_ADMIN,
+    ROLE_PROVENANCE,
+    ROLE_PROXY,
+    ROLE_NIFI;
+
+    /**
+     * @param rawAuthority string form of authority
+     * @return the matching role or null if the specified role does not match
+     * any roles
+     */
+    public static Authority valueOfAuthority(String rawAuthority) {
+        Authority desiredAuthority = null;
+
+        for (Authority authority : values()) {
+            if (authority.toString().equals(rawAuthority)) {
+                desiredAuthority = authority;
+                break;
+            }
+        }
+
+        return desiredAuthority;
+    }
+
+    /**
+     * @return the string value of each authority
+     */
+    public static Set<String> getRawAuthorities() {
+        Set<String> authorities = new LinkedHashSet<>();
+        for (Authority authority : values()) {
+            authorities.add(authority.toString());
+        }
+        return authorities;
+    }
+
+    public static Set<String> convertAuthorities(Set<Authority> authorities) {
+        if (authorities == null) {
+            throw new IllegalArgumentException("No authorities have been specified.");
+        }
+
+        // convert the set
+        Set<String> rawAuthorities = new HashSet<>(authorities.size());
+        for (Authority authority : authorities) {
+            rawAuthorities.add(authority.toString());
+        }
+        return rawAuthorities;
+    }
+
+    public static EnumSet<Authority> convertRawAuthorities(Set<String> rawAuthorities) {
+        if (rawAuthorities == null) {
+            throw new IllegalArgumentException("No authorities have been specified.");
+        }
+
+        // convert the set
+        EnumSet<Authority> authorities = EnumSet.noneOf(Authority.class);
+        for (String rawAuthority : rawAuthorities) {
+            Authority authority = Authority.valueOfAuthority(rawAuthority);
+            if (authority != null) {
+                authorities.add(authority);
+            }
+        }
+        return authorities;
+    }
+}

http://git-wip-us.apache.org/repos/asf/nifi/blob/3f4ac315/nifi-api/src/main/java/org/apache/nifi/authorization/AuthorityProvider.java
----------------------------------------------------------------------
diff --git a/nifi-api/src/main/java/org/apache/nifi/authorization/AuthorityProvider.java b/nifi-api/src/main/java/org/apache/nifi/authorization/AuthorityProvider.java
new file mode 100644
index 0000000..716216d
--- /dev/null
+++ b/nifi-api/src/main/java/org/apache/nifi/authorization/AuthorityProvider.java
@@ -0,0 +1,182 @@
+/*
+ * 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.authorization;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import org.apache.nifi.authorization.exception.AuthorityAccessException;
+import org.apache.nifi.authorization.exception.IdentityAlreadyExistsException;
+import org.apache.nifi.authorization.exception.ProviderCreationException;
+import org.apache.nifi.authorization.exception.ProviderDestructionException;
+import org.apache.nifi.authorization.exception.UnknownIdentityException;
+
+/**
+ * This class allows clients to retrieve the authorities for a given DN.
+ */
+public interface AuthorityProvider {
+
+    /**
+     * @param identity of the user. The identity may be a dn, an email, a username, or any string that identities the user.
+     * @return whether the user with the specified identity is known to this authority
+     * provider. It is not necessary for the user to have any authorities
+     */
+    boolean doesDnExist(String identity) throws AuthorityAccessException;
+
+    /**
+     * Get the authorities for the specified user. If the specified user exists
+     * but does not have any authorities, an empty set should be returned.
+     *
+     * @param identity of the user. The identity may be a dn, an email, a username, or any string that identities the user.
+     * @return the authorities for the specified user. If the specified user
+     * exists but does not have any authorities, an empty set should be returned
+     * @throws UnknownIdentityException if identity is not known
+     * @throws AuthorityAccessException if unable to access authorities
+     */
+    Set<Authority> getAuthorities(String identity) throws UnknownIdentityException, AuthorityAccessException;
+
+    /**
+     * Sets the specified authorities for the specified user.
+     *
+     * @param identity of the user. The identity may be a dn, an email, a username, or any string that identities the user.
+     * @param authorities the new authorities for the user
+     * @throws UnknownIdentityException if identity is not known
+     * @throws AuthorityAccessException if unable to access authorities
+     */
+    void setAuthorities(String identity, Set<Authority> authorities) throws UnknownIdentityException, AuthorityAccessException;
+
+    /**
+     * Gets the users for the specified authority.
+     *
+     * @param authority for which to determine membership of
+     * @return all users with the specified authority
+     * @throws AuthorityAccessException if unable to access authorities
+     */
+    Set<String> getUsers(Authority authority) throws AuthorityAccessException;
+
+    /**
+     * Revokes the specified user. Its up to the implementor to determine the
+     * semantics of revocation.
+     *
+     * @param identity of the user. The identity may be a dn, an email, a username, or any string that identities the user.
+     * @throws UnknownIdentityException if the user is not known
+     * @throws AuthorityAccessException if unable to access the authorities
+     */
+    void revokeUser(String identity) throws UnknownIdentityException, AuthorityAccessException;
+
+    /**
+     * Add the specified user.
+     *
+     * @param identity of the user. The identity may be a dn, an email, a username, or any string that identities the user.
+     * @param group Optional
+     * @throws UnknownIdentityException if the user is not known
+     * @throws AuthorityAccessException if unable to access the authorities
+     */
+    void addUser(String identity, String group) throws IdentityAlreadyExistsException, AuthorityAccessException;
+
+    /**
+     * Gets the group for the specified user. Return null if the user does not
+     * belong to a group.
+     *
+     * @param identity of the user. The identity may be a dn, an email, a username, or any string that identities the user.
+     * @return the group of the given user
+     * @throws UnknownIdentityException if the user is not known
+     * @throws AuthorityAccessException if unable to access the authorities
+     */
+    String getGroupForUser(String identity) throws UnknownIdentityException, AuthorityAccessException;
+
+    /**
+     * Revokes all users for a specified group. Its up to the implementor to
+     * determine the semantics of revocation.
+     *
+     * @param group to revoke the users of
+     * @throws UnknownIdentityException if the user is not known
+     * @throws AuthorityAccessException if unable to access the authorities
+     */
+    void revokeGroup(String group) throws UnknownIdentityException, AuthorityAccessException;
+
+    /**
+     * Adds the specified users to the specified group.
+     *
+     * @param identity of the user. The identity may be a dn, an email, a username, or any string that identities the user.
+     * @param group to add users to
+     * @throws UnknownIdentityException if the user is not known
+     * @throws AuthorityAccessException if unable to access the authorities
+     */
+    void setUsersGroup(Set<String> identity, String group) throws UnknownIdentityException, AuthorityAccessException;
+
+    /**
+     * Ungroups the specified user.
+     *
+     * @param identity of the user. The identity may be a dn, an email, a username, or any string that identities the user.
+     * @throws UnknownIdentityException if the user is not known
+     * @throws AuthorityAccessException if unable to access the authorities
+     */
+    void ungroupUser(String identity) throws UnknownIdentityException, AuthorityAccessException;
+
+    /**
+     * Ungroups the specified group. Since the semantics of revocation is up to
+     * the implementor, this method should do nothing if the specified group
+     * does not exist. If an admin revoked this group before calling ungroup, it
+     * may or may not exist.
+     *
+     * @param group to ungroup
+     * @throws AuthorityAccessException if unable to access the authorities
+     */
+    void ungroup(String group) throws AuthorityAccessException;
+
+    /**
+     * Determines whether the user in the specified dnChain should be able to
+     * download the content for the flowfile with the specified attributes.
+     *
+     * The first identity in the chain is the end user that the request was issued on
+     * behalf of. The subsequent identities in the chain represent entities proxying
+     * the user's request with the last being the proxy that sent the current
+     * request.
+     *
+     * @param proxyChain proxy chain of user identities that for the download request
+     * @param attributes of the flowfile being requested
+     * @return the authorization result
+     * @throws UnknownIdentityException if the user is not known
+     * @throws AuthorityAccessException if unable to access the authorities
+     */
+    DownloadAuthorization authorizeDownload(List<String> proxyChain, Map<String, String> attributes) throws UnknownIdentityException, AuthorityAccessException;
+
+    /**
+     * Called immediately after instance creation for implementers to perform
+     * additional setup
+     *
+     * @param initializationContext in which to initialize
+     */
+    void initialize(AuthorityProviderInitializationContext 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(AuthorityProviderConfigurationContext 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/3f4ac315/nifi-api/src/main/java/org/apache/nifi/authorization/AuthorityProviderConfigurationContext.java
----------------------------------------------------------------------
diff --git a/nifi-api/src/main/java/org/apache/nifi/authorization/AuthorityProviderConfigurationContext.java b/nifi-api/src/main/java/org/apache/nifi/authorization/AuthorityProviderConfigurationContext.java
new file mode 100644
index 0000000..c1ba5df
--- /dev/null
+++ b/nifi-api/src/main/java/org/apache/nifi/authorization/AuthorityProviderConfigurationContext.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.authorization;
+
+import java.util.Map;
+
+/**
+ *
+ */
+public interface AuthorityProviderConfigurationContext {
+
+    /**
+     * @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/3f4ac315/nifi-api/src/main/java/org/apache/nifi/authorization/AuthorityProviderInitializationContext.java
----------------------------------------------------------------------
diff --git a/nifi-api/src/main/java/org/apache/nifi/authorization/AuthorityProviderInitializationContext.java b/nifi-api/src/main/java/org/apache/nifi/authorization/AuthorityProviderInitializationContext.java
new file mode 100644
index 0000000..7b2f89f
--- /dev/null
+++ b/nifi-api/src/main/java/org/apache/nifi/authorization/AuthorityProviderInitializationContext.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.authorization;
+
+/**
+ *
+ */
+public interface AuthorityProviderInitializationContext {
+
+    public String getIdentifier();
+
+    public AuthorityProviderLookup getAuthorityProviderLookup();
+}

http://git-wip-us.apache.org/repos/asf/nifi/blob/3f4ac315/nifi-api/src/main/java/org/apache/nifi/authorization/AuthorityProviderLookup.java
----------------------------------------------------------------------
diff --git a/nifi-api/src/main/java/org/apache/nifi/authorization/AuthorityProviderLookup.java b/nifi-api/src/main/java/org/apache/nifi/authorization/AuthorityProviderLookup.java
new file mode 100644
index 0000000..dc30967
--- /dev/null
+++ b/nifi-api/src/main/java/org/apache/nifi/authorization/AuthorityProviderLookup.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.authorization;
+
+/**
+ *
+ */
+public interface AuthorityProviderLookup {
+
+    AuthorityProvider getAuthorityProvider(String identifier);
+}

http://git-wip-us.apache.org/repos/asf/nifi/blob/3f4ac315/nifi-api/src/main/java/org/apache/nifi/authorization/AuthorizationRequest.java
----------------------------------------------------------------------
diff --git a/nifi-api/src/main/java/org/apache/nifi/authorization/AuthorizationRequest.java b/nifi-api/src/main/java/org/apache/nifi/authorization/AuthorizationRequest.java
index 1538be0..38c9e26 100644
--- a/nifi-api/src/main/java/org/apache/nifi/authorization/AuthorizationRequest.java
+++ b/nifi-api/src/main/java/org/apache/nifi/authorization/AuthorizationRequest.java
@@ -34,6 +34,7 @@ public class AuthorizationRequest {
 
     private AuthorizationRequest(final Builder builder) {
         Objects.requireNonNull(builder.resource, "The resource is required when creating an authorization request");
+        Objects.requireNonNull(builder.identity, "The identity of the user is required when creating an authorization request");
         Objects.requireNonNull(builder.action, "The action is required when creating an authorization request");
 
         this.resource = builder.resource;
@@ -53,7 +54,7 @@ public class AuthorizationRequest {
     }
 
     /**
-     * The identity accessing the Resource. May be null if the user could not authenticate.
+     * The identity accessing the Resource. Not null.
      *
      * @return The identity
      */

http://git-wip-us.apache.org/repos/asf/nifi/blob/3f4ac315/nifi-api/src/main/java/org/apache/nifi/authorization/Authorizer.java
----------------------------------------------------------------------
diff --git a/nifi-api/src/main/java/org/apache/nifi/authorization/Authorizer.java b/nifi-api/src/main/java/org/apache/nifi/authorization/Authorizer.java
index 5aec6f0..01a76e4 100644
--- a/nifi-api/src/main/java/org/apache/nifi/authorization/Authorizer.java
+++ b/nifi-api/src/main/java/org/apache/nifi/authorization/Authorizer.java
@@ -16,6 +16,7 @@
  */
 package org.apache.nifi.authorization;
 
+import org.apache.nifi.authorization.exception.AuthorityAccessException;
 import org.apache.nifi.authorization.exception.AuthorizationAccessException;
 import org.apache.nifi.authorization.exception.AuthorizerCreationException;
 import org.apache.nifi.authorization.exception.AuthorizerDestructionException;
@@ -30,7 +31,7 @@ public interface Authorizer {
      *
      * @param   request The authorization request
      * @return  the authorization result
-     * @throws  AuthorizationAccessException if unable to access the authorities
+     * @throws  AuthorityAccessException if unable to access the authorities
      */
     AuthorizationResult authorize(AuthorizationRequest request) throws AuthorizationAccessException;
 

http://git-wip-us.apache.org/repos/asf/nifi/blob/3f4ac315/nifi-api/src/main/java/org/apache/nifi/authorization/DownloadAuthorization.java
----------------------------------------------------------------------
diff --git a/nifi-api/src/main/java/org/apache/nifi/authorization/DownloadAuthorization.java b/nifi-api/src/main/java/org/apache/nifi/authorization/DownloadAuthorization.java
new file mode 100644
index 0000000..416f3cf
--- /dev/null
+++ b/nifi-api/src/main/java/org/apache/nifi/authorization/DownloadAuthorization.java
@@ -0,0 +1,83 @@
+/*
+ * 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.authorization;
+
+/**
+ * Represents a decision whether authorization is granted to download content.
+ */
+public class DownloadAuthorization {
+
+    private static enum Result {
+
+        Approved,
+        Denied;
+    }
+
+    private static final DownloadAuthorization APPROVED = new DownloadAuthorization(Result.Approved, null);
+
+    private final Result result;
+    private final String explanation;
+
+    /**
+     * Creates a new DownloadAuthorization with the specified result and
+     * explanation.
+     *
+     * @param result of the authorization
+     * @param explanation for the authorization attempt
+     */
+    private DownloadAuthorization(Result result, String explanation) {
+        if (Result.Denied.equals(result) && explanation == null) {
+            throw new IllegalArgumentException("An explanation is required when the download request is denied.");
+        }
+
+        this.result = result;
+        this.explanation = explanation;
+    }
+
+    /**
+     * @return Whether or not the download request is approved
+     */
+    public boolean isApproved() {
+        return Result.Approved.equals(result);
+    }
+
+    /**
+     * @return If the download request is denied, the reason why. Null otherwise
+     */
+    public String getExplanation() {
+        return explanation;
+    }
+
+    /**
+     * @return a new approved DownloadAuthorization
+     */
+    public static DownloadAuthorization approved() {
+        return APPROVED;
+    }
+
+    /**
+     * Creates a new denied DownloadAuthorization with the specified
+     * explanation.
+     *
+     * @param explanation for why it was denied
+     * @return a new denied DownloadAuthorization with the specified explanation
+     * @throws IllegalArgumentException if explanation is null
+     */
+    public static DownloadAuthorization denied(String explanation) {
+        return new DownloadAuthorization(Result.Denied, explanation);
+    }
+}

http://git-wip-us.apache.org/repos/asf/nifi/blob/3f4ac315/nifi-api/src/main/java/org/apache/nifi/authorization/annotation/AuthorityProviderContext.java
----------------------------------------------------------------------
diff --git a/nifi-api/src/main/java/org/apache/nifi/authorization/annotation/AuthorityProviderContext.java b/nifi-api/src/main/java/org/apache/nifi/authorization/annotation/AuthorityProviderContext.java
new file mode 100644
index 0000000..5ac2af7
--- /dev/null
+++ b/nifi-api/src/main/java/org/apache/nifi/authorization/annotation/AuthorityProviderContext.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.authorization.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 AuthorityProviderContext {
+}

http://git-wip-us.apache.org/repos/asf/nifi/blob/3f4ac315/nifi-api/src/main/java/org/apache/nifi/authorization/exception/AuthorityAccessException.java
----------------------------------------------------------------------
diff --git a/nifi-api/src/main/java/org/apache/nifi/authorization/exception/AuthorityAccessException.java b/nifi-api/src/main/java/org/apache/nifi/authorization/exception/AuthorityAccessException.java
new file mode 100644
index 0000000..be64767
--- /dev/null
+++ b/nifi-api/src/main/java/org/apache/nifi/authorization/exception/AuthorityAccessException.java
@@ -0,0 +1,33 @@
+/*
+ * 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.authorization.exception;
+
+/**
+ * Represents the case when the DN could not be confirmed because it was unable
+ * to access the data store.
+ */
+public class AuthorityAccessException extends RuntimeException {
+
+    public AuthorityAccessException(String message, Throwable cause) {
+        super(message, cause);
+    }
+
+    public AuthorityAccessException(String message) {
+        super(message);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/nifi/blob/3f4ac315/nifi-api/src/main/java/org/apache/nifi/authorization/exception/IdentityAlreadyExistsException.java
----------------------------------------------------------------------
diff --git a/nifi-api/src/main/java/org/apache/nifi/authorization/exception/IdentityAlreadyExistsException.java b/nifi-api/src/main/java/org/apache/nifi/authorization/exception/IdentityAlreadyExistsException.java
new file mode 100644
index 0000000..ba80b6e
--- /dev/null
+++ b/nifi-api/src/main/java/org/apache/nifi/authorization/exception/IdentityAlreadyExistsException.java
@@ -0,0 +1,32 @@
+/*
+ * 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.authorization.exception;
+
+/**
+ * Represents the case when the user identity already exists.
+ */
+public class IdentityAlreadyExistsException extends RuntimeException {
+
+    public IdentityAlreadyExistsException(String message, Throwable cause) {
+        super(message, cause);
+    }
+
+    public IdentityAlreadyExistsException(String message) {
+        super(message);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/nifi/blob/3f4ac315/nifi-api/src/main/java/org/apache/nifi/authorization/exception/ProviderCreationException.java
----------------------------------------------------------------------
diff --git a/nifi-api/src/main/java/org/apache/nifi/authorization/exception/ProviderCreationException.java b/nifi-api/src/main/java/org/apache/nifi/authorization/exception/ProviderCreationException.java
new file mode 100644
index 0000000..24ac793
--- /dev/null
+++ b/nifi-api/src/main/java/org/apache/nifi/authorization/exception/ProviderCreationException.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.authorization.exception;
+
+/**
+ * Represents the exceptional case when an AuthorityProvider fails instantiated.
+ *
+ */
+public class ProviderCreationException extends RuntimeException {
+
+    public ProviderCreationException() {
+    }
+
+    public ProviderCreationException(String msg) {
+        super(msg);
+    }
+
+    public ProviderCreationException(Throwable cause) {
+        super(cause);
+    }
+
+    public ProviderCreationException(String msg, Throwable cause) {
+        super(msg, cause);
+    }
+}

http://git-wip-us.apache.org/repos/asf/nifi/blob/3f4ac315/nifi-api/src/main/java/org/apache/nifi/authorization/exception/ProviderDestructionException.java
----------------------------------------------------------------------
diff --git a/nifi-api/src/main/java/org/apache/nifi/authorization/exception/ProviderDestructionException.java b/nifi-api/src/main/java/org/apache/nifi/authorization/exception/ProviderDestructionException.java
new file mode 100644
index 0000000..985d3fb
--- /dev/null
+++ b/nifi-api/src/main/java/org/apache/nifi/authorization/exception/ProviderDestructionException.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.authorization.exception;
+
+/**
+ * Represents the exceptional case when an AuthorityProvider fails destruction.
+ *
+ */
+public class ProviderDestructionException extends RuntimeException {
+
+    public ProviderDestructionException() {
+    }
+
+    public ProviderDestructionException(String msg) {
+        super(msg);
+    }
+
+    public ProviderDestructionException(Throwable cause) {
+        super(cause);
+    }
+
+    public ProviderDestructionException(String msg, Throwable cause) {
+        super(msg, cause);
+    }
+}

http://git-wip-us.apache.org/repos/asf/nifi/blob/3f4ac315/nifi-api/src/main/java/org/apache/nifi/authorization/exception/UnknownIdentityException.java
----------------------------------------------------------------------
diff --git a/nifi-api/src/main/java/org/apache/nifi/authorization/exception/UnknownIdentityException.java b/nifi-api/src/main/java/org/apache/nifi/authorization/exception/UnknownIdentityException.java
new file mode 100644
index 0000000..2ada1c7
--- /dev/null
+++ b/nifi-api/src/main/java/org/apache/nifi/authorization/exception/UnknownIdentityException.java
@@ -0,0 +1,32 @@
+/*
+ * 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.authorization.exception;
+
+/**
+ * Represents the case when an identity cannot be confirmed.
+ */
+public class UnknownIdentityException extends RuntimeException {
+
+    public UnknownIdentityException(String message, Throwable cause) {
+        super(message, cause);
+    }
+
+    public UnknownIdentityException(String message) {
+        super(message);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/nifi/blob/3f4ac315/nifi-assembly/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-assembly/pom.xml b/nifi-assembly/pom.xml
index 2d26494..09a8d50 100644
--- a/nifi-assembly/pom.xml
+++ b/nifi-assembly/pom.xml
@@ -325,7 +325,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.authorizer.configuration.file>./conf/authorizers.xml</nifi.authorizer.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>
 
@@ -413,8 +413,9 @@ language governing permissions and limitations under the License. -->
         <nifi.security.truststoreType />
         <nifi.security.truststorePasswd />
         <nifi.security.needClientAuth />
+        <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.authorizer>file-provider</nifi.security.user.authorizer>
+        <nifi.security.user.authority.provider>file-provider</nifi.security.user.authority.provider>
         <nifi.security.user.login.identity.provider />
         <nifi.security.x509.principal.extractor />
         <nifi.security.support.new.account.requests />

http://git-wip-us.apache.org/repos/asf/nifi/blob/3f4ac315/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 224c3f6..517b19a 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
@@ -48,7 +48,7 @@ public class NiFiProperties extends Properties {
     public static final String PROPERTIES_FILE_PATH = "nifi.properties.file.path";
     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 AUTHORIZER_CONFIGURATION_FILE = "nifi.authorizer.configuration.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";
@@ -131,7 +131,7 @@ public class NiFiProperties extends Properties {
     public static final String SECURITY_TRUSTSTORE_TYPE = "nifi.security.truststoreType";
     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_AUTHORIZER = "nifi.security.user.authorizer";
+    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";
@@ -504,10 +504,10 @@ public class NiFiProperties extends Properties {
     }
 
     /**
-     * @return the user authorizers file
+     * @return the user authorities file
      */
-    public File getAuthorizerConfiguraitonFile() {
-        final String value = getProperty(AUTHORIZER_CONFIGURATION_FILE);
+    public File getAuthorityProviderConfiguraitonFile() {
+        final String value = getProperty(AUTHORITY_PROVIDER_CONFIGURATION_FILE);
         if (StringUtils.isBlank(value)) {
             return new File(DEFAULT_AUTHORITY_PROVIDER_CONFIGURATION_FILE);
         } else {

http://git-wip-us.apache.org/repos/asf/nifi/blob/3f4ac315/nifi-nar-bundles/nifi-cassandra-bundle/nifi-cassandra-processors/src/main/java/org/apache/nifi/processors/cassandra/AbstractCassandraProcessor.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-cassandra-bundle/nifi-cassandra-processors/src/main/java/org/apache/nifi/processors/cassandra/AbstractCassandraProcessor.java b/nifi-nar-bundles/nifi-cassandra-bundle/nifi-cassandra-processors/src/main/java/org/apache/nifi/processors/cassandra/AbstractCassandraProcessor.java
index 478ffaf..672a3ee 100644
--- a/nifi-nar-bundles/nifi-cassandra-bundle/nifi-cassandra-processors/src/main/java/org/apache/nifi/processors/cassandra/AbstractCassandraProcessor.java
+++ b/nifi-nar-bundles/nifi-cassandra-bundle/nifi-cassandra-processors/src/main/java/org/apache/nifi/processors/cassandra/AbstractCassandraProcessor.java
@@ -26,7 +26,7 @@ import com.datastax.driver.core.Session;
 import org.apache.avro.Schema;
 import org.apache.avro.SchemaBuilder;
 import org.apache.commons.lang3.StringUtils;
-import org.apache.nifi.authentication.exception.ProviderCreationException;
+import org.apache.nifi.authorization.exception.ProviderCreationException;
 import org.apache.nifi.components.PropertyDescriptor;
 import org.apache.nifi.components.PropertyValue;
 import org.apache.nifi.components.ValidationContext;

http://git-wip-us.apache.org/repos/asf/nifi/blob/3f4ac315/nifi-nar-bundles/nifi-cassandra-bundle/nifi-cassandra-processors/src/test/java/org/apache/nifi/processors/cassandra/AbstractCassandraProcessorTest.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-cassandra-bundle/nifi-cassandra-processors/src/test/java/org/apache/nifi/processors/cassandra/AbstractCassandraProcessorTest.java b/nifi-nar-bundles/nifi-cassandra-bundle/nifi-cassandra-processors/src/test/java/org/apache/nifi/processors/cassandra/AbstractCassandraProcessorTest.java
index 19e2320..1f62997 100644
--- a/nifi-nar-bundles/nifi-cassandra-bundle/nifi-cassandra-processors/src/test/java/org/apache/nifi/processors/cassandra/AbstractCassandraProcessorTest.java
+++ b/nifi-nar-bundles/nifi-cassandra-bundle/nifi-cassandra-processors/src/test/java/org/apache/nifi/processors/cassandra/AbstractCassandraProcessorTest.java
@@ -22,7 +22,7 @@ import com.datastax.driver.core.DataType;
 import com.datastax.driver.core.Metadata;
 import com.datastax.driver.core.Row;
 import com.google.common.collect.Sets;
-import org.apache.nifi.authentication.exception.ProviderCreationException;
+import org.apache.nifi.authorization.exception.ProviderCreationException;
 import org.apache.nifi.components.PropertyDescriptor;
 import org.apache.nifi.processor.ProcessContext;
 import org.apache.nifi.processor.ProcessSession;

http://git-wip-us.apache.org/repos/asf/nifi/blob/3f4ac315/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/java/org/apache/nifi/admin/KeyDataSourceFactoryBean.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/java/org/apache/nifi/admin/KeyDataSourceFactoryBean.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/java/org/apache/nifi/admin/KeyDataSourceFactoryBean.java
deleted file mode 100644
index 8347953..0000000
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/java/org/apache/nifi/admin/KeyDataSourceFactoryBean.java
+++ /dev/null
@@ -1,147 +0,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.
- */
-package org.apache.nifi.admin;
-
-import org.apache.commons.lang3.StringUtils;
-import org.apache.nifi.util.NiFiProperties;
-import org.h2.jdbcx.JdbcConnectionPool;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.FactoryBean;
-
-import java.io.File;
-import java.sql.Connection;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.sql.Statement;
-
-public class KeyDataSourceFactoryBean implements FactoryBean {
-
-    private static final Logger logger = LoggerFactory.getLogger(KeyDataSourceFactoryBean.class);
-    private static final String NF_USERNAME_PASSWORD = "nf";
-    private static final int MAX_CONNECTIONS = 5;
-
-    // database file name
-    private static final String USER_KEYS_DATABASE_FILE_NAME = "nifi-user-keys";
-
-    // ----------
-    // keys table
-    // ----------
-
-    private static final String CREATE_KEY_TABLE = "CREATE TABLE KEY ("
-            + "ID INT NOT NULL PRIMARY KEY AUTO_INCREMENT, "
-            + "IDENTITY VARCHAR2(4096) NOT NULL UNIQUE, "
-            + "KEY VARCHAR2(100) NOT NULL"
-            + ")";
-
-    private JdbcConnectionPool connectionPool;
-
-    private NiFiProperties properties;
-
-    @Override
-    public Object getObject() throws Exception {
-        if (connectionPool == null) {
-
-            // locate the repository directory
-            String repositoryDirectoryPath = properties.getProperty(NiFiProperties.REPOSITORY_DATABASE_DIRECTORY);
-
-            // ensure the repository directory is specified
-            if (repositoryDirectoryPath == null) {
-                throw new NullPointerException("Database directory must be specified.");
-            }
-
-            // create a handle to the repository directory
-            File repositoryDirectory = new File(repositoryDirectoryPath);
-
-            // create a handle to the database directory and file
-            File databaseFile = new File(repositoryDirectory, USER_KEYS_DATABASE_FILE_NAME);
-            String databaseUrl = getDatabaseUrl(databaseFile);
-
-            // create the pool
-            connectionPool = JdbcConnectionPool.create(databaseUrl, NF_USERNAME_PASSWORD, NF_USERNAME_PASSWORD);
-            connectionPool.setMaxConnections(MAX_CONNECTIONS);
-
-            Connection connection = null;
-            ResultSet rs = null;
-            Statement statement = null;
-            try {
-                // get a connection
-                connection = connectionPool.getConnection();
-                connection.setAutoCommit(false);
-
-                // create a statement for creating/updating the database
-                statement = connection.createStatement();
-
-                // determine if the key table need to be created
-                rs = connection.getMetaData().getTables(null, null, "KEY", null);
-                if (!rs.next()) {
-                    statement.execute(CREATE_KEY_TABLE);
-                }
-
-                // commit any changes
-                connection.commit();
-            } catch (SQLException sqle) {
-                RepositoryUtils.rollback(connection, logger);
-                throw sqle;
-            } finally {
-                RepositoryUtils.closeQuietly(rs);
-                RepositoryUtils.closeQuietly(statement);
-                RepositoryUtils.closeQuietly(connection);
-            }
-        }
-
-        return connectionPool;
-    }
-
-    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);
-        if (StringUtils.isNotBlank(databaseUrlAppend)) {
-            databaseUrl += databaseUrlAppend;
-        }
-        return databaseUrl;
-    }
-
-    @Override
-    public Class getObjectType() {
-        return JdbcConnectionPool.class;
-    }
-
-    @Override
-    public boolean isSingleton() {
-        return true;
-    }
-
-    public void setProperties(NiFiProperties properties) {
-        this.properties = properties;
-    }
-
-    public void shutdown() {
-        // shutdown the connection pool
-        if (connectionPool != null) {
-            try {
-                connectionPool.dispose();
-            } catch (Exception e) {
-                logger.warn("Unable to dispose of connection pool: " + e.getMessage());
-                if (logger.isDebugEnabled()) {
-                    logger.warn(StringUtils.EMPTY, e);
-                }
-            }
-        }
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/nifi/blob/3f4ac315/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
new file mode 100644
index 0000000..d45719d
--- /dev/null
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/java/org/apache/nifi/admin/UserDataSourceFactoryBean.java
@@ -0,0 +1,244 @@
+/*
+ * 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.admin;
+
+import java.io.File;
+import java.sql.Connection;
+import java.sql.ResultSet;
+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;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.FactoryBean;
+
+public class UserDataSourceFactoryBean implements FactoryBean {
+
+    private static final Logger logger = LoggerFactory.getLogger(UserDataSourceFactoryBean.class);
+    private static final String NF_USERNAME_PASSWORD = "nf";
+    private static final int MAX_CONNECTIONS = 5;
+
+    // database file name
+    private static final String AUDIT_DATABASE_FILE_NAME = "nifi-users";
+
+    private static final String CREATE_USER_TABLE = "CREATE TABLE USER ("
+            + "ID VARCHAR2(100) NOT NULL PRIMARY KEY, "
+            + "IDENTITY VARCHAR2(4096) NOT NULL UNIQUE, "
+            + "USER_NAME VARCHAR2(4096) NOT NULL, "
+            + "USER_GROUP VARCHAR2(100), "
+            + "CREATION TIMESTAMP NOT NULL, "
+            + "LAST_ACCESSED TIMESTAMP, "
+            + "LAST_VERIFIED TIMESTAMP, "
+            + "JUSTIFICATION VARCHAR2(500) NOT NULL, "
+            + "STATUS VARCHAR2(10) NOT NULL"
+            + ")";
+
+    private static final String CREATE_AUTHORITY_TABLE = "CREATE TABLE AUTHORITY ("
+            + "ID INT NOT NULL PRIMARY KEY AUTO_INCREMENT, "
+            + "USER_ID VARCHAR2(100) NOT NULL, "
+            + "ROLE VARCHAR2(50) NOT NULL, "
+            + "FOREIGN KEY (USER_ID) REFERENCES USER (ID), "
+            + "CONSTRAINT USER_ROLE_UNIQUE_CONSTRAINT UNIQUE (USER_ID, ROLE)"
+            + ")";
+
+    private static final String INSERT_ANONYMOUS_USER = "INSERT INTO USER ("
+            + "ID, IDENTITY, USER_NAME, CREATION, LAST_VERIFIED, JUSTIFICATION, STATUS"
+            + ") VALUES ("
+            + "'" + UUID.randomUUID().toString() + "', "
+            + "'" + NiFiUser.ANONYMOUS_USER_IDENTITY + "', "
+            + "'" + NiFiUser.ANONYMOUS_USER_IDENTITY + "', "
+            + "NOW(), "
+            + "NOW(), "
+            + "'Anonymous user needs no justification', "
+            + "'ACTIVE'"
+            + ")";
+
+    private static final String INSERT_ANONYMOUS_AUTHORITY = "INSERT INTO AUTHORITY ("
+            + "USER_ID, ROLE"
+            + ") VALUES ("
+            + "(SELECT ID FROM USER WHERE IDENTITY = '" + NiFiUser.ANONYMOUS_USER_IDENTITY + "'), "
+            + "'%s'"
+            + ")";
+
+    private static final String DELETE_ANONYMOUS_AUTHORITIES = "DELETE FROM AUTHORITY "
+            + "WHERE USER_ID = (SELECT ID FROM USER WHERE IDENTITY = '" + NiFiUser.ANONYMOUS_USER_IDENTITY + "')";
+
+    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)";
+
+    // ----------
+    // keys table
+    // ----------
+    private static final String CREATE_KEY_TABLE = "CREATE TABLE KEY ("
+            + "ID INT NOT NULL PRIMARY KEY AUTO_INCREMENT, "
+            + "IDENTITY VARCHAR2(4096) NOT NULL UNIQUE, "
+            + "KEY VARCHAR2(100) NOT NULL"
+            + ")";
+
+    private JdbcConnectionPool connectionPool;
+
+    private NiFiProperties properties;
+
+    @Override
+    public Object getObject() throws Exception {
+        if (connectionPool == null) {
+
+            // locate the repository directory
+            String repositoryDirectoryPath = properties.getProperty(NiFiProperties.REPOSITORY_DATABASE_DIRECTORY);
+
+            // ensure the repository directory is specified
+            if (repositoryDirectoryPath == null) {
+                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(String.format("Invalid authorities specified for anonymous access: [%s]. Valid values are: [%s].",
+                        StringUtils.join(rawAnonymousAuthorities, ", "), StringUtils.join(Authority.values(), ", ")));
+            }
+
+            // create a handle to the repository directory
+            File repositoryDirectory = new File(repositoryDirectoryPath);
+
+            // create a handle to the database directory and file
+            File databaseFile = new File(repositoryDirectory, AUDIT_DATABASE_FILE_NAME);
+            String databaseUrl = getDatabaseUrl(databaseFile);
+
+            // create the pool
+            connectionPool = JdbcConnectionPool.create(databaseUrl, NF_USERNAME_PASSWORD, NF_USERNAME_PASSWORD);
+            connectionPool.setMaxConnections(MAX_CONNECTIONS);
+
+            Connection connection = null;
+            ResultSet rs = null;
+            Statement statement = null;
+            try {
+                // get a connection
+                connection = connectionPool.getConnection();
+                connection.setAutoCommit(false);
+
+                // create a statement for creating/updating the database
+                statement = connection.createStatement();
+
+                // determine if the tables need to be created
+                rs = connection.getMetaData().getTables(null, null, "USER", null);
+                if (!rs.next()) {
+                    logger.info("Database not built for repository: " + databaseUrl + ".  Building now...");
+
+                    // create the tables
+                    statement.execute(CREATE_USER_TABLE);
+                    statement.execute(CREATE_AUTHORITY_TABLE);
+
+                    // seed the anonymous user
+                    statement.execute(INSERT_ANONYMOUS_USER);
+                } else {
+                    logger.info("Existing database found and connected to at: " + databaseUrl);
+                    RepositoryUtils.closeQuietly(rs);
+
+                    // if the DN column exists, transform the table
+                    rs = connection.getMetaData().getColumns(null, null, "USER", "DN");
+                    if (rs.next()) {
+                        statement.execute(RENAME_DN_COLUMN);
+                        statement.execute(RESIZE_IDENTITY_COLUMN);
+                        statement.execute(RESIZE_USER_NAME_COLUMN);
+                    }
+
+                    // 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()));
+                }
+
+                RepositoryUtils.closeQuietly(rs);
+
+                // determine if the key table need to be created
+                rs = connection.getMetaData().getTables(null, null, "KEY", null);
+                if (!rs.next()) {
+                    statement.execute(CREATE_KEY_TABLE);
+                }
+
+                // commit any changes
+                connection.commit();
+            } catch (SQLException sqle) {
+                RepositoryUtils.rollback(connection, logger);
+                throw sqle;
+            } finally {
+                RepositoryUtils.closeQuietly(rs);
+                RepositoryUtils.closeQuietly(statement);
+                RepositoryUtils.closeQuietly(connection);
+            }
+        }
+
+        return connectionPool;
+    }
+
+    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);
+        if (StringUtils.isNotBlank(databaseUrlAppend)) {
+            databaseUrl += databaseUrlAppend;
+        }
+        return databaseUrl;
+    }
+
+    @Override
+    public Class getObjectType() {
+        return JdbcConnectionPool.class;
+    }
+
+    @Override
+    public boolean isSingleton() {
+        return true;
+    }
+
+    public void setProperties(NiFiProperties properties) {
+        this.properties = properties;
+    }
+
+    public void shutdown() {
+
+        // shutdown the connection pool
+        if (connectionPool != null) {
+            try {
+                connectionPool.dispose();
+            } catch (Exception e) {
+                logger.warn("Unable to dispose of connection pool: " + e.getMessage());
+                if (logger.isDebugEnabled()) {
+                    logger.warn(StringUtils.EMPTY, e);
+                }
+            }
+        }
+
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/nifi/blob/3f4ac315/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/java/org/apache/nifi/admin/dao/AuthorityDAO.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/java/org/apache/nifi/admin/dao/AuthorityDAO.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/java/org/apache/nifi/admin/dao/AuthorityDAO.java
new file mode 100644
index 0000000..b80b78e
--- /dev/null
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/java/org/apache/nifi/admin/dao/AuthorityDAO.java
@@ -0,0 +1,59 @@
+/*
+ * 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.admin.dao;
+
+import java.util.Set;
+import org.apache.nifi.authorization.Authority;
+
+/**
+ * Authority data access.
+ */
+public interface AuthorityDAO {
+
+    /**
+     * Finds all Authority for the specified user.
+     *
+     * @param userId identifier of user
+     * @return authorities
+     */
+    Set<Authority> findAuthoritiesByUserId(String userId) throws DataAccessException;
+
+    /**
+     * Creates new Authorities for the specified user in addition to authorities
+     * they already have.
+     *
+     * @param authorities to add to the given user
+     * @param userId identifier of user
+     */
+    void createAuthorities(Set<Authority> authorities, String userId) throws DataAccessException;
+
+    /**
+     * Removes all Authorities for the specified user.
+     *
+     * @param userId user identifier
+     * @throws DataAccessException if unable to access authorities
+     */
+    void deleteAuthorities(String userId) throws DataAccessException;
+
+    /**
+     * Removes the specified Authority.
+     *
+     * @param authorities to remove
+     * @param userId user id
+     */
+    void deleteAuthorities(Set<Authority> authorities, String userId) throws DataAccessException;
+}

http://git-wip-us.apache.org/repos/asf/nifi/blob/3f4ac315/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/java/org/apache/nifi/admin/dao/DAOFactory.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/java/org/apache/nifi/admin/dao/DAOFactory.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/java/org/apache/nifi/admin/dao/DAOFactory.java
index 3fcc6d8..eb7e3ce 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/java/org/apache/nifi/admin/dao/DAOFactory.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/java/org/apache/nifi/admin/dao/DAOFactory.java
@@ -21,7 +21,11 @@ package org.apache.nifi.admin.dao;
  */
 public interface DAOFactory {
 
+    UserDAO getUserDAO();
+
     ActionDAO getActionDAO();
 
+    AuthorityDAO getAuthorityDAO();
+
     KeyDAO getKeyDAO();
 }

http://git-wip-us.apache.org/repos/asf/nifi/blob/3f4ac315/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/java/org/apache/nifi/admin/dao/UserDAO.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/java/org/apache/nifi/admin/dao/UserDAO.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/java/org/apache/nifi/admin/dao/UserDAO.java
new file mode 100644
index 0000000..7e91c07
--- /dev/null
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/java/org/apache/nifi/admin/dao/UserDAO.java
@@ -0,0 +1,128 @@
+/*
+ * 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.admin.dao;
+
+import java.util.Date;
+import java.util.Set;
+import org.apache.nifi.user.AccountStatus;
+import org.apache.nifi.user.NiFiUser;
+
+/**
+ * Defines the user data access object.
+ */
+public interface UserDAO {
+
+    /**
+     * Determines whether there are any PENDING user accounts.
+     *
+     * @return true if pending
+     * @throws DataAccessException dae
+     */
+    Boolean hasPendingUserAccounts() throws DataAccessException;
+
+    /**
+     * Returns all users.
+     *
+     * @return all users
+     * @throws DataAccessException dae
+     */
+    Set<NiFiUser> findUsers() throws DataAccessException;
+
+    /**
+     * Returns all user groups.
+     *
+     * @return all group names
+     * @throws DataAccessException dae
+     */
+    Set<String> findUserGroups() throws DataAccessException;
+
+    /**
+     * Returns all users for the specified group.
+     *
+     * @param group group
+     * @return users in group
+     * @throws DataAccessException dae
+     */
+    Set<NiFiUser> findUsersForGroup(String group) throws DataAccessException;
+
+    /**
+     * Returns the user with the specified id.
+     *
+     * @param id user id
+     * @return user for the given id
+     * @throws DataAccessException dae
+     */
+    NiFiUser findUserById(String id) throws DataAccessException;
+
+    /**
+     * Returns the user with the specified DN.
+     *
+     * @param dn user dn
+     * @return user
+     */
+    NiFiUser findUserByDn(String dn) throws DataAccessException;
+
+    /**
+     * Creates a new user based off the specified NiFiUser.
+     *
+     * @param user to create
+     * @return the created user with it's id
+     */
+    NiFiUser createUser(NiFiUser user) throws DataAccessException;
+
+    /**
+     * Updates the specified NiFiUser.
+     *
+     * @param user to update
+     */
+    void updateUser(NiFiUser user) throws DataAccessException;
+
+    /**
+     * Deletes the specified user.
+     *
+     * @param id user identifier
+     * @throws DataAccessException dae
+     */
+    void deleteUser(String id) throws DataAccessException;
+
+    /**
+     * Sets the status of the specified group.
+     *
+     * @param group group
+     * @param status status
+     * @throws DataAccessException dae
+     */
+    void updateGroupStatus(String group, AccountStatus status) throws DataAccessException;
+
+    /**
+     * Sets the last verified time for all users in the specified group.
+     *
+     * @param group group
+     * @param lastVerified date last verified
+     * @throws DataAccessException dae
+     */
+    void updateGroupVerification(String group, Date lastVerified) throws DataAccessException;
+
+    /**
+     * Ungroups the specified group.
+     *
+     * @param group to ungroup
+     * @throws DataAccessException dae
+     */
+    void ungroup(String group) throws DataAccessException;
+
+}

http://git-wip-us.apache.org/repos/asf/nifi/blob/3f4ac315/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/java/org/apache/nifi/admin/dao/impl/DAOFactoryImpl.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/java/org/apache/nifi/admin/dao/impl/DAOFactoryImpl.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/java/org/apache/nifi/admin/dao/impl/DAOFactoryImpl.java
index 09ad103..940e364 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/java/org/apache/nifi/admin/dao/impl/DAOFactoryImpl.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/java/org/apache/nifi/admin/dao/impl/DAOFactoryImpl.java
@@ -18,8 +18,10 @@ package org.apache.nifi.admin.dao.impl;
 
 import java.sql.Connection;
 import org.apache.nifi.admin.dao.ActionDAO;
+import org.apache.nifi.admin.dao.AuthorityDAO;
 import org.apache.nifi.admin.dao.DAOFactory;
 import org.apache.nifi.admin.dao.KeyDAO;
+import org.apache.nifi.admin.dao.UserDAO;
 
 /**
  *
@@ -38,6 +40,16 @@ public class DAOFactoryImpl implements DAOFactory {
     }
 
     @Override
+    public AuthorityDAO getAuthorityDAO() {
+        return new StandardAuthorityDAO(connection);
+    }
+
+    @Override
+    public UserDAO getUserDAO() {
+        return new StandardUserDAO(connection);
+    }
+
+    @Override
     public KeyDAO getKeyDAO() {
         return new StandardKeyDAO(connection);
     }