Repository: nifi
Updated Branches:
  refs/heads/NIFI-655 71d84117e -> ed27ed044


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

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

Branch: refs/heads/NIFI-655
Commit: ed27ed04498bd6f0f5c3b65c403aaca19954286a
Parents: 71d8411
Author: Matt Gilman <matt.c.gil...@gmail.com>
Authored: Tue Nov 3 12:45:37 2015 -0500
Committer: Matt Gilman <matt.c.gil...@gmail.com>
Committed: Tue Nov 3 12:45:37 2015 -0500

----------------------------------------------------------------------
 .../web/NiFiWebApiSecurityConfiguration.java    |   2 +
 .../web/security/RegistrationStatusFilter.java  |  16 +-
 .../form/LoginAuthenticationFilter.java         |   4 +
 .../security/jwt/JwtAuthenticationFilter.java   |  48 +++-
 .../webapp/js/nf/canvas/nf-canvas-header.js     |   4 +-
 .../src/main/webapp/js/nf/canvas/nf-canvas.js   | 218 ++++++++++---------
 .../src/main/webapp/js/nf/login/nf-login.js     |   7 +-
 7 files changed, 181 insertions(+), 118 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/nifi/blob/ed27ed04/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 d6feef0..649f412 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
@@ -156,6 +156,8 @@ public class NiFiWebApiSecurityConfiguration extends 
WebSecurityConfigurerAdapte
         final JwtAuthenticationFilter jwtFilter = new 
JwtAuthenticationFilter();
         jwtFilter.setProperties(properties);
         jwtFilter.setJwtService(jwtService);
+        jwtFilter.setCertificateExtractor(certificateExtractor);
+        jwtFilter.setPrincipalExtractor(principalExtractor);
         jwtFilter.setAuthenticationManager(authenticationManager());
         return jwtFilter;
     }

http://git-wip-us.apache.org/repos/asf/nifi/blob/ed27ed04/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/RegistrationStatusFilter.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/RegistrationStatusFilter.java
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/RegistrationStatusFilter.java
index 073de67..d2ffdc2 100644
--- 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/RegistrationStatusFilter.java
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/RegistrationStatusFilter.java
@@ -19,6 +19,8 @@ package org.apache.nifi.web.security;
 import java.io.IOException;
 import java.io.PrintWriter;
 import java.security.cert.X509Certificate;
+import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.List;
 import javax.servlet.FilterChain;
 import javax.servlet.ServletException;
@@ -75,17 +77,27 @@ public class RegistrationStatusFilter extends 
AbstractAuthenticationProcessingFi
         if (certificate == null) {
             final LoginCredentials credentials = getLoginCredentials(request);
             
+            // ensure we have something we can work with (certificate or 
crendentials)
             if (credentials == null) {
                 throw new BadCredentialsException("Unable to check 
registration status as no credentials were included with the request.");
             }
             
-            checkAuthorization(ProxiedEntitiesUtils.buildProxyChain(request, 
credentials.getUsername()));
+            // without a certificate, this is not a proxied request
+            final List<String> chain = 
Arrays.asList(credentials.getUsername());
+            
+            // check authorization for this user
+            checkAuthorization(chain);
+            
+            // no issues with authorization
             return new RegistrationStatusAuthenticationToken(credentials);
         } else {
-            // we have a certificate so let's use that
+            // TODO - certificate validation
+            
+            // we have a certificate so let's consider a proxy chain
             final String principal = extractPrincipal(certificate);
             checkAuthorization(ProxiedEntitiesUtils.buildProxyChain(request, 
principal));
 
+            // no issues with authorization
             final LoginCredentials preAuthenticatedCredentials = new 
LoginCredentials(principal, null);
             return new 
RegistrationStatusAuthenticationToken(preAuthenticatedCredentials);
         }

