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 3d7544e29f..7d1b02bdfd 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 @@ -88,16 +88,15 @@ public class NiFiWebApiSecurityConfiguration extends WebSecurityConfigurerAdapte .sessionManagement() .sessionCreationPolicy(SessionCreationPolicy.STATELESS); - // verify that login authentication is enabled if (loginIdentityProvider != null) { - // login authentication for /token - exchanges for JWT for subsequent API usage - http.addFilterBefore(buildLoginFilter("/token"), UsernamePasswordAuthenticationFilter.class); - // verify the configured login authenticator supports user login registration if (loginIdentityProvider.supportsRegistration()) { http.addFilterBefore(buildRegistrationFilter("/registration"), UsernamePasswordAuthenticationFilter.class); } } + + // login authentication for /token - exchanges for JWT for subsequent API usage + http.addFilterBefore(buildLoginFilter("/token"), UsernamePasswordAuthenticationFilter.class); // registration status - will check the status of a user's account registration (regardless if its based on login or not) http.addFilterBefore(buildRegistrationStatusFilter("/registration/status"), UsernamePasswordAuthenticationFilter.class); @@ -111,8 +110,10 @@ public class NiFiWebApiSecurityConfiguration extends WebSecurityConfigurerAdapte // x509 http.addFilterAfter(buildX509Filter(), AnonymousAuthenticationFilter.class); - // jwt - http.addFilterAfter(buildJwtFilter(), AnonymousAuthenticationFilter.class); + // jwt - consider when configured for log in + if (loginIdentityProvider != null) { + http.addFilterAfter(buildJwtFilter(), AnonymousAuthenticationFilter.class); + } } @Bean 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 456a2b2f65..2c10863b2c 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 @@ -86,6 +86,11 @@ public class LoginAuthenticationFilter extends AbstractAuthenticationProcessingF // if there is no certificate, look for an existing token if (certificate == null) { + // if not configured for login, don't consider existing tokens + if (loginIdentityProvider == null) { + throw new BadCredentialsException("Login not supported."); + } + final String principal = jwtService.getAuthentication(request); if (principal == null) { @@ -129,6 +134,11 @@ public class LoginAuthenticationFilter extends AbstractAuthenticationProcessingF return new LoginAuthenticationToken(preAuthenticatedCredentials); } } else { + // if not configuration for login, don't consider credentials + if (loginIdentityProvider == null) { + throw new BadCredentialsException("Login not supported."); + } + if (loginIdentityProvider.authenticate(credentials)) { return new LoginAuthenticationToken(credentials); } else { 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/RegistrationFilter.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/form/RegistrationFilter.java index 39adb6892e..68d738371a 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/form/RegistrationFilter.java +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/form/RegistrationFilter.java @@ -120,11 +120,6 @@ public class RegistrationFilter extends AbstractAuthenticationProcessingFilter { // generate JWT for response jwtService.addToken(response, authentication); - - // mark as successful - response.setStatus(HttpServletResponse.SC_CREATED); - response.setContentType("text/plain"); - response.setContentLength(0); } @Override 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 e2b7b9b127..a4967b1f3e 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 @@ -37,6 +37,9 @@ ${nf.login.script.tags} +
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/pages/message-page.jsp b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/pages/message-page.jsp index 796877fba2..b0ba026e69 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/pages/message-page.jsp +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/pages/message-page.jsp @@ -27,8 +27,8 @@
-

<%= request.getAttribute("title") == null ? "" : org.apache.nifi.util.EscapeUtils.escapeHtml(request.getAttribute("title").toString()) %>

-

<%= request.getAttribute("messages") == null ? "" : org.apache.nifi.util.EscapeUtils.escapeHtml(request.getAttribute("messages").toString()) %>

