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 2015/11/23 21:47:00 UTC

[49/50] [abbrv] nifi git commit: NIFI-655: - Refactoring web security to use Spring Security Java Configuration. - Introducing security in Web UI in order to get JWT.

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.

NIFI-655:
- Creating an endpoint for returning the identity of the current user.
- Updating the LoginAuthenticationFilter.

NIFI-655:
- Moving NiFi registration to the login page.
- Running the authentication filters in a different order to ensure we can disambiguate each case.
- Starting to layout each case... Forbidden, Login, Create User, Create NiFi Account.

NIFI-655:
- Addressing checkstyle issues.

NIFI-655:
- Making nf-storage available in the login page.
- Requiring use of local storage.
- Ignoring security for GET requests when obtaining the login configuration.

NIFI-655:
- Adding a new endpoint to obtain the status of a user registration.
- Updated the login page loading to ensure all possible states work.

NIFI-655:
- Ensuring we know the necessary state before we attempt to render the login page.
- Building the proxy chain in the JWT authentication filter.
- Only rendering the login when appropriate.

NIFI-655:
- Starting to style the login page.
- Added simple 'login' support by identifying username/password. Issuing JWT token coming...
- Added logout support
- Rendering the username when appropriate.

NIFI-655:
- Extracting certificate validation into a utility class.
- Fixing checkstyle issues.
- Cleaning up the web security context.
- Removing proxy chain checking where possible.

NIFI-655:
- Starting to add support for registration.
- Creating registration form.

NIFI-655:
- Starting to implement the JWT service.
- Parsing JWT on client side in order to render who the user currently is when logged in.

NIFI-655:
- Allowing the user to link back to the log in page from the new account page.
- Renaming DN to identity where possible.

NIFI-655:
- Fixing checkstyle issues.

NIFI-655:
- Adding more/better support for logging out.

NIFI-655:
- Fixing checkstyle issues.

NIFI-655:
- Adding a few new exceptions for the login identity provider.

NIFI-655:
- Disabling log in by default initially.
- Restoring authorization service unit test.

NIFI-655:
- Fixing checkstyle issues.

NIFI-655:
- Updating packages for log in filters.
- Handling new registration exceptions.
- Code clean up.

NIFI-655:
- Removing registration support.
- Removing file based implementation.

NIFI-655:
- Removing file based implementation.

NIFI-655:
- Removing unused spring configuration files.

NIFI-655:
- Making the auto wiring more explicit.

NIFI-655:
- Removing unused dependencies.

NIFI-655:
- Removing unused filter.

NIFI-655:
- Updating the login API authenticate method to use a richer set of exceptions.
- UI code clean.

NIFI-655:
- Ensuring the login identity provider is able to switch context classloaders via the standard NAR mechanisms.

NIFI-655:
- Initial commit of the LDAP based identity providers.
- Fixed issue when attempting to log into a NiFi that does not support new account requests.

NIFI-655:
- Allowing the ldap provider to specify if client authentication is required/desired.

NIFI-655:
- Persisting keys to sign user tokens.
- Allowing the identity provider to specify the token expiration.
- Code clean up.

NIFI-655:
- Ensuring identities are unique in the key table.

NIFI-655:
- Adding support for specifying the user search base and user search filter in the active directory provider.

NIFI-655:
- Fixing checkstyle issues.

NIFI-655:
- Adding automatic client side token renewal.

NIFI-655:
- Ensuring the logout link is rendered when appropriate.

NIFI-655:
- Adding configuration options for referrals and connect/read timeouts

NIFI-655:
- Added an endpoint for access details including configuration, creating tokens, and checking status.
- Updated DTOs and client side to utilize new endpoints.

NIFI-655:
- Refactoring certificate extraction and validation.
- Refactoring how expiration is specified in the login identity providers.
- Adding unit tests for the access endpoints.
- Code clean up.

NIFI-655:
- Keeping token expiration between 1 minute and 12 hours.

NIFI-655:
- Using the user identity provided by the login identity provider.

NIFI-655: - Fixed typo in error message for unrecognized authentication strategy.

Signed-off-by: Matt Gilman <ma...@gmail.com>

NIFI-655. - Added logback-test.xml configuration resource for nifi-web-security.

Signed-off-by: Matt Gilman <ma...@gmail.com>

NIFI-655. - Added issuer field to LoginAuthenticationToken. - Updated AccessResource to pass identity provider class name when creating LoginAuthenticationTokens. - Began refactoring JWT logic from request parsing logic in JwtService. - Added unit tests for JWT logic.

Signed-off-by: Matt Gilman <ma...@gmail.com>

NIFI-655. - Changed issuer field to use FQ class name because some classes return an empty string for getSimpleName(). - Finished refactoring JWT logic from request parsing logic in JwtService. - Updated AccessResource and JwtAuthenticationFilter to call new JwtService methods decoupled from request header parsing. - Added extensive unit tests for JWT logic.

Signed-off-by: Matt Gilman <ma...@gmail.com>

NIFI-655:
- Refactoring key service to expose the key id.
- Handling client side expiration better.
- Removing specialized active directory provider and abstract ldap provider.

NIFI-655. - Updated JwtService and JwtServiceTest to use Key POJO instead of raw String key from KeyService.

Signed-off-by: Matt Gilman <ma...@gmail.com>

NIFI-655:
- Fixing typo when loading the ldap connect timeout.
- Providing a better experience for session expiration.
- Using ellipsis for lengthly user name.
- Adding an issuer to the authentication response so the LIP can specify the appropriate value.