http://git-wip-us.apache.org/repos/asf/nifi/blob/ed27ed04/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 c8556d0..fcff545 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
@@ -83,6 +83,8 @@ public class LoginAuthenticationFilter extends 
AbstractAuthenticationProcessingF
             if (certificate == null) {
                 throw new PreAuthenticatedCredentialsNotFoundException("Unable 
to extract client certificate after processing request with no login 
credentials specified.");
             }
+            
+            // TODO - certificate validation
 
             // authorize the proxy if necessary
             final String principal = extractPrincipal(certificate);
@@ -96,6 +98,8 @@ public class LoginAuthenticationFilter extends 
AbstractAuthenticationProcessingF
 
             // if there was a certificate with this request see if it was 
proxying an end user request
             if (certificate != null) {
+                // TODO - certificate validation
+                
                 // authorize the proxy if necessary
                 final String principal = extractPrincipal(certificate);
                 
authorizeProxyIfNecessary(ProxiedEntitiesUtils.buildProxyChain(request, 
principal));

http://git-wip-us.apache.org/repos/asf/nifi/blob/ed27ed04/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/jwt/JwtAuthenticationFilter.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/JwtAuthenticationFilter.java
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/jwt/JwtAuthenticationFilter.java
index 380289d..b02a2a3 100644
--- 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/jwt/JwtAuthenticationFilter.java
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/jwt/JwtAuthenticationFilter.java
@@ -16,6 +16,8 @@
  */
 package org.apache.nifi.web.security.jwt;
 
+import java.security.cert.X509Certificate;
+import java.util.Arrays;
 import java.util.List;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
@@ -24,9 +26,12 @@ import org.apache.nifi.web.security.ProxiedEntitiesUtils;
 import org.apache.nifi.web.security.token.NewAccountAuthenticationRequestToken;
 import org.apache.nifi.web.security.token.NiFiAuthenticationRequestToken;
 import org.apache.nifi.web.security.user.NewAccountRequest;
+import org.apache.nifi.web.security.x509.X509CertificateExtractor;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
+import org.springframework.security.authentication.BadCredentialsException;
 import org.springframework.security.core.Authentication;
+import 
org.springframework.security.web.authentication.preauth.x509.X509PrincipalExtractor;
 
 /**
  */
@@ -34,6 +39,8 @@ public class JwtAuthenticationFilter extends 
NiFiAuthenticationFilter {
 
     private static final Logger logger = 
LoggerFactory.getLogger(JwtAuthenticationFilter.class);
 
+    private X509CertificateExtractor certificateExtractor;
+    private X509PrincipalExtractor principalExtractor;
     private JwtService jwtService;
 
     @Override
@@ -43,16 +50,39 @@ public class JwtAuthenticationFilter extends 
NiFiAuthenticationFilter {
             return null;
         }
 
-        final String principal = jwtService.getAuthentication(request);
-        if (principal == null) {
+        // get the principal out of the user token
+        final String jwtPrincipal = jwtService.getAuthentication(request);
+        if (jwtPrincipal == null) {
             return null;
         }
 
-        final List<String> proxyChain = 
ProxiedEntitiesUtils.buildProxyChain(request, principal);
+        // look for a certificate
+        final X509Certificate certificate = 
certificateExtractor.extractClientCertificate(request);
+
+        final List<String> chain;
+        if (certificate == null) {
+            // without a certificate, this is not a proxied request
+            chain = Arrays.asList(jwtPrincipal);
+        } else {
+            // TODO - certificate validation
+
+            // extract the principal
+            Object certificatePrincipal = 
principalExtractor.extractPrincipal(certificate);
+            final String principal = 
ProxiedEntitiesUtils.formatProxyDn(certificatePrincipal.toString());
+
+            // get the proxy chain and verify the principal is found
+            chain = ProxiedEntitiesUtils.buildProxyChain(request, principal);
+
+            // ensure the chain contains the jwt principal
+            if (!chain.contains(jwtPrincipal)) {
+                throw new BadCredentialsException("Principal in user token not 
found in the proxy chain.");
+            }
+        }
+
         if (isNewAccountRequest(request)) {
-            return new NewAccountAuthenticationRequestToken(new 
NewAccountRequest(proxyChain, getJustification(request)));
+            return new NewAccountAuthenticationRequestToken(new 
NewAccountRequest(chain, getJustification(request)));
         } else {
-            return new NiFiAuthenticationRequestToken(proxyChain);
+            return new NiFiAuthenticationRequestToken(chain);
         }
     }
 
@@ -60,4 +90,12 @@ public class JwtAuthenticationFilter extends 
NiFiAuthenticationFilter {
         this.jwtService = jwtService;
     }
 
+    public void setCertificateExtractor(X509CertificateExtractor 
certificateExtractor) {
+        this.certificateExtractor = certificateExtractor;
+    }
+
+    public void setPrincipalExtractor(X509PrincipalExtractor 
principalExtractor) {
+        this.principalExtractor = principalExtractor;
+    }
+
 }

http://git-wip-us.apache.org/repos/asf/nifi/blob/ed27ed04/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-canvas-header.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-header.js
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-canvas-header.js
index 551f33e..9ae3f4e 100644
--- 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-canvas-header.js
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-canvas-header.js
@@ -139,7 +139,9 @@ nf.CanvasHeader = (function () {
                 nf.Shell.showPage(config.urls.helpDocument);
             });
 
-            if (supportsLogin === true) {
+            // show the login link if supported and user is currently anonymous
+            var isAnonymous = $('#current-user').text() === 'anonymous';
+            if (supportsLogin === true && isAnonymous) {
                 // login link
                 $('#login-link').click(function () {
                     nf.Shell.showPage('login', false);

http://git-wip-us.apache.org/repos/asf/nifi/blob/ed27ed04/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 28359d7..1906620 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
@@ -1076,121 +1076,123 @@ nf.Canvas = (function () {
                     // 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',
-                url: config.urls.controllerConfig,
-                dataType: 'json'
-            });
-            
-            // get the login config
-            var loginXhr = $.ajax({
-                type: 'GET',
-                url: config.urls.loginConfig,
-                dataType: 'json'
-            });
-            
-            // create the deferred cluster request
-            var isClusteredRequest = $.Deferred(function (deferred) {
-                $.ajax({
-                    type: 'HEAD',
-                    url: config.urls.cluster
-                }).done(function (response, status, xhr) {
-                    clustered = true;
-                    deferred.resolve(response, status, xhr);
-                }).fail(function (xhr, status, error) {
-                    if (xhr.status === 404) {
-                        clustered = false;
-                        deferred.resolve('', 'success', xhr);
                     } else {
                         deferred.reject(xhr, status, error);
                     }
                 });
             }).promise();
+            
+            userXhr.done(function () {
+                // get the controller config to register the status poller
+                var configXhr = $.ajax({
+                    type: 'GET',
+                    url: config.urls.controllerConfig,
+                    dataType: 'json'
+                });
 
-            // ensure the config requests are loaded
-            $.when(configXhr, loginXhr, userXhr).done(function (configResult, 
loginResult) {
-                var configResponse = configResult[0];
-                var loginResponse = loginResult[0];
+                // get the login config
+                var loginXhr = $.ajax({
+                    type: 'GET',
+                    url: config.urls.loginConfig,
+                    dataType: 'json'
+                });
 
-                // calculate the canvas offset
-                var canvasContainer = $('#canvas-container');
-                nf.Canvas.CANVAS_OFFSET = canvasContainer.offset().top;
-
-                // get the config details
-                var configDetails = configResponse.config;
-                var loginDetails = loginResponse.config;
-
-                // when both request complete, load the application
-                isClusteredRequest.done(function () {
-                    // get the auto refresh interval
-                    var autoRefreshIntervalSeconds = 
parseInt(configDetails.autoRefreshIntervalSeconds, 10);
-
-                    // initialize whether site to site is secure
-                    secureSiteToSite = configDetails.siteToSiteSecure;
-
-                    // load d3
-                    loadD3().done(function () {
-                        nf.Storage.init();
-
-                        // initialize the application
-                        initCanvas();
-                        nf.Canvas.View.init();
-                        nf.ContextMenu.init();
-                        nf.CanvasToolbar.init();
-                        nf.CanvasToolbox.init();
-                        nf.CanvasHeader.init(loginDetails.supportsLogin);
-                        nf.GraphControl.init();
-                        nf.Search.init();
-                        nf.Settings.init();
-
-                        // initialize the component behaviors
-                        nf.Draggable.init();
-                        nf.Selectable.init();
-                        nf.Connectable.init();
-
-                        // initialize the chart
-                        nf.StatusHistory.init(configDetails.timeOffset);
-
-                        // initialize the birdseye
-                        nf.Birdseye.init();
-
-                        // initialize components
-                        nf.ConnectionConfiguration.init();
-                        nf.ControllerService.init();
-                        nf.ReportingTask.init();
-                        nf.ProcessorConfiguration.init();
-                        nf.ProcessGroupConfiguration.init();
-                        nf.RemoteProcessGroupConfiguration.init();
-                        nf.RemoteProcessGroupPorts.init();
-                        nf.PortConfiguration.init();
-                        nf.SecurePortConfiguration.init();
-                        nf.LabelConfiguration.init();
-                        nf.ProcessorDetails.init();
-                        nf.ProcessGroupDetails.init();
-                        nf.PortDetails.init();
-                        nf.SecurePortDetails.init();
-                        nf.ConnectionDetails.init();
-                        nf.RemoteProcessGroupDetails.init();
-                        nf.GoTo.init();
-                        nf.Graph.init().done(function () {
-                            // determine the split between the polling
-                            var pollingSplit = autoRefreshIntervalSeconds / 2;
-
-                            // register the revision and status polling
-                            startRevisionPolling(autoRefreshIntervalSeconds);
-                            setTimeout(function () {
-                                startStatusPolling(autoRefreshIntervalSeconds);
-                            }, pollingSplit * 1000);
-
-                            // hide the splash screen
-                            nf.Canvas.hideSplash();
+                // create the deferred cluster request
+                var isClusteredRequest = $.Deferred(function (deferred) {
+                    $.ajax({
+                        type: 'HEAD',
+                        url: config.urls.cluster
+                    }).done(function (response, status, xhr) {
+                        clustered = true;
+                        deferred.resolve(response, status, xhr);
+                    }).fail(function (xhr, status, error) {
+                        if (xhr.status === 404) {
+                            clustered = false;
+                            deferred.resolve('', 'success', xhr);
+                        } else {
+                            deferred.reject(xhr, status, error);
+                        }
+                    });
+                }).promise();
+                
+                // ensure the config requests are loaded
+                $.when(configXhr, loginXhr, userXhr).done(function 
(configResult, loginResult) {
+                    var configResponse = configResult[0];
+                    var loginResponse = loginResult[0];
+
+                    // calculate the canvas offset
+                    var canvasContainer = $('#canvas-container');
+                    nf.Canvas.CANVAS_OFFSET = canvasContainer.offset().top;
+
+                    // get the config details
+                    var configDetails = configResponse.config;
+                    var loginDetails = loginResponse.config;
+
+                    // when both request complete, load the application
+                    isClusteredRequest.done(function () {
+                        // get the auto refresh interval
+                        var autoRefreshIntervalSeconds = 
parseInt(configDetails.autoRefreshIntervalSeconds, 10);
+
+                        // initialize whether site to site is secure
+                        secureSiteToSite = configDetails.siteToSiteSecure;
+
+                        // load d3
+                        loadD3().done(function () {
+                            nf.Storage.init();
+
+                            // initialize the application
+                            initCanvas();
+                            nf.Canvas.View.init();
+                            nf.ContextMenu.init();
+                            nf.CanvasToolbar.init();
+                            nf.CanvasToolbox.init();
+                            nf.CanvasHeader.init(loginDetails.supportsLogin);
+                            nf.GraphControl.init();
+                            nf.Search.init();
+                            nf.Settings.init();
+
+                            // initialize the component behaviors
+                            nf.Draggable.init();
+                            nf.Selectable.init();
+                            nf.Connectable.init();
+
+                            // initialize the chart
+                            nf.StatusHistory.init(configDetails.timeOffset);
+
+                            // initialize the birdseye
+                            nf.Birdseye.init();
+
+                            // initialize components
+                            nf.ConnectionConfiguration.init();
+                            nf.ControllerService.init();
+                            nf.ReportingTask.init();
+                            nf.ProcessorConfiguration.init();
+                            nf.ProcessGroupConfiguration.init();
+                            nf.RemoteProcessGroupConfiguration.init();
+                            nf.RemoteProcessGroupPorts.init();
+                            nf.PortConfiguration.init();
+                            nf.SecurePortConfiguration.init();
+                            nf.LabelConfiguration.init();
+                            nf.ProcessorDetails.init();
+                            nf.ProcessGroupDetails.init();
+                            nf.PortDetails.init();
+                            nf.SecurePortDetails.init();
+                            nf.ConnectionDetails.init();
+                            nf.RemoteProcessGroupDetails.init();
+                            nf.GoTo.init();
+                            nf.Graph.init().done(function () {
+                                // determine the split between the polling
+                                var pollingSplit = autoRefreshIntervalSeconds 
/ 2;
+
+                                // register the revision and status polling
+                                
startRevisionPolling(autoRefreshIntervalSeconds);
+                                setTimeout(function () {
+                                    
startStatusPolling(autoRefreshIntervalSeconds);
+                                }, pollingSplit * 1000);
+
+                                // hide the splash screen
+                                nf.Canvas.hideSplash();
+                            }).fail(nf.Common.handleAjaxError);
                         }).fail(nf.Common.handleAjaxError);
                     }).fail(nf.Common.handleAjaxError);
                 }).fail(nf.Common.handleAjaxError);

http://git-wip-us.apache.org/repos/asf/nifi/blob/ed27ed04/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 45ef691..9bc3264 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
@@ -231,6 +231,8 @@ nf.Login = (function () {
                         }).fail(function () {
                             // no token granted, user needs to login with 
their credentials
                             needsLogin = true;
+                        }).always(function () {
+                            deferred.resolve();
                         });
                     } else {
                         showMessage = true;
@@ -241,13 +243,14 @@ nf.Login = (function () {
                         } else {
                             $('#login-message').text(xhr.responseText);
                         }
+                        
+                        deferred.resolve();
                     }
-                    deferred.resolve();
                 });
             }).promise();
             
             // render the page accordingly
-            $.when(pageStateInit).done(function () {
+            pageStateInit.done(function () {
                 if (showMessage === true) {
                     initializeMessage();
                 } else if (needsLogin === true) {

Reply via email to