+
<%= request.getAttribute("title") == null ? "" : org.apache.nifi.util.EscapeUtils.escapeHtml(request.getAttribute("title").toString()) %>
+
<%= request.getAttribute("messages") == null ? "" : org.apache.nifi.util.EscapeUtils.escapeHtml(request.getAttribute("messages").toString()) %>
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/partials/canvas/canvas-header.jsp b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/partials/canvas/canvas-header.jsp index 204b1b3703..2ea7ca61f0 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/partials/canvas/canvas-header.jsp +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/partials/canvas/canvas-header.jsp @@ -45,7 +45,7 @@
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/partials/message-pane.jsp b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/partials/message-pane.jsp index 1bdec3def0..db5dece360 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/partials/message-pane.jsp +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/partials/message-pane.jsp @@ -16,8 +16,11 @@ --%> <%@ page contentType="text/html" pageEncoding="UTF-8" session="false" %> \ No newline at end of file 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 29ef12ac84..f055d1a5fc 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 @@ -81,16 +81,9 @@ body.login-body input, body.login-body textarea { } #nifi-user-submit-justification { - float: left; font-weight: bold; } -#nifi-user-submit-justification-logout { - margin-left: 10px; - float: left; - text-decoration: underline; -} - #nifi-registration-justification { height: 200px; } diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/css/main.css b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/css/main.css index 2e43a8bab7..deadcd58c7 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/css/main.css +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/css/main.css @@ -77,6 +77,17 @@ div.context-menu-provenance { background-position: top left; } +#user-logout-container { + position: absolute; + left: 478px; + top: 100px; + z-index: 1300; +} + +#user-logout { + text-decoration: underline; +} + /* General Styles */ 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 f5411afba9..88156ef541 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 @@ -23,7 +23,7 @@ $(document).ready(function () { nf.Login = (function () { - var isAnonymous = false; + var supportsAnonymous = false; var config = { urls: { @@ -70,7 +70,7 @@ nf.Login = (function () { $('#nifi-registration-justification').count({ charCountField: '#remaining-characters' }); - + // toggle between signup and login $('#login-to-account-link').on('click', function () { showLogin(); @@ -165,9 +165,14 @@ nf.Login = (function () { 'password': password, 'justification': $('#nifi-registration-justification').val() } - }).done(function (response, status, xhr) { + }).done(function (jwt) { + // store the jwt + nf.Storage.setItem('jwt', jwt); + showLogoutLink(); + + // inform the user of their pending request var markup = 'An administrator will process your request shortly.'; - if (isAnonymous === true) { + if (supportsAnonymous === true) { markup += '

In the meantime you can continue accessing anonymously.'; } @@ -195,7 +200,7 @@ nf.Login = (function () { } }).done(function (response) { var markup = 'An administrator will process your request shortly.'; - if (isAnonymous === true) { + if (supportsAnonymous === true) { markup += '

In the meantime you can continue accessing anonymously.'; } @@ -239,6 +244,20 @@ nf.Login = (function () { return ''; }; + var logout = function () { + nf.Storage.removeItem('jwt'); + }; + + var showLogoutLink = function () { + $('#user-logout-container').show(); + + // handle logout + $('#user-logout').on('click', function () { + logout(); + window.location = '/nifi/login'; + }); + }; + return { /** * Initializes the login page. @@ -250,15 +269,9 @@ nf.Login = (function () { var needsLogin = false; var needsNiFiRegistration = false; - var logout = function () { - nf.Storage.removeItem('jwt'); - }; - - // handle logout - $('#nifi-user-submit-justification-logout').on('click', function () { - logout(); - window.location = '/nifi/login'; - }); + if (nf.Storage.getItem('jwt') !== null) { + showLogoutLink(); + } var token = $.ajax({ type: 'GET', @@ -276,7 +289,7 @@ nf.Login = (function () { identity.done(function (response) { // if the user is anonymous see if they need to login or if they are working with a certificate if (response.identity === 'anonymous') { - isAnonymous = true; + supportsAnonymous = true; // request a token without including credentials, if successful then the user is using a certificate token.done(function (jwt) { @@ -294,7 +307,7 @@ nf.Login = (function () { }).fail(function (xhr, status, error) { if (xhr.status === 401) { var user = getJwtSubject(jwt); - + // show the user $('#nifi-user-submit-justification').text(user); 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 8c023e71df..9b321c32ba 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 @@ -63,6 +63,23 @@ $(document).ready(function () { // initialize the tooltips $('img.setting-icon').qtip(nf.Common.config.tooltipConfig); + + // shows the logout link in the message-pane when appropriate + if (nf.Storage.getItem('jwt')) { + $('#user-logout-container').show(); + } + + // handle logout + $('#user-logout').on('click', function () { + nf.Storage.removeItem('jwt'); + + // reload as appropriate + if (top !== window) { + parent.window.location = '/nifi'; + } else { + window.location = '/nifi'; + } + }); }); // Define a common utility class used across the entire application. @@ -219,7 +236,7 @@ nf.Common = { } else { $('#message-content').text(xhr.responseText); } - + // show the error pane $('#message-pane').show();