NIFI-655:
- Showing a logging in notification during the log in process.

NIFI-655:
- Removing unnecessary class.

NIFI-655:
- Fixing checkstyle issues.
- Showing the progress spinner while submitting account justification.

NIFI-655:
- Removing deprecated authentication strategy.
- Renaming TLS to START_TLS.
- Allowing the protocol to be configured.

NIFI-655:
- Fixing issue detecting the presence of DN column

NIFI-655:
- Pre-populating the login-identity-providers.xml file with necessary properties and documentation.
- Renaming the Authentication Duration property name.

NIFI-655:
- Updating documentation for the failure response codes.

NIFI-655:
- Ensuring the user identity is not too long.

NIFI-655:
- Updating default authentication expiration to 12 hours.

NIFI-655:
- Remaining on the login form when there is any unsuccessful login attempt.
- Fixing checkstyle issues.


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

Branch: refs/heads/NIFI-655
Commit: aaf14c45c96077c0075af8f3442e392b717244c1
Parents: 4e2c94d
Author: Matt Gilman <ma...@gmail.com>
Authored: Wed Oct 7 13:33:34 2015 -0400
Committer: Matt Gilman <ma...@gmail.com>
Committed: Mon Nov 23 14:50:13 2015 -0500

----------------------------------------------------------------------
 LICENSE                                         |   22 +
 .../authentication/AuthenticationResponse.java  |   65 +
 .../nifi/authentication/LoginCredentials.java   |   39 +
 .../authentication/LoginIdentityProvider.java   |   61 +
 ...ginIdentityProviderConfigurationContext.java |   48 +
 ...inIdentityProviderInitializationContext.java |   27 +
 .../LoginIdentityProviderLookup.java            |   25 +
 .../LoginIdentityProviderContext.java           |   35 +
 .../exception/IdentityAccessException.java      |   33 +
 .../InvalidLoginCredentialsException.java       |   33 +
 .../nifi/authorization/AuthorityProvider.java   |   42 +-
 .../nifi/web/NiFiWebConfigurationContext.java   |    2 +-
 .../org/apache/nifi/web/NiFiWebContext.java     |    2 +-
 nifi-assembly/LICENSE                           |   22 +
 nifi-assembly/pom.xml                           |    8 +
 .../org/apache/nifi/util/NiFiProperties.java    |   64 +-
 .../nifi/security/util/CertificateUtils.java    |   51 +-
 .../nifi-framework/nifi-administration/pom.xml  |    1 -
 .../nifi/admin/AuditDataSourceFactoryBean.java  |   23 +-
 .../nifi/admin/KeyDataSourceFactoryBean.java    |  154 ++
 .../nifi/admin/UserDataSourceFactoryBean.java   |   93 +-
 .../org/apache/nifi/admin/dao/DAOFactory.java   |    2 +
 .../java/org/apache/nifi/admin/dao/KeyDAO.java  |   49 +
 .../nifi/admin/dao/impl/DAOFactoryImpl.java     |    6 +
 .../nifi/admin/dao/impl/StandardActionDAO.java  |   10 +-
 .../nifi/admin/dao/impl/StandardKeyDAO.java     |  154 ++
 .../nifi/admin/dao/impl/StandardUserDAO.java    |   53 +-
 .../apache/nifi/admin/service/KeyService.java   |   42 +
 .../service/action/AbstractUserAction.java      |    4 +-
 .../service/action/AuthorizeUserAction.java     |   24 +-
 .../admin/service/action/DisableUserAction.java |    6 +-
 .../admin/service/action/GetKeyByIdAction.java  |   42 +
 .../service/action/GetKeyByIdentityAction.java  |   42 +
 .../service/action/GetOrCreateKeyAction.java    |   48 +
 .../action/RequestUserAccountAction.java        |   14 +-
 .../service/action/SeedUserAccountsAction.java  |   18 +-
 .../admin/service/action/UngroupUserAction.java |    6 +-
 .../admin/service/action/UpdateUserAction.java  |   24 +-
 .../service/action/UpdateUserGroupAction.java   |   32 +-
 .../admin/service/impl/StandardKeyService.java  |  126 ++
 .../src/main/java/org/apache/nifi/key/Key.java  |   69 +
 .../java/org/apache/nifi/user/NiFiUser.java     |   18 +-
 .../resources/nifi-administration-context.xml   |   16 +
 .../service/action/AuthorizeUserActionTest.java |  100 +-
 .../service/action/CreateUserActionTest.java    |   12 +-
 .../service/action/DisableUserActionTest.java   |   14 +-
 .../action/RequestUserAccountActionTest.java    |   22 +-
 .../action/SeedUserAccountsActionTest.java      |   44 +-
 .../action/SetUserAuthoritiesActionTest.java    |   18 +-
 .../web/api/dto/AccessConfigurationDTO.java     |   61 +
 .../nifi/web/api/dto/AccessStatusDTO.java       |  101 +
 .../api/entity/AccessConfigurationEntity.java   |   43 +
 .../nifi/web/api/entity/AccessStatusEntity.java |   43 +
 .../nifi/web/api/entity/IdentityEntity.java     |   52 +
 .../org/apache/nifi/nar/ExtensionManager.java   |   17 +-
 .../nifi/nar/NarThreadContextClassLoader.java   |    2 +
 .../resources/conf/login-identity-providers.xml |   92 +
 .../src/main/resources/conf/nifi.properties     |    3 +
 .../org/apache/nifi/web/server/JettyServer.java |    8 +-
 .../apache/nifi/audit/ControllerAuditor.java    |    8 +-
 .../nifi/audit/ControllerServiceAuditor.java    |   12 +-
 .../org/apache/nifi/audit/FunnelAuditor.java    |    2 +-
 .../java/org/apache/nifi/audit/PortAuditor.java |    6 +-
 .../apache/nifi/audit/ProcessGroupAuditor.java  |    6 +-
 .../org/apache/nifi/audit/ProcessorAuditor.java |    6 +-
 .../apache/nifi/audit/RelationshipAuditor.java  |    4 +-
 .../nifi/audit/RemoteProcessGroupAuditor.java   |    6 +-
 .../apache/nifi/audit/ReportingTaskAuditor.java |    6 +-
 .../org/apache/nifi/audit/SnippetAuditor.java   |    2 +-
 .../org/apache/nifi/web/NiFiServiceFacade.java  |    7 +
 .../nifi/web/NiFiWebApiConfiguration.java       |   40 +
 .../web/NiFiWebApiSecurityConfiguration.java    |  179 ++
 .../nifi/web/StandardNiFiServiceFacade.java     |   28 +-
 .../StandardNiFiWebConfigurationContext.java    |    8 +-
 .../apache/nifi/web/StandardNiFiWebContext.java |    8 +-
 .../org/apache/nifi/web/api/AccessResource.java |  424 ++++
 .../nifi/web/api/ApplicationResource.java       |   16 +-
 .../apache/nifi/web/api/ControllerResource.java |   65 +-
 .../org/apache/nifi/web/api/UserResource.java   |   49 +-
 .../api/config/AccessDeniedExceptionMapper.java |    2 +-
 .../InvalidAuthenticationExceptionMapper.java   |   44 +
 .../org/apache/nifi/web/api/dto/DtoFactory.java |    2 +-
 .../nifi/web/controller/ControllerFacade.java   |   17 +-
 .../web/dao/impl/StandardConnectionDAO.java     |    2 +-
 .../apache/nifi/web/filter/RequestLogger.java   |    6 +-
 .../src/main/resources/nifi-web-api-context.xml |    9 +
 .../src/main/webapp/WEB-INF/web.xml             |   13 +-
 .../accesscontrol/AccessTokenEndpointTest.java  |  292 +++
 .../util/NiFiTestAuthorizationProvider.java     |    3 +-
 .../util/NiFiTestLoginIdentityProvider.java     |   75 +
 .../nifi/integration/util/NiFiTestServer.java   |    9 +-
 .../nifi/integration/util/NiFiTestUser.java     |  232 ++-
 ...he.nifi.authentication.LoginIdentityProvider |   15 +
 .../access-control/controller-services.xml      |   18 -
 .../access-control/login-identity-providers.xml |   24 +
 .../resources/access-control/nifi.properties    |    8 +-
 .../access-control/reporting-tasks.xml          |   17 -
 .../nifi-web/nifi-web-security/pom.xml          |   43 +
 .../org/apache/nifi/web/security/DnUtils.java   |   85 -
 .../InvalidAuthenticationException.java         |   35 +
 .../security/NiFiAuthenticationEntryPoint.java  |   71 +
 .../web/security/NiFiAuthenticationFilter.java  |  209 ++
 .../security/NiFiAuthenticationProvider.java    |   73 +
 .../nifi/web/security/ProxiedEntitiesUtils.java |  147 ++
 .../anonymous/NiFiAnonymousUserFilter.java      |   56 +-
 .../NiFiAuthenticationEntryPoint.java           |   69 -
 .../authorization/NiFiAuthorizationService.java |   46 +-
 .../authorization/NodeAuthorizedUserFilter.java |  128 --
 .../security/jwt/JwtAuthenticationFilter.java   |   80 +
 .../nifi/web/security/jwt/JwtService.java       |  162 ++
 .../security/node/NodeAuthorizedUserFilter.java |  127 ++
 .../LoginIdentityProviderFactoryBean.java       |  312 +++
 ...ginIdentityProviderConfigurationContext.java |   51 +
 ...inIdentityProviderInitializationContext.java |   45 +
 .../token/LoginAuthenticationToken.java         |  123 ++
 .../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 |    3 +-
 .../nifi/web/security/user/NiFiUserUtils.java   |   27 +-
 .../security/x509/X509AuthenticationFilter.java |  304 +--
 .../security/x509/X509CertificateExtractor.java |    4 +-
 .../security/x509/X509CertificateValidator.java |   58 +
 .../web/security/x509/X509IdentityProvider.java |   94 +
 .../x509/ocsp/OcspCertificateValidator.java     |   20 +-
 .../resources/nifi-web-security-context.xml     |   83 +-
 .../src/main/xsd/login-identity-providers.xsd   |   49 +
 .../NiFiAuthorizationServiceTest.java           |   64 +-
 .../nifi/web/security/jwt/JwtServiceTest.java   |  445 ++++
 .../src/test/resources/logback-test.xml         |   36 +
 .../nifi-framework/nifi-web/nifi-web-ui/pom.xml |   53 +-
 .../src/main/resources/META-INF/LICENSE         |   22 +
 .../resources/filters/bulletin-board.properties |    1 +
 .../main/resources/filters/canvas.properties    |    3 +-
 .../main/resources/filters/cluster.properties   |    1 +
 .../main/resources/filters/counters.properties  |    1 +
 .../main/resources/filters/history.properties   |    1 +
 .../main/resources/filters/login-min.properties |   18 +
 .../src/main/resources/filters/login.properties |   25 +
 .../resources/filters/provenance.properties     |    1 +
 .../main/resources/filters/summary.properties   |    1 +
 .../main/resources/filters/templates.properties |    1 +
 .../src/main/resources/filters/users.properties |    1 +
 .../webapp/WEB-INF/pages/bulletin-board.jsp     |    1 +
 .../src/main/webapp/WEB-INF/pages/canvas.jsp    |    3 +-
 .../src/main/webapp/WEB-INF/pages/cluster.jsp   |    1 +
 .../src/main/webapp/WEB-INF/pages/counters.jsp  |    1 +
 .../src/main/webapp/WEB-INF/pages/history.jsp   |    1 +
 .../src/main/webapp/WEB-INF/pages/login.jsp     |   54 +
 .../main/webapp/WEB-INF/pages/message-page.jsp  |    4 +-
 .../main/webapp/WEB-INF/pages/provenance.jsp    |    1 +
 .../src/main/webapp/WEB-INF/pages/summary.jsp   |    1 +
 .../src/main/webapp/WEB-INF/pages/templates.jsp |    1 +
 .../src/main/webapp/WEB-INF/pages/users.jsp     |    1 +
 .../WEB-INF/partials/canvas/canvas-header.jsp   |   11 +
 .../WEB-INF/partials/canvas/registration.jsp    |   44 -
 .../WEB-INF/partials/login/login-form.jsp       |   32 +
 .../WEB-INF/partials/login/login-message.jsp    |   21 +
 .../WEB-INF/partials/login/login-progress.jsp   |   22 +
 .../WEB-INF/partials/login/login-submission.jsp |   20 +
 .../partials/login/nifi-registration-form.jsp   |   38 +
 .../webapp/WEB-INF/partials/message-pane.jsp    |    7 +-
 .../partials/users/user-details-dialog.jsp      |    2 +-
 .../nifi-web-ui/src/main/webapp/WEB-INF/web.xml |   22 +-
 .../nifi-web-ui/src/main/webapp/css/canvas.css  |    1 -
 .../nifi-web-ui/src/main/webapp/css/header.css  |   18 +
 .../nifi-web-ui/src/main/webapp/css/login.css   |   95 +
 .../nifi-web-ui/src/main/webapp/css/main.css    |   13 +-
 .../src/main/webapp/css/registration.css        |   45 -
 .../src/main/webapp/js/jquery/jquery.base64.js  |  123 ++
 .../js/nf/bulletin-board/nf-bulletin-board.js   |    2 +
 .../webapp/js/nf/canvas/nf-canvas-header.js     |   49 +-
 .../src/main/webapp/js/nf/canvas/nf-canvas.js   |  248 ++-
 .../main/webapp/js/nf/canvas/nf-registration.js |   71 -
 .../src/main/webapp/js/nf/canvas/nf-storage.js  |  139 --
 .../src/main/webapp/js/nf/cluster/nf-cluster.js |    2 +
 .../main/webapp/js/nf/counters/nf-counters.js   |    2 +
 .../src/main/webapp/js/nf/history/nf-history.js |    2 +
 .../src/main/webapp/js/nf/login/nf-login.js     |  302 +++
 .../src/main/webapp/js/nf/nf-common.js          | 1926 ++++++++++--------
 .../src/main/webapp/js/nf/nf-dialog.js          |   23 +-
 .../src/main/webapp/js/nf/nf-storage.js         |  172 ++
 .../webapp/js/nf/provenance/nf-provenance.js    |    2 +
 .../src/main/webapp/js/nf/summary/nf-summary.js |    2 +
 .../main/webapp/js/nf/templates/nf-templates.js |    2 +
 .../src/main/webapp/js/nf/users/nf-users.js     |    2 +
 .../nifi-ldap-iaa-providers-nar/pom.xml         |   32 +
 .../nifi-ldap-iaa-providers/pom.xml             |   60 +
 .../nifi/ldap/LdapAuthenticationStrategy.java   |   27 +
 .../java/org/apache/nifi/ldap/LdapProvider.java |  279 +++
 .../org/apache/nifi/ldap/ReferralStrategy.java  |   39 +
 ...he.nifi.authentication.LoginIdentityProvider |   15 +
 .../nifi-ldap-iaa-providers-bundle/pom.xml      |   38 +
 nifi-nar-bundles/pom.xml                        |    1 +
 pom.xml                                         |   67 +-
 197 files changed, 8863 insertions(+), 2596 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/nifi/blob/aaf14c45/LICENSE
