NIFI-655:

- Adding more/better support for logging out.
This commit is contained in:
Matt Gilman 2015-11-06 18:06:47 -05:00
parent d41b83c19b
commit d47c00f00e
12 changed files with 86 additions and 42 deletions

View File

@ -88,17 +88,16 @@ 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,9 +110,11 @@ public class NiFiWebApiSecurityConfiguration extends WebSecurityConfigurerAdapte
// x509
http.addFilterAfter(buildX509Filter(), AnonymousAuthenticationFilter.class);
// jwt
// jwt - consider when configured for log in
if (loginIdentityProvider != null) {
http.addFilterAfter(buildJwtFilter(), AnonymousAuthenticationFilter.class);
}
}
@Bean
@Override

View File

@ -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 {

View File

@ -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

View File

@ -37,6 +37,9 @@
${nf.login.script.tags}
</head>
<body class="login-body">
<div id="user-logout-container" class="hidden">
<span id="user-logout" class="link">logout</span>
</div>
<div id="login-contents-container">
<jsp:include page="/WEB-INF/partials/login/login-message.jsp"/>
<jsp:include page="/WEB-INF/partials/login/login-form.jsp"/>

View File

@ -27,8 +27,8 @@
<body class="message-pane">
<div class="message-pane-message-box">
<p class="message-pane-title"><%= request.getAttribute("title") == null ? "" : org.apache.nifi.util.EscapeUtils.escapeHtml(request.getAttribute("title").toString()) %></p>
<p class="message-pane-content"><%= request.getAttribute("messages") == null ? "" : org.apache.nifi.util.EscapeUtils.escapeHtml(request.getAttribute("messages").toString()) %></p>
<div class="message-pane-title"><%= request.getAttribute("title") == null ? "" : org.apache.nifi.util.EscapeUtils.escapeHtml(request.getAttribute("title").toString()) %></div>
<div class="message-pane-content"><%= request.getAttribute("messages") == null ? "" : org.apache.nifi.util.EscapeUtils.escapeHtml(request.getAttribute("messages").toString()) %></div>
</div>
</body>
</html>

View File

@ -45,7 +45,7 @@
<div id="header-links-container">
<ul>
<li id="current-user-container">
<div id="anonymous-user-alert"></div>
<div id="anonymous-user-alert" class="hidden"></div>
<div id="current-user"></div>
<div class="clear"></div>
</li>

View File

@ -22,8 +22,6 @@
<div class="setting-name">User</div>
<div class="setting-field">
<div id="nifi-user-submit-justification"></div>
<span id="nifi-user-submit-justification-logout" class="link hidden">logout</span>
<div class="clear"></div>
</div>
</div>
</div>

View File

@ -16,8 +16,11 @@
--%>
<%@ page contentType="text/html" pageEncoding="UTF-8" session="false" %>
<div id="message-pane" class="message-pane hidden">
<div id="user-logout-container" class="hidden">
<span id="user-logout" class="link">logout</span>
</div>
<div class="message-pane-message-box">
<p id="message-title" class="message-pane-title"></p>
<p id="message-content" class="message-pane-content"></p>
<div id="message-title" class="message-pane-title"></div>
<div id="message-content" class="message-pane-content"></div>
</div>
</div>

View File

@ -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;
}

View File

@ -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
*/

View File

@ -23,7 +23,7 @@ $(document).ready(function () {
nf.Login = (function () {
var isAnonymous = false;
var supportsAnonymous = false;
var config = {
urls: {
@ -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 += '<br/><br/>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 += '<br/><br/>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) {

View File

@ -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.