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/02 20:54:55 UTC

[1/2] nifi git commit: 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

Repository: nifi
Updated Branches:
  refs/heads/NIFI-655 e7a5e1822 -> 5e341214a


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.

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

Branch: refs/heads/NIFI-655
Commit: ade5dc9baccb55f9675d6ff64097c26a318f7da2
Parents: e7a5e18
Author: Matt Gilman <ma...@gmail.com>
Authored: Mon Nov 2 14:21:25 2015 -0500
Committer: Matt Gilman <ma...@gmail.com>
Committed: Mon Nov 2 14:21:25 2015 -0500

----------------------------------------------------------------------
 .../FileAuthorizationProvider.java              |  48 ++++---
 .../web/NiFiWebApiSecurityConfiguration.java    |  56 +++++---
 .../security/NiFiAuthenticationEntryPoint.java  |  42 +++---
 .../web/security/NiFiAuthenticationFilter.java  |  72 +++++++++-
 .../security/NiFiAuthenticationProvider.java    |  19 +--
 .../anonymous/NiFiAnonymousUserFilter.java      |  13 +-
 .../form/LoginAuthenticationFilter.java         |  13 +-
 .../security/jwt/JwtAuthenticationProvider.java |  47 ------
 .../x509/X509AuthenticationProvider.java        |  47 ------
 .../resources/nifi-web-security-context.xml     |   6 +
 .../nifi-framework/nifi-web/nifi-web-ui/pom.xml |   2 -
 .../main/resources/filters/canvas.properties    |   1 -
 .../src/main/webapp/WEB-INF/pages/canvas.jsp    |   2 -
 .../src/main/webapp/WEB-INF/pages/login.jsp     |   5 +-
 .../WEB-INF/partials/canvas/registration.jsp    |  44 ------
 .../WEB-INF/partials/login/login-form.jsp       |   5 +-
 .../WEB-INF/partials/login/login-submission.jsp |  20 +++
 .../partials/login/nifi-registration-form.jsp   |  31 ++++
 .../partials/login/registration-form.jsp        |  19 ---
 .../partials/login/user-registration-form.jsp   |  19 +++
 .../nifi-web-ui/src/main/webapp/css/canvas.css  |   1 -
 .../nifi-web-ui/src/main/webapp/css/login.css   |  19 ++-
 .../src/main/webapp/css/registration.css        |  45 ------
 .../src/main/webapp/js/nf/canvas/nf-canvas.js   |  75 +++++++---
 .../main/webapp/js/nf/canvas/nf-registration.js |  71 ----------
 .../src/main/webapp/js/nf/login/nf-login.js     | 142 +++++++++++++++++--
 .../src/main/webapp/js/nf/nf-common.js          |  16 +--
 27 files changed, 475 insertions(+), 405 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/nifi/blob/ade5dc9b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-file-authorization-provider/src/main/java/org/apache/nifi/authorization/FileAuthorizationProvider.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-file-authorization-provider/src/main/java/org/apache/nifi/authorization/FileAuthorizationProvider.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-file-authorization-provider/src/main/java/org/apache/nifi/authorization/FileAuthorizationProvider.java
index 02a5e75..d06b85f 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-file-authorization-provider/src/main/java/org/apache/nifi/authorization/FileAuthorizationProvider.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-file-authorization-provider/src/main/java/org/apache/nifi/authorization/FileAuthorizationProvider.java
@@ -113,21 +113,7 @@ public class FileAuthorizationProvider implements AuthorityProvider {
             return true;
         }
 
-        return authorizedUsers.hasUser(new HasUser() {
-            @Override
-            public boolean hasUser(List<NiFiUser> users) {
-                // attempt to get the user and ensure it was located
-                NiFiUser desiredUser = null;
-                for (final NiFiUser user : users) {
-                    if (dn.equalsIgnoreCase(authorizedUsers.getUserIdentity(user))) {
-                        desiredUser = user;
-                        break;
-                    }
-                }
-
-                return desiredUser != null;
-            }
-        });
+        return authorizedUsers.hasUser(new HasUserByIdentity(dn));
     }
 
     @Override