----------------------------------------------------------------------
diff --git a/LICENSE b/LICENSE
index 59741e6..f4be753 100644
--- a/LICENSE
+++ b/LICENSE
@@ -374,6 +374,28 @@ For details see http://jqueryui.com
     OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
     WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
+This product bundles 'jquery.base64.js' which is available under an MIT style license.
+
+    Copyright (c) 2013 Yannick Albert (http://yckart.com/)
+
+    Permission is hereby granted, free of charge, to any person obtaining 
+    a copy of this software and associated documentation files (the "Software"), 
+    to deal in the Software without restriction, including without limitation 
+    the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 
+    sell copies of the Software, and to permit persons to whom the Software is 
+    furnished to do so, subject to the following conditions:
+
+    The above copyright notice and this permission notice shall be 
+    included in all copies or substantial portions of the Software.
+
+    THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, 
+    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 
+    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 
+    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 
+    LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 
+    OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 
+    WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
 This product bundles 'SlickGrid v2.2' which is available under an MIT style license.
 
     Copyright (c) 2010 Michael Leibman, http://github.com/mleibman/slickgrid

http://git-wip-us.apache.org/repos/asf/nifi/blob/aaf14c45/nifi-api/src/main/java/org/apache/nifi/authentication/AuthenticationResponse.java
----------------------------------------------------------------------
diff --git a/nifi-api/src/main/java/org/apache/nifi/authentication/AuthenticationResponse.java b/nifi-api/src/main/java/org/apache/nifi/authentication/AuthenticationResponse.java
new file mode 100644
index 0000000..e9999fc
--- /dev/null
+++ b/nifi-api/src/main/java/org/apache/nifi/authentication/AuthenticationResponse.java
@@ -0,0 +1,65 @@
+/*
+ * 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;
+
+/**
+ * Authentication response for a user login attempt.
+ */
+public class AuthenticationResponse {
+
+    private final String identity;
+    private final String username;
+    private final long expiration;
+    private final String issuer;
+
+    /**
+     * Creates an authentication response. The username and how long the authentication is valid in milliseconds
+     *
+     * @param identity The user identity
+     * @param username The username
+     * @param expiration The expiration in milliseconds
+     * @param issuer The issuer of the token
+     */
+    public AuthenticationResponse(final String identity, final String username, final long expiration, final String issuer) {
+        this.identity = identity;
+        this.username = username;
+        this.expiration = expiration;
+        this.issuer = issuer;
+    }
+
+    public String getIdentity() {
+        return identity;
+    }
+
+    public String getUsername() {
+        return username;
+    }
+
+    public String getIssuer() {
+        return issuer;
+    }
+
+    /**
+     * Returns the expiration of a given authentication in milliseconds.
+     *
+     * @return The expiration in milliseconds
+     */
+    public long getExpiration() {
+        return expiration;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/nifi/blob/aaf14c45/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/aaf14c45/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..54becb3
--- /dev/null
+++ b/nifi-api/src/main/java/org/apache/nifi/authentication/LoginIdentityProvider.java
@@ -0,0 +1,61 @@
+/*
+ * 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.authentication.exception.IdentityAccessException;
+import org.apache.nifi.authentication.exception.InvalidLoginCredentialsException;
+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 {
+
+    /**
+     * Authenticates the specified login credentials.
+     *
+     * @param credentials the credentials
+     * @return The authentication response
+     * @throws InvalidLoginCredentialsException The login credentials were invalid
+     * @throws IdentityAccessException Unable to register the user due to an issue accessing the underlying storage
+     */
+    AuthenticationResponse authenticate(LoginCredentials credentials) throws InvalidLoginCredentialsException, IdentityAccessException;
+
+    /**
+     * Called immediately after instance creation for implementers to perform additional setup
+     *
+     * @param initializationContext in which to initialize
+     * @throws ProviderCreationException Unable 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/aaf14c45/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/aaf14c45/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/aaf14c45/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/aaf14c45/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/aaf14c45/nifi-api/src/main/java/org/apache/nifi/authentication/exception/IdentityAccessException.java
----------------------------------------------------------------------
diff --git a/nifi-api/src/main/java/org/apache/nifi/authentication/exception/IdentityAccessException.java b/nifi-api/src/main/java/org/apache/nifi/authentication/exception/IdentityAccessException.java
new file mode 100644
index 0000000..b68c675
--- /dev/null
+++ b/nifi-api/src/main/java/org/apache/nifi/authentication/exception/IdentityAccessException.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.authentication.exception;
+
+/**
+ * Represents the case when the identity could not be confirmed because it was unable
+ * to access the backing store.
+ */
+public class IdentityAccessException extends RuntimeException {
+
+    public IdentityAccessException(String message, Throwable cause) {
+        super(message, cause);
+    }
+
+    public IdentityAccessException(String message) {
+        super(message);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/nifi/blob/aaf14c45/nifi-api/src/main/java/org/apache/nifi/authentication/exception/InvalidLoginCredentialsException.java
----------------------------------------------------------------------
diff --git a/nifi-api/src/main/java/org/apache/nifi/authentication/exception/InvalidLoginCredentialsException.java b/nifi-api/src/main/java/org/apache/nifi/authentication/exception/InvalidLoginCredentialsException.java
new file mode 100644
index 0000000..fbfa324
--- /dev/null
+++ b/nifi-api/src/main/java/org/apache/nifi/authentication/exception/InvalidLoginCredentialsException.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.authentication.exception;
+
+/**
+ * Represents the case when the identity could not be confirmed because the
+ * login credentials were invalid.
+ */
+public class InvalidLoginCredentialsException extends RuntimeException {
+
+    public InvalidLoginCredentialsException(String message, Throwable cause) {
+        super(message, cause);
+    }
+
+    public InvalidLoginCredentialsException(String message) {
+        super(message);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/nifi/blob/aaf14c45/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
index 723ec33..716216d 100644
--- a/nifi-api/src/main/java/org/apache/nifi/authorization/AuthorityProvider.java
+++ b/nifi-api/src/main/java/org/apache/nifi/authorization/AuthorityProvider.java
@@ -31,33 +31,33 @@ import org.apache.nifi.authorization.exception.UnknownIdentityException;
 public interface AuthorityProvider {
 
     /**
-     * @param dn of the user
-     * @return whether the user with the specified DN is known to this authority
+     * @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 dn) throws AuthorityAccessException;
+    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 dn of the user to lookup
+     * @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 dn) throws UnknownIdentityException, AuthorityAccessException;
+    Set<Authority> getAuthorities(String identity) throws UnknownIdentityException, AuthorityAccessException;
 
     /**
      * Sets the specified authorities for the specified user.
      *
-     * @param dn 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 dn, Set<Authority> authorities) throws UnknownIdentityException, AuthorityAccessException;
+    void setAuthorities(String identity, Set<Authority> authorities) throws UnknownIdentityException, AuthorityAccessException;
 
     /**
      * Gets the users for the specified authority.
@@ -72,32 +72,32 @@ public interface AuthorityProvider {
      * Revokes the specified user. Its up to the implementor to determine the
      * semantics of revocation.
      *
-     * @param dn the dn of the 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 revokeUser(String dn) throws UnknownIdentityException, AuthorityAccessException;
+    void revokeUser(String identity) throws UnknownIdentityException, AuthorityAccessException;
 
     /**
      * Add the specified user.
      *
-     * @param dn of the 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 dn, String group) throws IdentityAlreadyExistsException, AuthorityAccessException;
+    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 dn the user
+     * @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 dn) throws UnknownIdentityException, AuthorityAccessException;
+    String getGroupForUser(String identity) throws UnknownIdentityException, AuthorityAccessException;
 
     /**
      * Revokes all users for a specified group. Its up to the implementor to
@@ -112,21 +112,21 @@ public interface AuthorityProvider {
     /**
      * Adds the specified users to the specified group.
      *
-     * @param dn the set of users to add to the 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> dn, String group) throws UnknownIdentityException, AuthorityAccessException;
+    void setUsersGroup(Set<String> identity, String group) throws UnknownIdentityException, AuthorityAccessException;
 
     /**
      * Ungroups the specified user.
      *
-     * @param dn of the 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 dn) throws UnknownIdentityException, AuthorityAccessException;
+    void ungroupUser(String identity) throws UnknownIdentityException, AuthorityAccessException;
 
     /**
      * Ungroups the specified group. Since the semantics of revocation is up to
@@ -143,18 +143,18 @@ public interface AuthorityProvider {
      * Determines whether the user in the specified dnChain should be able to
      * download the content for the flowfile with the specified attributes.
      *
-     * The first dn in the chain is the end user that the request was issued on
-     * behalf of. The subsequent dn's in the chain represent entities proxying
+     * 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 dnChain of the user
+     * @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> dnChain, Map<String, String> attributes) throws UnknownIdentityException, AuthorityAccessException;
+    DownloadAuthorization authorizeDownload(List<String> proxyChain, Map<String, String> attributes) throws UnknownIdentityException, AuthorityAccessException;
 
     /**
      * Called immediately after instance creation for implementers to perform

http://git-wip-us.apache.org/repos/asf/nifi/blob/aaf14c45/nifi-api/src/main/java/org/apache/nifi/web/NiFiWebConfigurationContext.java
----------------------------------------------------------------------
diff --git a/nifi-api/src/main/java/org/apache/nifi/web/NiFiWebConfigurationContext.java b/nifi-api/src/main/java/org/apache/nifi/web/NiFiWebConfigurationContext.java
index ae32b10..39bea4f 100644
--- a/nifi-api/src/main/java/org/apache/nifi/web/NiFiWebConfigurationContext.java
+++ b/nifi-api/src/main/java/org/apache/nifi/web/NiFiWebConfigurationContext.java
@@ -54,7 +54,7 @@ public interface NiFiWebConfigurationContext {
     void saveActions(NiFiWebRequestContext requestContext, Collection<ConfigurationAction> actions);
 
     /**
-     * @return the current user dn. Returns null if no user is found
+     * @return the current user identity. The value may be a DN, an email, a username, or any string that identities the user. Returns null if no user is found
      */
     String getCurrentUserDn();
 

http://git-wip-us.apache.org/repos/asf/nifi/blob/aaf14c45/nifi-api/src/main/java/org/apache/nifi/web/NiFiWebContext.java
----------------------------------------------------------------------
diff --git a/nifi-api/src/main/java/org/apache/nifi/web/NiFiWebContext.java b/nifi-api/src/main/java/org/apache/nifi/web/NiFiWebContext.java
index 55e90e8..96261e5 100644
--- a/nifi-api/src/main/java/org/apache/nifi/web/NiFiWebContext.java
+++ b/nifi-api/src/main/java/org/apache/nifi/web/NiFiWebContext.java
@@ -51,7 +51,7 @@ public interface NiFiWebContext {
     void saveActions(Collection<ProcessorConfigurationAction> actions);
 
     /**
-     * @return the current user dn. Returns null if no user is found
+     * @return the current user identity. It may be a dn, an email, a username, or any string that identities the user. Returns null if no user is found
      */
     String getCurrentUserDn();
 

http://git-wip-us.apache.org/repos/asf/nifi/blob/aaf14c45/nifi-assembly/LICENSE
----------------------------------------------------------------------
diff --git a/nifi-assembly/LICENSE b/nifi-assembly/LICENSE
index 5c499e3..e21ecc9 100644
--- a/nifi-assembly/LICENSE
+++ b/nifi-assembly/LICENSE
@@ -374,6 +374,28 @@ For details see http://jqueryui.com
     OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
     WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
+This product bundles 'jquery.base64.js' which is available under an MIT style license.
+
+    Copyright (c) 2013 Yannick Albert (http://yckart.com/)
+
+    Permission is hereby granted, free of charge, to any person obtaining 
+    a copy of this software and associated documentation files (the "Software"), 
+    to deal in the Software without restriction, including without limitation 
+    the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 
+    sell copies of the Software, and to permit persons to whom the Software is 
+    furnished to do so, subject to the following conditions:
+
+    The above copyright notice and this permission notice shall be 
+    included in all copies or substantial portions of the Software.
+
+    THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, 
+    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 
+    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 
+    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 
+    LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 
+    OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 
+    WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
 This product bundles 'SlickGrid v2.2' which is available under an MIT style license.
 
     Copyright (c) 2010 Michael Leibman, http://github.com/mleibman/slickgrid

http://git-wip-us.apache.org/repos/asf/nifi/blob/aaf14c45/nifi-assembly/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-assembly/pom.xml b/nifi-assembly/pom.xml
index 961349f..86aa8bc 100644
--- a/nifi-assembly/pom.xml
+++ b/nifi-assembly/pom.xml
@@ -174,6 +174,11 @@ language governing permissions and limitations under the License. -->
         </dependency>
         <dependency>
             <groupId>org.apache.nifi</groupId>
+            <artifactId>nifi-ldap-iaa-providers-nar</artifactId>
+            <type>nar</type>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.nifi</groupId>
             <artifactId>nifi-dbcp-service-nar</artifactId>
             <type>nar</type>
         </dependency>
@@ -268,6 +273,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>
@@ -353,8 +359,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></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/aaf14c45/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..809dd09 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
      */
@@ -483,6 +486,18 @@ public class NiFiProperties extends Properties {
     }
 
     /**
+     * @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.
      *
      * @return Whether client auth is required
@@ -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/aaf14c45/nifi-commons/nifi-security-utils/src/main/java/org/apache/nifi/security/util/CertificateUtils.java
----------------------------------------------------------------------
diff --git a/nifi-commons/nifi-security-utils/src/main/java/org/apache/nifi/security/util/CertificateUtils.java b/nifi-commons/nifi-security-utils/src/main/java/org/apache/nifi/security/util/CertificateUtils.java
index 5126933..6236d8e 100644
--- a/nifi-commons/nifi-security-utils/src/main/java/org/apache/nifi/security/util/CertificateUtils.java
+++ b/nifi-commons/nifi-security-utils/src/main/java/org/apache/nifi/security/util/CertificateUtils.java
@@ -34,8 +34,7 @@ public final class CertificateUtils {
     private static final Logger logger = LoggerFactory.getLogger(CertificateUtils.class);
 
     /**
-     * Returns true if the given keystore can be loaded using the given keystore
-     * type and password. Returns false otherwise.
+     * Returns true if the given keystore can be loaded using the given keystore type and password. Returns false otherwise.
      *
      * @param keystore the keystore to validate
      * @param keystoreType the type of the keystore
@@ -77,40 +76,29 @@ public final class CertificateUtils {
     }
 
     /**
-     * Extracts the username from the specified DN. If the username cannot be
-     * extracted because the CN is in an unrecognized format, the entire CN is
-     * returned. If the CN cannot be extracted because the DN is in an
-     * unrecognized format, the entire DN is returned.
+     * Extracts the username from the specified DN. If the username cannot be extracted because the CN is in an unrecognized format, the entire CN is returned. If the CN cannot be extracted because
+     * the DN is in an unrecognized format, the entire DN is returned.
      *
      * @param dn the dn to extract the username from
      * @return the exatracted username
      */
     public static String extractUsername(String dn) {
         String username = dn;
-        String cn = "";
 
         // ensure the dn is specified
         if (StringUtils.isNotBlank(dn)) {
-
-            // attempt to locate the cn
-            if (dn.startsWith("CN=")) {
-                cn = StringUtils.substringBetween(dn, "CN=", ",");
-            } else if (dn.startsWith("/CN=")) {
-                cn = StringUtils.substringBetween(dn, "CN=", "/");
-            } else if (dn.startsWith("C=") || dn.startsWith("/C=")) {
-                cn = StringUtils.substringAfter(dn, "CN=");
-            } else if (dn.startsWith("/") && StringUtils.contains(dn, "CN=")) {
-                cn = StringUtils.substringAfter(dn, "CN=");
-            }
-
-            // attempt to get the username from the cn
-            if (StringUtils.isNotBlank(cn)) {
-                if (cn.endsWith(")")) {
-                    username = StringUtils.substringBetween(cn, "(", ")");
-                } else if (cn.contains(" ")) {
-                    username = StringUtils.substringAfterLast(cn, " ");
+            // determine the separate
+            final String separator = StringUtils.indexOfIgnoreCase(dn, "/cn=") > 0 ? "/" : ",";
+
+            // attempt to locate the cd
+            final String cnPattern = "cn=";
+            final int cnIndex = StringUtils.indexOfIgnoreCase(dn, cnPattern);
+            if (cnIndex >= 0) {
+                int separatorIndex = StringUtils.indexOf(dn, separator, cnIndex);
+                if (separatorIndex > 0) {
+                    username = StringUtils.substring(dn, cnIndex + cnPattern.length(), separatorIndex);
                 } else {
-                    username = cn;
+                    username = StringUtils.substring(dn, cnIndex + cnPattern.length());
                 }
             }
         }
@@ -119,9 +107,7 @@ public final class CertificateUtils {
     }
 
     /**
-     * Returns a list of subject alternative names. Any name that is represented
-     * as a String by X509Certificate.getSubjectAlternativeNames() is converted
-     * to lowercase and returned.
+     * Returns a list of subject alternative names. Any name that is represented as a String by X509Certificate.getSubjectAlternativeNames() is converted to lowercase and returned.
      *
      * @param certificate a certificate
      * @return a list of subject alternative names; list is never null
@@ -137,12 +123,9 @@ public final class CertificateUtils {
         final List<String> result = new ArrayList<>();
         for (final List<?> generalName : altNames) {
             /**
-             * generalName has the name type as the first element a String or
-             * byte array for the second element.  We return any general names
-             * that are String types.
+             * generalName has the name type as the first element a String or byte array for the second element. We return any general names that are String types.
              *
-             * We don't inspect the numeric name type because some certificates
-             * incorrectly put IPs and DNS names under the wrong name types.
+             * We don't inspect the numeric name type because some certificates incorrectly put IPs and DNS names under the wrong name types.
              */
             final Object value = generalName.get(1);
             if (value instanceof String) {

http://git-wip-us.apache.org/repos/asf/nifi/blob/aaf14c45/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 aeaeda8..b117618 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/aaf14c45/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..87cd420 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
@@ -45,8 +45,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 +107,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 +152,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 +175,15 @@ public class AuditDataSourceFactoryBean implements FactoryBean {
                     statement.execute(CREATE_PURGE_DETAILS_TABLE);
                 } else {
                     logger.info("Existing database found and connected to at: " + databaseUrl);
+                    RepositoryUtils.closeQuietly(rs);
+
+                    // check if the DN column exists to see if we need to transform the table
+                    rs = connection.getMetaData().getColumns(null, null, "ACTION", "USER_DN");
+                    if (rs.next()) {
+                        statement.execute(RENAME_DN_COLUMN);
+                        statement.execute(RESIZE_IDENTITY_COLUMN);
+                        statement.execute(RESIZE_USER_NAME_COLUMN);
+                    }
                 }
 
                 // commit any changes

http://git-wip-us.apache.org/repos/asf/nifi/blob/aaf14c45/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
new file mode 100644
index 0000000..688aa5a
--- /dev/null
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/java/org/apache/nifi/admin/KeyDataSourceFactoryBean.java
@@ -0,0 +1,154 @@
+/*
+ * 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 org.apache.commons.lang3.StringUtils;
+import org.h2.jdbcx.JdbcConnectionPool;
+import org.apache.nifi.util.NiFiProperties;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.FactoryBean;
+
+/**
+ *
+ */
+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 KEY_DATABASE_FILE_NAME = "nifi-key";
+
+    // ----------
+    // 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);
+
+            // get a handle to the database file
+            File databaseFile = new File(repositoryDirectory, KEY_DATABASE_FILE_NAME);
+
+            // format the database url
+            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;
+            }
+
+            // 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 initializing the database
+                statement = connection.createStatement();
+
+                // determine if the tables need to be created
+                rs = connection.getMetaData().getTables(null, null, "KEY", null);
+                if (!rs.next()) {
+                    logger.info("Database not built for repository: " + databaseUrl + ".  Building now...");
+                    RepositoryUtils.closeQuietly(rs);
+
+                    // action table
+                    statement.execute(CREATE_KEY_TABLE);
+                } else {
+                    logger.info("Existing database found and connected to at: " + databaseUrl);
+                }
+
+                // 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;
+    }
+
+    @Override
+    public Class getObjectType() {
+        return JdbcConnectionPool.class;
+    }
+
+    @Override
+    public boolean isSingleton() {
+        return true;
+    }
+
+    public void setProperties(NiFiProperties properties) {
+        this.properties = properties;
+    }
+
+    /**
+     * Disposes resources.
+     */
+    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/aaf14c45/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..6d8566e 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
@@ -21,8 +21,11 @@ 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;
@@ -41,8 +44,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,57 +63,30 @@ 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 + "', "
-            + "'" + NiFiUser.ANONYMOUS_USER_DN + "', "
+            + "'" + NiFiUser.ANONYMOUS_USER_IDENTITY + "', "
+            + "'" + NiFiUser.ANONYMOUS_USER_IDENTITY + "', "
             + "NOW(), "
             + "NOW(), "
             + "'Anonymous user needs no justification', "
             + "'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_IDENTITY + "'), "
+            + "'%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 DELETE_ANONYMOUS_AUTHORITIES = "DELETE FROM AUTHORITY "
+            + "WHERE USER_ID = (SELECT ID FROM USER WHERE IDENTITY = '" + NiFiUser.ANONYMOUS_USER_IDENTITY + "')";
 
-    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 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 +104,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 +148,25 @@ 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);
+                    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);
                 }
 
-                // close the previous result set
-                RepositoryUtils.closeQuietly(rs);
-
-                // 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);
+                // add all authorities for the anonymous user
+                for (final Authority authority : anonymousAuthorities) {
+                    statement.execute(String.format(INSERT_ANONYMOUS_AUTHORITY, authority.name()));
                 }
 
                 // commit any changes

http://git-wip-us.apache.org/repos/asf/nifi/blob/aaf14c45/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 dee4ef9..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
@@ -26,4 +26,6 @@ public interface DAOFactory {
     ActionDAO getActionDAO();
 
     AuthorityDAO getAuthorityDAO();
+
+    KeyDAO getKeyDAO();
 }