mirror of https://github.com/apache/nifi.git
parent
d41b83c19b
commit
d47c00f00e
|
@ -88,17 +88,16 @@ public class NiFiWebApiSecurityConfiguration extends WebSecurityConfigurerAdapte
|
||||||
.sessionManagement()
|
.sessionManagement()
|
||||||
.sessionCreationPolicy(SessionCreationPolicy.STATELESS);
|
.sessionCreationPolicy(SessionCreationPolicy.STATELESS);
|
||||||
|
|
||||||
// verify that login authentication is enabled
|
|
||||||
if (loginIdentityProvider != null) {
|
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
|
// verify the configured login authenticator supports user login registration
|
||||||
if (loginIdentityProvider.supportsRegistration()) {
|
if (loginIdentityProvider.supportsRegistration()) {
|
||||||
http.addFilterBefore(buildRegistrationFilter("/registration"), UsernamePasswordAuthenticationFilter.class);
|
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)
|
// 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);
|
http.addFilterBefore(buildRegistrationStatusFilter("/registration/status"), UsernamePasswordAuthenticationFilter.class);
|
||||||
|
|
||||||
|
@ -111,9 +110,11 @@ public class NiFiWebApiSecurityConfiguration extends WebSecurityConfigurerAdapte
|
||||||
// x509
|
// x509
|
||||||
http.addFilterAfter(buildX509Filter(), AnonymousAuthenticationFilter.class);
|
http.addFilterAfter(buildX509Filter(), AnonymousAuthenticationFilter.class);
|
||||||
|
|
||||||
// jwt
|
// jwt - consider when configured for log in
|
||||||
|
if (loginIdentityProvider != null) {
|
||||||
http.addFilterAfter(buildJwtFilter(), AnonymousAuthenticationFilter.class);
|
http.addFilterAfter(buildJwtFilter(), AnonymousAuthenticationFilter.class);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -86,6 +86,11 @@ public class LoginAuthenticationFilter extends AbstractAuthenticationProcessingF
|
||||||
|
|
||||||
// if there is no certificate, look for an existing token
|
// if there is no certificate, look for an existing token
|
||||||
if (certificate == null) {
|
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);
|
final String principal = jwtService.getAuthentication(request);
|
||||||
|
|
||||||
if (principal == null) {
|
if (principal == null) {
|
||||||
|
@ -129,6 +134,11 @@ public class LoginAuthenticationFilter extends AbstractAuthenticationProcessingF
|
||||||
return new LoginAuthenticationToken(preAuthenticatedCredentials);
|
return new LoginAuthenticationToken(preAuthenticatedCredentials);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
// if not configuration for login, don't consider credentials
|
||||||
|
if (loginIdentityProvider == null) {
|
||||||
|
throw new BadCredentialsException("Login not supported.");
|
||||||
|
}
|
||||||
|
|
||||||
if (loginIdentityProvider.authenticate(credentials)) {
|
if (loginIdentityProvider.authenticate(credentials)) {
|
||||||
return new LoginAuthenticationToken(credentials);
|
return new LoginAuthenticationToken(credentials);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -120,11 +120,6 @@ public class RegistrationFilter extends AbstractAuthenticationProcessingFilter {
|
||||||
|
|
||||||
// generate JWT for response
|
// generate JWT for response
|
||||||
jwtService.addToken(response, authentication);
|
jwtService.addToken(response, authentication);
|
||||||
|
|
||||||
// mark as successful
|
|
||||||
response.setStatus(HttpServletResponse.SC_CREATED);
|
|
||||||
response.setContentType("text/plain");
|
|
||||||
response.setContentLength(0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -37,6 +37,9 @@
|
||||||
${nf.login.script.tags}
|
${nf.login.script.tags}
|
||||||
</head>
|
</head>
|
||||||
<body class="login-body">
|
<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">
|
<div id="login-contents-container">
|
||||||
<jsp:include page="/WEB-INF/partials/login/login-message.jsp"/>
|
<jsp:include page="/WEB-INF/partials/login/login-message.jsp"/>
|
||||||
<jsp:include page="/WEB-INF/partials/login/login-form.jsp"/>
|
<jsp:include page="/WEB-INF/partials/login/login-form.jsp"/>
|
||||||
|
|
|
@ -27,8 +27,8 @@
|
||||||
|
|
||||||
<body class="message-pane">
|
<body class="message-pane">
|
||||||
<div class="message-pane-message-box">
|
<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>
|
<div class="message-pane-title"><%= request.getAttribute("title") == null ? "" : org.apache.nifi.util.EscapeUtils.escapeHtml(request.getAttribute("title").toString()) %></div>
|
||||||
<p class="message-pane-content"><%= request.getAttribute("messages") == null ? "" : org.apache.nifi.util.EscapeUtils.escapeHtml(request.getAttribute("messages").toString()) %></p>
|
<div class="message-pane-content"><%= request.getAttribute("messages") == null ? "" : org.apache.nifi.util.EscapeUtils.escapeHtml(request.getAttribute("messages").toString()) %></div>
|
||||||
</div>
|
</div>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
@ -45,7 +45,7 @@
|
||||||
<div id="header-links-container">
|
<div id="header-links-container">
|
||||||
<ul>
|
<ul>
|
||||||
<li id="current-user-container">
|
<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 id="current-user"></div>
|
||||||
<div class="clear"></div>
|
<div class="clear"></div>
|
||||||
</li>
|
</li>
|
||||||
|
|
|
@ -22,8 +22,6 @@
|
||||||
<div class="setting-name">User</div>
|
<div class="setting-name">User</div>
|
||||||
<div class="setting-field">
|
<div class="setting-field">
|
||||||
<div id="nifi-user-submit-justification"></div>
|
<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>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -16,8 +16,11 @@
|
||||||
--%>
|
--%>
|
||||||
<%@ page contentType="text/html" pageEncoding="UTF-8" session="false" %>
|
<%@ page contentType="text/html" pageEncoding="UTF-8" session="false" %>
|
||||||
<div id="message-pane" class="message-pane hidden">
|
<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">
|
<div class="message-pane-message-box">
|
||||||
<p id="message-title" class="message-pane-title"></p>
|
<div id="message-title" class="message-pane-title"></div>
|
||||||
<p id="message-content" class="message-pane-content"></p>
|
<div id="message-content" class="message-pane-content"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
|
@ -81,16 +81,9 @@ body.login-body input, body.login-body textarea {
|
||||||
}
|
}
|
||||||
|
|
||||||
#nifi-user-submit-justification {
|
#nifi-user-submit-justification {
|
||||||
float: left;
|
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
|
|
||||||
#nifi-user-submit-justification-logout {
|
|
||||||
margin-left: 10px;
|
|
||||||
float: left;
|
|
||||||
text-decoration: underline;
|
|
||||||
}
|
|
||||||
|
|
||||||
#nifi-registration-justification {
|
#nifi-registration-justification {
|
||||||
height: 200px;
|
height: 200px;
|
||||||
}
|
}
|
||||||
|
|
|
@ -77,6 +77,17 @@ div.context-menu-provenance {
|
||||||
background-position: top left;
|
background-position: top left;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#user-logout-container {
|
||||||
|
position: absolute;
|
||||||
|
left: 478px;
|
||||||
|
top: 100px;
|
||||||
|
z-index: 1300;
|
||||||
|
}
|
||||||
|
|
||||||
|
#user-logout {
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
General Styles
|
General Styles
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -23,7 +23,7 @@ $(document).ready(function () {
|
||||||
|
|
||||||
nf.Login = (function () {
|
nf.Login = (function () {
|
||||||
|
|
||||||
var isAnonymous = false;
|
var supportsAnonymous = false;
|
||||||
|
|
||||||
var config = {
|
var config = {
|
||||||
urls: {
|
urls: {
|
||||||
|
@ -165,9 +165,14 @@ nf.Login = (function () {
|
||||||
'password': password,
|
'password': password,
|
||||||
'justification': $('#nifi-registration-justification').val()
|
'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.';
|
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.';
|
markup += '<br/><br/>In the meantime you can continue accessing anonymously.';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -195,7 +200,7 @@ nf.Login = (function () {
|
||||||
}
|
}
|
||||||
}).done(function (response) {
|
}).done(function (response) {
|
||||||
var markup = 'An administrator will process your request shortly.';
|
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.';
|
markup += '<br/><br/>In the meantime you can continue accessing anonymously.';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -239,6 +244,20 @@ nf.Login = (function () {
|
||||||
return '';
|
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 {
|
return {
|
||||||
/**
|
/**
|
||||||
* Initializes the login page.
|
* Initializes the login page.
|
||||||
|
@ -250,15 +269,9 @@ nf.Login = (function () {
|
||||||
var needsLogin = false;
|
var needsLogin = false;
|
||||||
var needsNiFiRegistration = false;
|
var needsNiFiRegistration = false;
|
||||||
|
|
||||||
var logout = function () {
|
if (nf.Storage.getItem('jwt') !== null) {
|
||||||
nf.Storage.removeItem('jwt');
|
showLogoutLink();
|
||||||
};
|
}
|
||||||
|
|
||||||
// handle logout
|
|
||||||
$('#nifi-user-submit-justification-logout').on('click', function () {
|
|
||||||
logout();
|
|
||||||
window.location = '/nifi/login';
|
|
||||||
});
|
|
||||||
|
|
||||||
var token = $.ajax({
|
var token = $.ajax({
|
||||||
type: 'GET',
|
type: 'GET',
|
||||||
|
@ -276,7 +289,7 @@ nf.Login = (function () {
|
||||||
identity.done(function (response) {
|
identity.done(function (response) {
|
||||||
// if the user is anonymous see if they need to login or if they are working with a certificate
|
// if the user is anonymous see if they need to login or if they are working with a certificate
|
||||||
if (response.identity === 'anonymous') {
|
if (response.identity === 'anonymous') {
|
||||||
isAnonymous = true;
|
supportsAnonymous = true;
|
||||||
|
|
||||||
// request a token without including credentials, if successful then the user is using a certificate
|
// request a token without including credentials, if successful then the user is using a certificate
|
||||||
token.done(function (jwt) {
|
token.done(function (jwt) {
|
||||||
|
|
|
@ -63,6 +63,23 @@ $(document).ready(function () {
|
||||||
|
|
||||||
// initialize the tooltips
|
// initialize the tooltips
|
||||||
$('img.setting-icon').qtip(nf.Common.config.tooltipConfig);
|
$('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.
|
// Define a common utility class used across the entire application.
|
||||||
|
|
Loading…
Reference in New Issue