@@ -199,10 +185,8 @@ public class FileAuthorizationProvider implements AuthorityProvider {
         authorizedUsers.createUser(new CreateUser() {
             @Override
             public NiFiUser createUser() {
-                final NiFiUser user = authorizedUsers.getUser(new FindUserByIdentity(dn));
-
                 // ensure the user doesn't already exist
-                if (user != null) {
+                if (authorizedUsers.hasUser(new HasUserByIdentity(dn))) {
                     throw new IdentityAlreadyExistsException(String.format("User identity already exists: %s", dn));
                 }
 
@@ -322,6 +306,34 @@ public class FileAuthorizationProvider implements AuthorityProvider {
         this.properties = properties;
     }
 
+    public class HasUserByIdentity implements HasUser {
+
+        private final String identity;
+
+        public HasUserByIdentity(String identity) {
+            // ensure the identity was specified
+            if (identity == null) {
+                throw new UnknownIdentityException("User identity not specified.");
+            }
+
+            this.identity = identity;
+        }
+
+        @Override
+        public boolean hasUser(List<NiFiUser> users) {
+            // attempt to get the user and ensure it was located
+            NiFiUser desiredUser = null;
+            for (final NiFiUser user : users) {
+                if (identity.equalsIgnoreCase(authorizedUsers.getUserIdentity(user))) {
+                    desiredUser = user;
+                    break;
+                }
+            }
+
+            return desiredUser != null;
+        }
+    }
+
     public class FindUserByIdentity implements FindUser {
 
         private final String identity;

http://git-wip-us.apache.org/repos/asf/nifi/blob/ade5dc9b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/NiFiWebApiSecurityConfiguration.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/NiFiWebApiSecurityConfiguration.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/NiFiWebApiSecurityConfiguration.java
index dcf2e71..7bafce0 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/NiFiWebApiSecurityConfiguration.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/NiFiWebApiSecurityConfiguration.java
@@ -25,12 +25,9 @@ import org.apache.nifi.web.security.anonymous.NiFiAnonymousUserFilter;
 import org.apache.nifi.web.security.NiFiAuthenticationEntryPoint;
 import org.apache.nifi.web.security.form.LoginAuthenticationFilter;
 import org.apache.nifi.web.security.jwt.JwtAuthenticationFilter;
-import org.apache.nifi.web.security.jwt.JwtAuthenticationProvider;
 import org.apache.nifi.web.security.jwt.JwtService;
 import org.apache.nifi.web.security.node.NodeAuthorizedUserFilter;
-import org.apache.nifi.web.security.x509.SubjectDnX509PrincipalExtractor;
 import org.apache.nifi.web.security.x509.X509AuthenticationFilter;
-import org.apache.nifi.web.security.x509.X509AuthenticationProvider;
 import org.apache.nifi.web.security.x509.X509CertificateExtractor;
 import org.apache.nifi.web.security.x509.ocsp.OcspCertificateValidator;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -38,16 +35,17 @@ import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
 import org.springframework.http.HttpMethod;
 import org.springframework.security.authentication.AuthenticationManager;
-import org.springframework.security.authentication.AuthenticationProvider;
 import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
 import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
 import org.springframework.security.config.annotation.web.builders.HttpSecurity;
+import org.springframework.security.config.annotation.web.builders.WebSecurity;
 import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
 import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
 import org.springframework.security.config.http.SessionCreationPolicy;
 import org.springframework.security.core.userdetails.AuthenticationUserDetailsService;
 import org.springframework.security.web.authentication.AnonymousAuthenticationFilter;
 import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
+import org.springframework.security.web.authentication.preauth.x509.X509PrincipalExtractor;
 
 /**
  * NiFi Web Api Spring security
@@ -61,6 +59,8 @@ public class NiFiWebApiSecurityConfiguration extends WebSecurityConfigurerAdapte
     private UserService userService;
     private AuthenticationUserDetailsService userDetailsService;
     private JwtService jwtService;
+    private X509CertificateExtractor certificateExtractor;
+    private X509PrincipalExtractor principalExtractor;
     private LoginIdentityProvider loginIdentityProvider;
 
     public NiFiWebApiSecurityConfiguration() {
@@ -68,14 +68,18 @@ public class NiFiWebApiSecurityConfiguration extends WebSecurityConfigurerAdapte
     }
 
     @Override
+    public void configure(WebSecurity webSecurity) throws Exception {
+        webSecurity.ignoring().antMatchers("/controller/login/config");
+    }
+
+    @Override
     protected void configure(HttpSecurity http) throws Exception {
         http
                 .rememberMe().disable()
                 .exceptionHandling()
-                .authenticationEntryPoint(new NiFiAuthenticationEntryPoint())
+                .authenticationEntryPoint(new NiFiAuthenticationEntryPoint(properties))
                 .and()
                 .authorizeRequests()
-                .antMatchers(HttpMethod.GET, "/controller/login/config").permitAll()
                 .anyRequest().fullyAuthenticated()
                 .and()
                 .sessionManagement()
@@ -86,7 +90,7 @@ public class NiFiWebApiSecurityConfiguration extends WebSecurityConfigurerAdapte
             // login authentication for /token - exchanges for JWT for subsequent API usage
             http.addFilterBefore(buildLoginFilter("/token"), UsernamePasswordAuthenticationFilter.class);
 
-            // login registration
+            // verify the configured login authenticator supports registration
             if (loginIdentityProvider.supportsRegistration()) {
                 http.addFilterBefore(buildRegistrationFilter("/registration"), UsernamePasswordAuthenticationFilter.class);
             }
@@ -95,14 +99,14 @@ public class NiFiWebApiSecurityConfiguration extends WebSecurityConfigurerAdapte
         // cluster authorized user
         http.addFilterBefore(buildNodeAuthorizedUserFilter(), AnonymousAuthenticationFilter.class);
 
+        // anonymous
+        http.anonymous().authenticationFilter(buildAnonymousFilter());
+
         // x509
-        http.addFilterBefore(buildX509Filter(), AnonymousAuthenticationFilter.class);
+        http.addFilterAfter(buildX509Filter(), AnonymousAuthenticationFilter.class);
 
         // jwt
-        http.addFilterBefore(buildJwtFilter(), AnonymousAuthenticationFilter.class);
-
-        // anonymous
-        http.anonymous().authenticationFilter(buildAnonymousFilter());
+        http.addFilterAfter(buildJwtFilter(), AnonymousAuthenticationFilter.class);
     }
 
     @Bean
@@ -114,20 +118,16 @@ public class NiFiWebApiSecurityConfiguration extends WebSecurityConfigurerAdapte
 
     @Override
     protected void configure(AuthenticationManagerBuilder auth) throws Exception {
-        final AuthenticationProvider x509AuthenticationProvider = new NiFiAuthenticationProvider(new X509AuthenticationProvider(), userDetailsService);
-        final AuthenticationProvider jwtAuthenticationProvider = new NiFiAuthenticationProvider(new JwtAuthenticationProvider(), userDetailsService);
-
-        auth
-                .authenticationProvider(x509AuthenticationProvider)
-                .authenticationProvider(jwtAuthenticationProvider);
+        auth.authenticationProvider(new NiFiAuthenticationProvider(userDetailsService));
     }
 
     private LoginAuthenticationFilter buildLoginFilter(final String url) {
         final LoginAuthenticationFilter loginFilter = new LoginAuthenticationFilter(url);
         loginFilter.setJwtService(jwtService);
+        loginFilter.setLoginIdentityProvider(loginIdentityProvider);
         loginFilter.setUserDetailsService(userDetailsService);
-        loginFilter.setPrincipalExtractor(new SubjectDnX509PrincipalExtractor());
-        loginFilter.setCertificateExtractor(new X509CertificateExtractor());
+        loginFilter.setPrincipalExtractor(principalExtractor);
+        loginFilter.setCertificateExtractor(certificateExtractor);
         return loginFilter;
     }
 
@@ -141,6 +141,7 @@ public class NiFiWebApiSecurityConfiguration extends WebSecurityConfigurerAdapte
 
     private JwtAuthenticationFilter buildJwtFilter() throws Exception {
         final JwtAuthenticationFilter jwtFilter = new JwtAuthenticationFilter();
+        jwtFilter.setProperties(properties);
         jwtFilter.setJwtService(jwtService);
         jwtFilter.setAuthenticationManager(authenticationManager());
         return jwtFilter;
@@ -148,8 +149,9 @@ public class NiFiWebApiSecurityConfiguration extends WebSecurityConfigurerAdapte
 
     private X509AuthenticationFilter buildX509Filter() throws Exception {
         final X509AuthenticationFilter x509Filter = new X509AuthenticationFilter();
-        x509Filter.setPrincipalExtractor(new SubjectDnX509PrincipalExtractor());
-        x509Filter.setCertificateExtractor(new X509CertificateExtractor());
+        x509Filter.setProperties(properties);
+        x509Filter.setPrincipalExtractor(principalExtractor);
+        x509Filter.setCertificateExtractor(certificateExtractor);
         x509Filter.setCertificateValidator(new OcspCertificateValidator(properties));
         x509Filter.setAuthenticationManager(authenticationManager());
         return x509Filter;
@@ -185,4 +187,14 @@ public class NiFiWebApiSecurityConfiguration extends WebSecurityConfigurerAdapte
     public void setLoginIdentityProvider(LoginIdentityProvider loginIdentityProvider) {
         this.loginIdentityProvider = loginIdentityProvider;
     }
+
+    @Autowired
+    public void setCertificateExtractor(X509CertificateExtractor certificateExtractor) {
+        this.certificateExtractor = certificateExtractor;
+    }
+
+    @Autowired
+    public void setPrincipalExtractor(X509PrincipalExtractor principalExtractor) {
+        this.principalExtractor = principalExtractor;
+    }
 }

http://git-wip-us.apache.org/repos/asf/nifi/blob/ade5dc9b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/NiFiAuthenticationEntryPoint.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/NiFiAuthenticationEntryPoint.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/NiFiAuthenticationEntryPoint.java
index 6cae1f0..ab8951b 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/NiFiAuthenticationEntryPoint.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/NiFiAuthenticationEntryPoint.java
@@ -21,21 +21,26 @@ import java.io.PrintWriter;
 import javax.servlet.ServletException;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
+import org.apache.nifi.util.NiFiProperties;
+import org.apache.nifi.util.StringUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.security.core.AuthenticationException;
 import org.springframework.security.web.AuthenticationEntryPoint;
-import org.springframework.security.web.WebAttributes;
 
 /**
- * This is our own implementation of
- * org.springframework.security.web.AuthenticationEntryPoint that allows us to
- * send the response to the client exactly how we want to and log the results.
+ * This is our own implementation of org.springframework.security.web.AuthenticationEntryPoint that allows us to send the response to the client exactly how we want to and log the results.
  */
 public class NiFiAuthenticationEntryPoint implements AuthenticationEntryPoint {
 
     private static final Logger logger = LoggerFactory.getLogger(NiFiAuthenticationEntryPoint.class);
 
+    private final NiFiProperties properties;
+
+    public NiFiAuthenticationEntryPoint(NiFiProperties properties) {
+        this.properties = properties;
+    }
+    
     /**
      * Always returns a 403 error code to the client.
      *
@@ -47,23 +52,20 @@ public class NiFiAuthenticationEntryPoint implements AuthenticationEntryPoint {
      */
     @Override
     public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException ae) throws IOException, ServletException {
-        // get the last exception - the exception that is being passed in is a generic no credentials found
-        // exception because the authentication could not be found in the security context. the actual cause
-        // of the problem is stored in the session as the authentication_exception
-        Object authenticationException = request.getSession().getAttribute(WebAttributes.AUTHENTICATION_EXCEPTION);
+        // if the content type is not set, mark as access denied
+        if (StringUtils.isBlank(response.getContentType())) {
+            // write the response message
+            PrintWriter out = response.getWriter();
+            response.setContentType("text/plain");
 
-        // log request result
-        if (authenticationException instanceof AuthenticationException) {
-            ae = (AuthenticationException) authenticationException;
-            logger.info(String.format("Rejecting access to web api: %s", ae.getMessage()));
+            // return authorized if the request is secure and this nifi supports new account requests
+            if (request.isSecure() && properties.getSupportNewAccountRequests()) {
+                response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
+                out.println("Not authorized.");
+            } else {
+                response.setStatus(HttpServletResponse.SC_FORBIDDEN);
+                out.println("Access is denied.");
+            }
         }
-
-        // set the response status
-        response.setStatus(HttpServletResponse.SC_FORBIDDEN);
-        response.setContentType("text/plain");
-
-        // write the response message
-        PrintWriter out = response.getWriter();
-        out.println("Access is denied.");
     }
 }

http://git-wip-us.apache.org/repos/asf/nifi/blob/ade5dc9b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/NiFiAuthenticationFilter.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/NiFiAuthenticationFilter.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/NiFiAuthenticationFilter.java
index b83b283..21b18d0 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/NiFiAuthenticationFilter.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/NiFiAuthenticationFilter.java
@@ -17,6 +17,7 @@
 package org.apache.nifi.web.security;
 
 import java.io.IOException;
+import java.io.PrintWriter;
 import javax.servlet.Filter;
 import javax.servlet.FilterChain;
 import javax.servlet.FilterConfig;
@@ -26,13 +27,18 @@ import javax.servlet.ServletResponse;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 import org.apache.commons.lang3.StringUtils;
+import org.apache.nifi.user.NiFiUser;
+import org.apache.nifi.util.NiFiProperties;
 import org.apache.nifi.web.security.user.NiFiUserUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
+import org.springframework.security.authentication.AccountStatusException;
 import org.springframework.security.authentication.AuthenticationManager;
+import org.springframework.security.authentication.AuthenticationServiceException;
 import org.springframework.security.core.Authentication;
 import org.springframework.security.core.AuthenticationException;
 import org.springframework.security.core.context.SecurityContextHolder;
+import org.springframework.security.core.userdetails.UsernameNotFoundException;
 
 /**
  *
@@ -42,6 +48,7 @@ public abstract class NiFiAuthenticationFilter implements Filter {
     private static final Logger logger = LoggerFactory.getLogger(NiFiAuthenticationFilter.class);
 
     private AuthenticationManager authenticationManager;
+    private NiFiProperties properties;
 
     @Override
     public void init(final FilterConfig filterConfig) throws ServletException {
@@ -62,10 +69,21 @@ public abstract class NiFiAuthenticationFilter implements Filter {
     }
 
     private boolean requiresAuthentication(final HttpServletRequest request) {
+        // continue attempting authorization if the user is anonymous
+        if (isAnonymousUser()) {
+            return true;
+        }
+
+        // or there is no user yet
         return NiFiUserUtils.getNiFiUser() == null && NiFiUserUtils.getNewAccountRequest() == null;
     }
 
-    private void authenticate(final HttpServletRequest request, final HttpServletResponse response) {
+    private boolean isAnonymousUser() {
+        final NiFiUser user = NiFiUserUtils.getNiFiUser();
+        return user != null && NiFiUser.ANONYMOUS_USER_DN.equals(user.getDn());
+    }
+
+    private void authenticate(final HttpServletRequest request, final HttpServletResponse response) throws IOException {
         try {
             final Authentication authenticated = attemptAuthentication(request, response);
             if (authenticated != null) {
@@ -73,7 +91,9 @@ public abstract class NiFiAuthenticationFilter implements Filter {
                 successfulAuthorization(request, response, authorized);
             }
         } catch (final AuthenticationException ae) {
-            unsuccessfulAuthorization(request, response, ae);
+            if (!isAnonymousUser()) {
+                unsuccessfulAuthorization(request, response, ae);
+            }
         }
     }
 
@@ -88,8 +108,48 @@ public abstract class NiFiAuthenticationFilter implements Filter {
         ProxiedEntitiesUtils.successfulAuthorization(request, response, authResult);
     }
 
-    protected void unsuccessfulAuthorization(HttpServletRequest request, HttpServletResponse response, AuthenticationException failed) {
-        ProxiedEntitiesUtils.unsuccessfulAuthorization(request, response, failed);
+    protected void unsuccessfulAuthorization(HttpServletRequest request, HttpServletResponse response, AuthenticationException ae) throws IOException {
+        // populate the response
+        ProxiedEntitiesUtils.unsuccessfulAuthorization(request, response, ae);
+
+        // set the response status
+        response.setContentType("text/plain");
+
+        // write the response message
+        PrintWriter out = response.getWriter();
+
+        // use the type of authentication exception to determine the response code
+        if (ae instanceof UsernameNotFoundException) {
+            if (properties.getSupportNewAccountRequests()) {
+                response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
+                out.println("Not authorized.");
+            } else {
+                response.setStatus(HttpServletResponse.SC_FORBIDDEN);
+                out.println("Access is denied.");
+            }
+        } else if (ae instanceof AccountStatusException) {
+            response.setStatus(HttpServletResponse.SC_FORBIDDEN);
+            out.println(ae.getMessage());
+        } else if (ae instanceof UntrustedProxyException) {
+            response.setStatus(HttpServletResponse.SC_FORBIDDEN);
+            out.println(ae.getMessage());
+        } else if (ae instanceof AuthenticationServiceException) {
+            logger.error(String.format("Unable to authorize: %s", ae.getMessage()), ae);
+            response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
+            out.println(String.format("Unable to authorize: %s", ae.getMessage()));
+        } else {
+            logger.error(String.format("Unable to authorize: %s", ae.getMessage()), ae);
+            response.setStatus(HttpServletResponse.SC_FORBIDDEN);
+            out.println("Access is denied.");
+        }
+
+        // log the failure
+        logger.info(String.format("Rejecting access to web api: %s", ae.getMessage()));
+
+        // optionally log the stack trace
+        if (logger.isDebugEnabled()) {
+            logger.debug(StringUtils.EMPTY, ae);
+        }
     }
 
     /**
@@ -133,4 +193,8 @@ public abstract class NiFiAuthenticationFilter implements Filter {
         this.authenticationManager = authenticationManager;
     }
 
+    public void setProperties(NiFiProperties properties) {
+        this.properties = properties;
+    }
+
 }

http://git-wip-us.apache.org/repos/asf/nifi/blob/ade5dc9b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/NiFiAuthenticationProvider.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/NiFiAuthenticationProvider.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/NiFiAuthenticationProvider.java
index e63a97e..79e8eb2 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/NiFiAuthenticationProvider.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/NiFiAuthenticationProvider.java
@@ -16,6 +16,7 @@
  */
 package org.apache.nifi.web.security;
 
+import org.apache.nifi.web.security.token.NewAccountAuthenticationRequestToken;
 import org.apache.nifi.web.security.token.NewAccountAuthenticationToken;
 import org.apache.nifi.web.security.token.NiFiAuthenticationRequestToken;
 import org.apache.nifi.web.security.token.NiFiAuthorizationToken;
@@ -31,11 +32,9 @@ import org.springframework.security.core.userdetails.UsernameNotFoundException;
  */
 public class NiFiAuthenticationProvider implements AuthenticationProvider {
 
-    private final AuthenticationProvider provider;
     private final AuthenticationUserDetailsService<NiFiAuthenticationRequestToken> userDetailsService;
 
-    public NiFiAuthenticationProvider(final AuthenticationProvider provider, final AuthenticationUserDetailsService<NiFiAuthenticationRequestToken> userDetailsService) {
-        this.provider = provider;
+    public NiFiAuthenticationProvider(final AuthenticationUserDetailsService<NiFiAuthenticationRequestToken> userDetailsService) {
         this.userDetailsService = userDetailsService;
     }
 
@@ -43,12 +42,6 @@ public class NiFiAuthenticationProvider implements AuthenticationProvider {
     public Authentication authenticate(Authentication authentication) throws AuthenticationException {
         final NiFiAuthenticationRequestToken request = (NiFiAuthenticationRequestToken) authentication;
 
-        // ensure the base provider could authenticate
-        final Authentication result = provider.authenticate(request);
-        if (result == null) {
-            return null;
-        }
-
         try {
             // defer to the nifi user details service to authorize the user
             final UserDetails userDetails = userDetailsService.loadUserDetails(request);
@@ -58,8 +51,8 @@ public class NiFiAuthenticationProvider implements AuthenticationProvider {
         } catch (final UsernameNotFoundException unfe) {
             // if the result was an authenticated new account request and it could not be authorized because the user was not found,
             // return the token so the new account could be created. this must go here to ensure that any proxies have been authorized
-            if (isNewAccountAuthenticationToken(result)) {
-                return result;
+            if (isNewAccountAuthenticationToken(request)) {
+                return new NewAccountAuthenticationToken(((NewAccountAuthenticationRequestToken) authentication).getNewAccountRequest());
             } else {
                 throw unfe;
             }
@@ -67,12 +60,12 @@ public class NiFiAuthenticationProvider implements AuthenticationProvider {
     }
 
     private boolean isNewAccountAuthenticationToken(final Authentication authentication) {
-        return NewAccountAuthenticationToken.class.isAssignableFrom(authentication.getClass());
+        return NewAccountAuthenticationRequestToken.class.isAssignableFrom(authentication.getClass());
     }
 
     @Override
     public boolean supports(Class<?> authentication) {
-        return provider.supports(authentication) && NiFiAuthenticationRequestToken.class.isAssignableFrom(authentication);
+        return NiFiAuthenticationRequestToken.class.isAssignableFrom(authentication);
     }
 
 }

http://git-wip-us.apache.org/repos/asf/nifi/blob/ade5dc9b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/anonymous/NiFiAnonymousUserFilter.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/anonymous/NiFiAnonymousUserFilter.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/anonymous/NiFiAnonymousUserFilter.java
index ed6e6a8..0c62825 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/anonymous/NiFiAnonymousUserFilter.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/anonymous/NiFiAnonymousUserFilter.java
@@ -50,10 +50,14 @@ public class NiFiAnonymousUserFilter extends AnonymousAuthenticationFilter {
         try {
             // load the anonymous user from the database
             NiFiUser user = userService.getUserByDn(NiFiUser.ANONYMOUS_USER_DN);
-            NiFiUserDetails userDetails = new NiFiUserDetails(user);
+            
+            // only create an authentication token if the anonymous user has some authorities
+            if (!user.getAuthorities().isEmpty()) {
+                NiFiUserDetails userDetails = new NiFiUserDetails(user);
 
-            // get the granted authorities
-            authentication = new NiFiAuthorizationToken(userDetails);
+                // get the granted authorities
+                authentication = new NiFiAuthorizationToken(userDetails);
+            }
         } catch (AdministrationException ase) {
             // record the issue
             anonymousUserFilterLogger.warn("Unable to load anonymous user from accounts database: " + ase.getMessage());
@@ -64,7 +68,10 @@ public class NiFiAnonymousUserFilter extends AnonymousAuthenticationFilter {
         return authentication;
     }
 
+    
+    
     /* setters */
+    
     public void setUserService(UserService userService) {
         this.userService = userService;
     }

http://git-wip-us.apache.org/repos/asf/nifi/blob/ade5dc9b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/form/LoginAuthenticationFilter.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/form/LoginAuthenticationFilter.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/form/LoginAuthenticationFilter.java
index 5b9e6e0..c759f7a 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/form/LoginAuthenticationFilter.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/form/LoginAuthenticationFilter.java
@@ -109,6 +109,12 @@ public class LoginAuthenticationFilter extends AbstractAuthenticationProcessingF
         }
     }
 
+    /**
+     * Ensures the proxyChain is authorized before allowing the user to be authenticated.
+     * 
+     * @param proxyChain the proxy chain
+     * @throws AuthenticationException if the proxy chain is not authorized
+     */
     private void authorizeProxyIfNecessary(final List<String> proxyChain) throws AuthenticationException {
         if (proxyChain.size() > 1) {
             try {
@@ -143,6 +149,11 @@ public class LoginAuthenticationFilter extends AbstractAuthenticationProcessingF
 
         // generate JWT for response
         jwtService.addToken(response, authentication);
+        
+        // mark as successful
+        response.setStatus(HttpServletResponse.SC_OK);
+        response.setContentType("text/plain");
+        response.setContentLength(0);
     }
 
     @Override
@@ -152,7 +163,7 @@ public class LoginAuthenticationFilter extends AbstractAuthenticationProcessingF
         response.setContentType("text/plain");
 
         final PrintWriter out = response.getWriter();
-        out.println("Invalid username/password");
+        out.println("Unable to authenticate.");
     }
 
     /**

http://git-wip-us.apache.org/repos/asf/nifi/blob/ade5dc9b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/jwt/JwtAuthenticationProvider.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/jwt/JwtAuthenticationProvider.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/jwt/JwtAuthenticationProvider.java
deleted file mode 100644
index ae459b0..0000000
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/jwt/JwtAuthenticationProvider.java
+++ /dev/null
@@ -1,47 +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.web.security.jwt;
-
-import org.apache.nifi.web.security.token.NewAccountAuthenticationRequestToken;
-import org.apache.nifi.web.security.token.NewAccountAuthenticationToken;
-import org.apache.nifi.web.security.token.NiFiAuthenticationRequestToken;
-import org.springframework.security.authentication.AuthenticationProvider;
-import org.springframework.security.core.Authentication;
-import org.springframework.security.core.AuthenticationException;
-
-/**
- *
- */
-public class JwtAuthenticationProvider implements AuthenticationProvider {
-
-    @Override
-    public Authentication authenticate(Authentication authentication) throws AuthenticationException {
-        if (NewAccountAuthenticationRequestToken.class.isAssignableFrom(authentication.getClass())) {
-            return new NewAccountAuthenticationToken(((NewAccountAuthenticationRequestToken) authentication).getNewAccountRequest());
-        } else if (NiFiAuthenticationRequestToken.class.isAssignableFrom(authentication.getClass())) {
-            return authentication;
-        } else {
-            return null;
-        }
-    }
-
-    @Override
-    public boolean supports(Class<?> authentication) {
-        return NiFiAuthenticationRequestToken.class.isAssignableFrom(authentication);
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/nifi/blob/ade5dc9b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/x509/X509AuthenticationProvider.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/x509/X509AuthenticationProvider.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/x509/X509AuthenticationProvider.java
deleted file mode 100644
index df23856..0000000
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/x509/X509AuthenticationProvider.java
+++ /dev/null
@@ -1,47 +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.web.security.x509;
-
-import org.apache.nifi.web.security.token.NewAccountAuthenticationRequestToken;
-import org.apache.nifi.web.security.token.NewAccountAuthenticationToken;
-import org.apache.nifi.web.security.token.NiFiAuthenticationRequestToken;
-import org.springframework.security.authentication.AuthenticationProvider;
-import org.springframework.security.core.Authentication;
-import org.springframework.security.core.AuthenticationException;
-
-/**
- *
- */
-public class X509AuthenticationProvider implements AuthenticationProvider {
-
-    @Override
-    public Authentication authenticate(Authentication authentication) throws AuthenticationException {
-        if (NewAccountAuthenticationRequestToken.class.isAssignableFrom(authentication.getClass())) {
-            return new NewAccountAuthenticationToken(((NewAccountAuthenticationRequestToken) authentication).getNewAccountRequest());
-        } else if (NiFiAuthenticationRequestToken.class.isAssignableFrom(authentication.getClass())) {
-            return authentication;
-        } else {
-            return null;
-        }
-    }
-
-    @Override
-    public boolean supports(Class<?> authentication) {
-        return NiFiAuthenticationRequestToken.class.isAssignableFrom(authentication);
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/nifi/blob/ade5dc9b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/resources/nifi-web-security-context.xml
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/resources/nifi-web-security-context.xml b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/resources/nifi-web-security-context.xml
index 5f4e1b2..52395c7 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/resources/nifi-web-security-context.xml
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/resources/nifi-web-security-context.xml
@@ -54,6 +54,12 @@
         </property>
     </bean>-->
 
+    <!-- certificate extractor -->
+    <bean id="certificateExtractor" class="org.apache.nifi.web.security.x509.X509CertificateExtractor"/>
+
+    <!-- principal extractor -->
+    <bean id="principalExtractor" class="org.apache.nifi.web.security.x509.SubjectDnX509PrincipalExtractor"/>
+        
     <!-- user details service -->
     <bean id="userDetailsService" class="org.apache.nifi.web.security.authorization.NiFiAuthorizationService">
         <property name="userService" ref="userService"/>

http://git-wip-us.apache.org/repos/asf/nifi/blob/ade5dc9b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/pom.xml b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/pom.xml
index c346a28..93a36f6 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/pom.xml
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/pom.xml
@@ -279,7 +279,6 @@
                                                 <include>${staging.dir}/js/nf/canvas/nf-snippet.js</include>
                                                 <include>${staging.dir}/js/nf/canvas/nf-canvas-toolbox.js</include>
                                                 <include>${staging.dir}/js/nf/canvas/nf-custom-ui.js</include>
-                                                <include>${staging.dir}/js/nf/canvas/nf-registration.js</include>
                                                 <include>${staging.dir}/js/nf/canvas/nf-controller-service.js</include>
                                                 <include>${staging.dir}/js/nf/canvas/nf-reporting-task.js</include>
                                                 <include>${staging.dir}/js/nf/canvas/nf-processor-configuration.js</include>
@@ -440,7 +439,6 @@
                                                 <include>${staging.dir}/css/connection-configuration.css</include>
                                                 <include>${staging.dir}/css/connection-details.css</include>
                                                 <include>${staging.dir}/css/shell.css</include>
-                                                <include>${staging.dir}/css/registration.css</include>
                                                 <include>${staging.dir}/css/dialog.css</include>
                                                 <include>${staging.dir}/css/new-processor-dialog.css</include>
                                                 <include>${staging.dir}/css/new-controller-service-dialog.css</include>

http://git-wip-us.apache.org/repos/asf/nifi/blob/ade5dc9b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/resources/filters/canvas.properties
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/resources/filters/canvas.properties b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/resources/filters/canvas.properties
index fd2bc17..fd5b7f2 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/resources/filters/canvas.properties
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/resources/filters/canvas.properties
@@ -23,7 +23,6 @@ nf.canvas.script.tags=<script type="text/javascript" src="js/nf/nf-namespace.js?
 <script type="text/javascript" src="js/nf/canvas/nf-snippet.js?${project.version}"></script>\n\
 <script type="text/javascript" src="js/nf/canvas/nf-canvas-toolbox.js?${project.version}"></script>\n\
 <script type="text/javascript" src="js/nf/canvas/nf-custom-ui.js?${project.version}"></script>\n\
-<script type="text/javascript" src="js/nf/canvas/nf-registration.js?${project.version}"></script>\n\
 <script type="text/javascript" src="js/nf/canvas/nf-controller-service.js?${project.version}"></script>\n\
 <script type="text/javascript" src="js/nf/canvas/nf-reporting-task.js?${project.version}"></script>\n\
 <script type="text/javascript" src="js/nf/canvas/nf-processor-configuration.js?${project.version}"></script>\n\

http://git-wip-us.apache.org/repos/asf/nifi/blob/ade5dc9b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/pages/canvas.jsp
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/pages/canvas.jsp b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/pages/canvas.jsp
index c81bb9d..dcfb47b 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/pages/canvas.jsp
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/pages/canvas.jsp
@@ -41,7 +41,6 @@
         <script type="text/javascript" src="js/jquery/jquery-2.1.1.min.js"></script>
         <script type="text/javascript" src="js/jquery/ui-smoothness/jquery-ui-1.10.4.min.js"></script>
         <script type="text/javascript" src="js/jquery/jquery.center.js"></script>
-        <script type="text/javascript" src="js/jquery/jquery.count.js"></script>
         <script type="text/javascript" src="js/jquery/jquery.ellipsis.js"></script>
         <script type="text/javascript" src="js/jquery/jquery.each.js"></script>
         <script type="text/javascript" src="js/jquery/jquery.tab.js"></script>
@@ -73,7 +72,6 @@
             <img id="splash-img" src="images/loadAnimation.gif" alt="Loading..."/>
         </div>
         <jsp:include page="/WEB-INF/partials/message-pane.jsp"/>
-        <jsp:include page="/WEB-INF/partials/canvas/registration.jsp"/>
         <jsp:include page="/WEB-INF/partials/banners-main.jsp"/>
         <jsp:include page="/WEB-INF/partials/canvas/canvas-header.jsp"/>
         <jsp:include page="/WEB-INF/partials/canvas/about-dialog.jsp"/>

http://git-wip-us.apache.org/repos/asf/nifi/blob/ade5dc9b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/pages/login.jsp
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/pages/login.jsp b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/pages/login.jsp
index 69c91e6..5cdce5b 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/pages/login.jsp
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/pages/login.jsp
@@ -27,6 +27,7 @@
         <link rel="stylesheet" href="js/jquery/qtip2/jquery.qtip.min.css?" type="text/css" />
         <link rel="stylesheet" href="js/jquery/ui-smoothness/jquery-ui-1.10.4.min.css" type="text/css" />
         <script type="text/javascript" src="js/jquery/jquery-2.1.1.min.js"></script>
+        <script type="text/javascript" src="js/jquery/jquery.count.js"></script>
         <script type="text/javascript" src="js/jquery/modal/jquery.modal.js?${project.version}"></script>
         <script type="text/javascript" src="js/jquery/qtip2/jquery.qtip.min.js"></script>
         <script type="text/javascript" src="js/jquery/ui-smoothness/jquery-ui-1.10.4.min.js"></script>
@@ -35,6 +36,8 @@
     </head>
     <body>
         <jsp:include page="/WEB-INF/partials/login/login-form.jsp"/>
-        <jsp:include page="/WEB-INF/partials/login/registration-form.jsp"/>
+        <jsp:include page="/WEB-INF/partials/login/user-registration-form.jsp"/>
+        <jsp:include page="/WEB-INF/partials/login/nifi-registration-form.jsp"/>
+        <jsp:include page="/WEB-INF/partials/login/login-submission.jsp"/>
     </body>
 </html>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/nifi/blob/ade5dc9b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/partials/canvas/registration.jsp
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/partials/canvas/registration.jsp b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/partials/canvas/registration.jsp
deleted file mode 100644
index 56b3236..0000000
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/partials/canvas/registration.jsp
+++ /dev/null
@@ -1,44 +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.
---%>
-<%@ page contentType="text/html" pageEncoding="UTF-8" session="false" %>
-<div id="registration-pane" class="message-pane hidden">
-    <div class="message-pane-message-box">
-        <p id="register-title" class="message-pane-title">You are not authorized to access this data flow</p>
-        <p id="register-content" class="message-pane-content">
-        <div>
-            <div id="expand-registration-button" class="collapsed pointer"></div>
-            <span id="expand-registration-text" class="link">Request Access</span>
-        </div>
-        <div id="registration-form" class="settings hidden">
-            <div class="setting">
-                <div class="setting-name">Justification</div>
-                <div class="setting-field">
-                    <textarea cols="30" rows="4" id="registration-justification" maxlength="500" name="registration-justification" class="setting-input"></textarea>
-                </div>
-                <div style="text-align: right; color: #666; margin-top: 2px;">
-                    <span id="remaining-characters"></span>&nbsp;characters remaining
-                </div>
-                <div class="clear"></div>
-            </div>
-            <div>
-                <div id="registration-form-submit" class="button">Submit</div>
-                <div class="clear"></div>
-            </div>
-        </div>
-        </p>
-    </div>
-</div>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/nifi/blob/ade5dc9b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/partials/login/login-form.jsp
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/partials/login/login-form.jsp b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/partials/login/login-form.jsp
index 889863e..2ee0a17 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/partials/login/login-form.jsp
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/partials/login/login-form.jsp
@@ -15,14 +15,11 @@
   limitations under the License.
 --%>
 <%@ page contentType="text/html" pageEncoding="UTF-8" session="false" %>
-<div id="login-form">
+<div id="login-container" class="hidden">
     <legend>Please Login</legend>
     <label for="username">Username</label>
     <input type="text" id="username" name="username" value="${username}"/>
     <br>
     <label for="password">Password</label>
     <input type="password" id="password" name="password"/>
-    <div class="form-actions">
-        <button id="login-button" type="submit" class="btn">Log in</button>
-    </div>
 </div>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/nifi/blob/ade5dc9b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/partials/login/login-submission.jsp
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/partials/login/login-submission.jsp b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/partials/login/login-submission.jsp
new file mode 100644
index 0000000..787bb56
--- /dev/null
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/partials/login/login-submission.jsp
@@ -0,0 +1,20 @@
+<%--
+ 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.
+--%>
+<%@ page contentType="text/html" pageEncoding="UTF-8" session="false" %>
+<div id="login-submission-container">
+    <button id="login-submission-button" type="submit" class="btn">Log in</button>
+</div>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/nifi/blob/ade5dc9b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/partials/login/nifi-registration-form.jsp
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/partials/login/nifi-registration-form.jsp b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/partials/login/nifi-registration-form.jsp
new file mode 100644
index 0000000..3d5f864
--- /dev/null
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/partials/login/nifi-registration-form.jsp
@@ -0,0 +1,31 @@
+<%--
+ 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.
+--%>
+<%@ page contentType="text/html" pageEncoding="UTF-8" session="false" %>
+<div id="nifi-registration-container" class="hidden">
+    <div id="nifi-registration-form" class="settings">
+        <div class="setting">
+            <div class="setting-name">Justification</div>
+            <div class="setting-field">
+                <textarea cols="30" rows="4" id="nifi-registration-justification" maxlength="500" class="setting-input"></textarea>
+            </div>
+            <div style="text-align: right; color: #666; margin-top: 2px;">
+                <span id="remaining-characters"></span>&nbsp;characters remaining
+            </div>
+            <div class="clear"></div>
+        </div>
+    </div>
+</div>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/nifi/blob/ade5dc9b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/partials/login/registration-form.jsp
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/partials/login/registration-form.jsp b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/partials/login/registration-form.jsp
deleted file mode 100644
index 56808e2..0000000
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/partials/login/registration-form.jsp
+++ /dev/null
@@ -1,19 +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.
---%>
-<%@ page contentType="text/html" pageEncoding="UTF-8" session="false" %>
-<div id="registration-form">
-</div>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/nifi/blob/ade5dc9b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/partials/login/user-registration-form.jsp
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/partials/login/user-registration-form.jsp b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/partials/login/user-registration-form.jsp
new file mode 100644
index 0000000..92382b3
--- /dev/null
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/partials/login/user-registration-form.jsp
@@ -0,0 +1,19 @@
+<%--
+ 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.
+--%>
+<%@ page contentType="text/html" pageEncoding="UTF-8" session="false" %>
+<div id="user-registration-container" class="hidden">
+</div>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/nifi/blob/ade5dc9b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/css/canvas.css
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/css/canvas.css b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/css/canvas.css
index 1c66609..e4cf89a 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/css/canvas.css
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/css/canvas.css
@@ -28,7 +28,6 @@
 @import url(connection-configuration.css);
 @import url(connection-details.css);
 @import url(shell.css);
-@import url(registration.css);
 @import url(dialog.css);
 @import url(new-processor-dialog.css);
 @import url(new-controller-service-dialog.css);

http://git-wip-us.apache.org/repos/asf/nifi/blob/ade5dc9b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/css/login.css
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/css/login.css b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/css/login.css
index 203f5b9..72f15f4 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/css/login.css
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/css/login.css
@@ -17,4 +17,21 @@
 
 /*
     Login Styles
-*/
\ No newline at end of file
+*/
+
+/*
+    NiFi Registration
+*/
+
+#nifi-registration-container {
+}
+
+#nifi-registration-form {
+    margin-top: 10px;
+    width: 610px;
+}
+
+#nifi-registration-justification {
+    width: 600px;
+    height: 200px;
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/nifi/blob/ade5dc9b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/css/registration.css
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/css/registration.css b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/css/registration.css
deleted file mode 100644
index d4fdc7e..0000000
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/css/registration.css
+++ /dev/null
@@ -1,45 +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.
- */
-/*
-    Registration form styles.
-*/
-
-#registration-pane {
-    z-index: 1299;
-}
-
-#registration-form {
-    margin-top: 10px;
-    width: 610px;
-}
-
-#expand-registration-button {
-    width: 10px;
-    height: 10px;
-    float: left;
-    margin-right: 5px;
-}
-
-#expand-registration-text {
-    -webkit-user-select: none;
-    -moz-user-select: none;
-}
-
-#registration-justification {
-    width: 600px;
-    height: 200px;
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/nifi/blob/ade5dc9b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-canvas.js
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-canvas.js b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-canvas.js
index 190c7a7..d2d9e82 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-canvas.js
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-canvas.js
@@ -57,12 +57,14 @@ nf.Canvas = (function () {
 
     var config = {
         urls: {
+            identity: '../nifi-api/controller/identity',
             authorities: '../nifi-api/controller/authorities',
             revision: '../nifi-api/controller/revision',
             status: '../nifi-api/controller/status',
             bulletinBoard: '../nifi-api/controller/bulletin-board',
             banners: '../nifi-api/controller/banners',
             controller: '../nifi-api/controller',
+            token: '../nifi-api/token',
             controllerConfig: '../nifi-api/controller/config',
             loginConfig: '../nifi-api/controller/login/config',
             cluster: '../nifi-api/cluster',
@@ -1027,10 +1029,58 @@ nf.Canvas = (function () {
          * Initialize NiFi.
          */
         init: function () {
-            // init the registration form before performing the first query since 
-            // the response could lead to a registration attempt
-            nf.Registration.init();
-
+            // get the current user's identity
+            var identityXhr = $.ajax({
+                type: 'GET',
+                url: config.urls.identity,
+                dataType: 'json'
+            });
+            
+            // get the current user's authorities
+            var authoritiesXhr = $.ajax({
+                type: 'GET',
+                url: config.urls.authorities,
+                dataType: 'json'
+            });
+            
+            
+            // load the identity and authorities for the current user
+            var userXhr = $.Deferred(function(deferred) {
+                $.when(authoritiesXhr, identityXhr).done(function (authoritiesResult, identityResult) {
+                    var authoritiesResponse = authoritiesResult[0];
+                    var identityResponse = identityResult[0];
+
+                    // set the user's authorities
+                    nf.Common.setAuthorities(authoritiesResponse.authorities);
+
+                    // at this point the user may be themselves or anonymous
+
+                    // if the user is logged, we want to determine if they were logged in using a certificate
+                    if (identityResponse.identity !== 'anonymous') {
+                        // attempt to get a token for the current user without passing login credentials
+                        $.ajax({
+                            type: 'GET',
+                            url: config.urls.token
+                        }).fail(function () {
+                            // if this request succeeds, it means the user is logged in using their certificate.
+                            // if this request fails, it means the user is logged in with login credentials so we want to render a logout button.
+                            // TODO - render logout button
+                        }).always(function () {
+                            deferred.resolve();
+                        });
+                    } else {
+                        deferred.resolve();
+                    }
+                }).fail(function (xhr, status, error) {
+                    // there is no anonymous access and we don't know this user - open the login page which handles login/registration/etc
+                    if (xhr.status === 401) {
+                        window.location = '/nifi/login';
+                    }
+                    
+                    deferred.reject(xhr, status, error);
+                });
+            }).promise();
+            
             // get the controller config to register the status poller
             var configXhr = $.ajax({
                 type: 'GET',
@@ -1044,7 +1094,7 @@ nf.Canvas = (function () {
                 url: config.urls.loginConfig,
                 dataType: 'json'
             });
-
+            
             // create the deferred cluster request
             var isClusteredRequest = $.Deferred(function (deferred) {
                 $.ajax({
@@ -1063,22 +1113,11 @@ nf.Canvas = (function () {
                 });
             }).promise();
 
-            // load the authorities
-            var authoritiesXhr = $.ajax({
-                type: 'GET',
-                url: config.urls.authorities,
-                dataType: 'json'
-            });
-
-            // ensure the authorities and config request is processed first
-            $.when(authoritiesXhr, configXhr, loginXhr).done(function (authoritiesResult, configResult, loginResult) {
-                var authoritiesResponse = authoritiesResult[0];
+            // ensure the config requests are loaded
+            $.when(configXhr, loginXhr, userXhr).done(function (configResult, loginResult) {
                 var configResponse = configResult[0];
                 var loginResponse = loginResult[0];
 
-                // set the user's authorities
-                nf.Common.setAuthorities(authoritiesResponse.authorities);
-
                 // calculate the canvas offset
                 var canvasContainer = $('#canvas-container');
                 nf.Canvas.CANVAS_OFFSET = canvasContainer.offset().top;

http://git-wip-us.apache.org/repos/asf/nifi/blob/ade5dc9b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-registration.js
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-registration.js b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-registration.js
deleted file mode 100644
index b678e27..0000000
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-registration.js
+++ /dev/null
@@ -1,71 +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.
- */
-
-/* global nf */
-
-nf.Registration = (function () {
-
-    var config = {
-        urls: {
-            users: '../nifi-api/controller/users'
-        }
-    };
-
-    return {
-        /**
-         * Initializes the user account registration form.
-         */
-        init: function () {
-            $('#registration-justification').count({
-                charCountField: '#remaining-characters'
-            });
-
-            // register a click listener to expand/collapse the registration form
-            $('#expand-registration-button, #expand-registration-text').click(function () {
-                var registrationForm = $('#registration-form');
-                if (registrationForm.is(':visible')) {
-                    $('#expand-registration-button').removeClass('registration-expanded').addClass('collapsed');
-                } else {
-                    $('#expand-registration-button').removeClass('registration-collapsed').addClass('expanded');
-                }
-                registrationForm.toggle();
-            });
-
-            // register a click listener for submitting user account requests
-            $('#registration-form-submit').one('click', function () {
-                var justification = $('#registration-justification').val();
-
-                // attempt to create the user account registration
-                $.ajax({
-                    type: 'POST',
-                    url: config.urls.users,
-                    data: {
-                        'justification': justification
-                    }
-                }).done(function (response) {
-                    // hide the registration pane
-                    $('#registration-pane').hide();
-
-                    // show the message pane
-                    $('#message-pane').show();
-                    $('#message-title').text('Thanks');
-                    $('#message-content').text('Your request will be processed shortly.');
-                }).fail(nf.Common.handleAjaxError);
-            });
-        }
-    };
-}());
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/nifi/blob/ade5dc9b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/login/nf-login.js
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/login/nf-login.js b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/login/nf-login.js
index 345d794..1630683 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/login/nf-login.js
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/login/nf-login.js
@@ -22,28 +22,54 @@ $(document).ready(function () {
 });
 
 nf.Login = (function () {
-    var loadControllerConfiguration = function () {
+    
+    var config = {
+        urls: {
+            identity: '../nifi-api/controller/identity',
+            users: '../nifi-api/controller/users',
+            token: '../nifi-api/token',
+            loginConfig: '../nifi-api/controller/login/config'
+        }
+    };
+
+    var initializeLogin = function () {
         return $.ajax({
             type: 'GET',
-            url: '../nifi-api/controller/login/config',
+            url: config.urls.loginConfig,
             dataType: 'json'
-        });
-    };
-
-    var initializePage = function () {
-        return loadControllerConfiguration().done(function (response) {
+        }).done(function (response) {
             var config = response.config;
             
+            // if this nifi supports login, render the login form
             if (config.supportsLogin === true) {
                 
+                // handle login click
+                $('#login-button').on('click', function () {
+                    login().done(function (response) {
+                       console.log(response); 
+                    });
+                });
+                
+                // show the login form
+                $('#login-container').show();
             }
             
-            if (config.supportsRegistration === true) {
+            // if this nifi supports registration, render the registration form
+            if (config.supportsRegistration === false) {
+                initializeUserRegistration();
                 
+                // automatically include support for nifi registration
+                initializeNiFiRegistration();
             }
         });
     };
     
+    var initializeUserRegistration = function () {
+        
+        // show the user registration form
+        $('#user-registration-container').show();
+    };
+    
     var login = function () {
         var username = $('#username').val();
         var password = $('#password').val();
@@ -58,19 +84,109 @@ nf.Login = (function () {
             dataType: 'json'
         });
     };
+    
+    var initializeNiFiRegistration = function () {
+        $('#nifi-registration-justification').count({
+            charCountField: '#remaining-characters'
+        });
+
+        // show the nifi registration container
+        $('#nifi-registration-container').show();
+    };
+    
+    var initializeSubmission = function () {
+        $('#login-submission-button').one('click', function () {
+            if ($('#login-container').is(':visible')) {
+                // login submit
+            } else if ($('#user-registration-container').is(':visible')) {
+                // new user account submit
+            } else if ($('#nifi-registration-container').is(':visible')) {
+                // new nifi account submit
+                var justification = $('#registration-justification').val();
+
+                // attempt to create the user account registration
+                $.ajax({
+                    type: 'POST',
+                    url: config.urls.users,
+                    data: {
+                        'justification': justification
+                    }
+                }).done(function (response) {
+                    // TODO
+    //                // hide the registration pane
+    //                $('#registration-pane').hide();
+    //
+    //                // show the message pane
+    //                $('#message-pane').show();
+    //                $('#message-title').text('Thanks');
+    //                $('#message-content').text('Your request will be processed shortly.');
+                }).fail(nf.Common.handleAjaxError);
+            }
+        });
+    };
 
     return {
         /**
          * Initializes the login page.
          */
         init: function () {
-            initializePage();
+            var needsLogin = false;
+            var needsNiFiRegistration = false;
+            
+            var token = $.ajax({
+                type: 'GET',
+                url: config.urls.token
+            });
             
-            // handle login click
-            $('#login-button').on('click', function () {
-                login().done(function (response) {
-                   console.log(response); 
+            var pageStateInit = $.Deferred(function(deferred) {
+                // get the current user's identity
+                $.ajax({
+                    type: 'GET',
+                    url: config.urls.identity,
+                    dataType: 'json'
+                }).done(function (response) {
+                    var identity = response.identity;
+
+                    // if the user is anonymous they need to login
+                    if (identity === 'anonymous') {
+                        token.done(function () {
+                            // anonymous user and 200 from token means they have a certificate but have not yet requested an account
+                            needsNiFiRegistration = true;
+                        }).fail(function (xhr, status, error) {
+                            // no token granted, user needs to login with their credentials
+                            needsLogin = true;
+                        });
+                    }
+                }).fail(function (xhr, status, error) {
+                    if (xhr.status === 401) {
+                        // attempt to get a token for the current user without passing login credentials
+                        token.done(function () {
+                            // 401 from identity request and 200 from token means they have a certificate but have not yet requested an account 
+                            needsNiFiRegistration = true;
+                        }).fail(function (xhr, status, error) {
+                            // no token granted, user needs to login with their credentials
+                            needsLogin = true;
+                        });
+                    } else if (xhr.status === 403) {
+                        // the user is logged in with certificate or credentials but their account is still pending. error message should indicate
+                        // TODO - show error
+                    }
+                }).always(function () {
+                    deferred.resolve();
                 });
+            }).promise();
+            
+            // render the page accordingly
+            $.when(pageStateInit).done(function () {
+                if (needsLogin === true) {
+                    initializeLogin();
+                } else if (needsNiFiRegistration === true) {
+                    initializeNiFiRegistration();
+                }
+                
+                if (needsLogin === true || needsNiFiRegistration === true) {
+                    initializeSubmission();
+                }
             });
         }
     };

http://git-wip-us.apache.org/repos/asf/nifi/blob/ade5dc9b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/nf-common.js
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/nf-common.js b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/nf-common.js
index 06c34f9..642bc31 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/nf-common.js
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/nf-common.js
@@ -185,14 +185,14 @@ nf.Common = {
      */
     handleAjaxError: function (xhr, status, error) {
         // show the account registration page if necessary
-        if (xhr.status === 401 && $('#registration-pane').length) {
-            // show the registration pane
-            $('#registration-pane').show();
-
-            // close the canvas
-            nf.Common.closeCanvas();
-            return;
-        }
+//        if (xhr.status === 401 && $('#registration-pane').length) {
+//            // show the registration pane
+//            $('#registration-pane').show();
+//
+//            // close the canvas
+//            nf.Common.closeCanvas();
+//            return;
+//        }
         
         // if an error occurs while the splash screen is visible close the canvas show the error message
         if ($('#splash').is(':visible')) {


[2/2] nifi git commit: NIFI-655: - Addressing checkstyle issues.

Posted by mc...@apache.org.
NIFI-655:
- Addressing checkstyle issues.

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

Branch: refs/heads/NIFI-655
Commit: 5e341214a61519eff53596782e78eb1b82a32da6
Parents: ade5dc9
Author: Matt Gilman <ma...@gmail.com>
Authored: Mon Nov 2 14:54:51 2015 -0500
Committer: Matt Gilman <ma...@gmail.com>
Committed: Mon Nov 2 14:54:51 2015 -0500

----------------------------------------------------------------------
 .../org/apache/nifi/web/NiFiWebApiSecurityConfiguration.java    | 1 -
 .../apache/nifi/web/security/NiFiAuthenticationEntryPoint.java  | 2 +-
 .../nifi/web/security/anonymous/NiFiAnonymousUserFilter.java    | 5 +----
 .../nifi/web/security/form/LoginAuthenticationFilter.java       | 4 ++--
 4 files changed, 4 insertions(+), 8 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/nifi/blob/5e341214/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/NiFiWebApiSecurityConfiguration.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/NiFiWebApiSecurityConfiguration.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/NiFiWebApiSecurityConfiguration.java
index 7bafce0..b004ff0 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/NiFiWebApiSecurityConfiguration.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/NiFiWebApiSecurityConfiguration.java
@@ -33,7 +33,6 @@ import org.apache.nifi.web.security.x509.ocsp.OcspCertificateValidator;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
-import org.springframework.http.HttpMethod;
 import org.springframework.security.authentication.AuthenticationManager;
 import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
 import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;

http://git-wip-us.apache.org/repos/asf/nifi/blob/5e341214/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/NiFiAuthenticationEntryPoint.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/NiFiAuthenticationEntryPoint.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/NiFiAuthenticationEntryPoint.java
index ab8951b..ef1dfb2 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/NiFiAuthenticationEntryPoint.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/NiFiAuthenticationEntryPoint.java
@@ -40,7 +40,7 @@ public class NiFiAuthenticationEntryPoint implements AuthenticationEntryPoint {
     public NiFiAuthenticationEntryPoint(NiFiProperties properties) {
         this.properties = properties;
     }
-    
+
     /**
      * Always returns a 403 error code to the client.
      *

http://git-wip-us.apache.org/repos/asf/nifi/blob/5e341214/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/anonymous/NiFiAnonymousUserFilter.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/anonymous/NiFiAnonymousUserFilter.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/anonymous/NiFiAnonymousUserFilter.java
index 0c62825..7ffd673 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/anonymous/NiFiAnonymousUserFilter.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/anonymous/NiFiAnonymousUserFilter.java
@@ -50,7 +50,7 @@ public class NiFiAnonymousUserFilter extends AnonymousAuthenticationFilter {
         try {
             // load the anonymous user from the database
             NiFiUser user = userService.getUserByDn(NiFiUser.ANONYMOUS_USER_DN);
-            
+
             // only create an authentication token if the anonymous user has some authorities
             if (!user.getAuthorities().isEmpty()) {
                 NiFiUserDetails userDetails = new NiFiUserDetails(user);
@@ -68,10 +68,7 @@ public class NiFiAnonymousUserFilter extends AnonymousAuthenticationFilter {
         return authentication;
     }
 
-    
-    
     /* setters */
-    
     public void setUserService(UserService userService) {
         this.userService = userService;
     }

http://git-wip-us.apache.org/repos/asf/nifi/blob/5e341214/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/form/LoginAuthenticationFilter.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/form/LoginAuthenticationFilter.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/form/LoginAuthenticationFilter.java
index c759f7a..c8556d0 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/form/LoginAuthenticationFilter.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/form/LoginAuthenticationFilter.java
@@ -111,7 +111,7 @@ public class LoginAuthenticationFilter extends AbstractAuthenticationProcessingF
 
     /**
      * Ensures the proxyChain is authorized before allowing the user to be authenticated.
-     * 
+     *
      * @param proxyChain the proxy chain
      * @throws AuthenticationException if the proxy chain is not authorized
      */
@@ -149,7 +149,7 @@ public class LoginAuthenticationFilter extends AbstractAuthenticationProcessingF
 
         // generate JWT for response
         jwtService.addToken(response, authentication);
-        
+
         // mark as successful
         response.setStatus(HttpServletResponse.SC_OK);
         response.setContentType("text/plain");