mirror of https://github.com/apache/nifi.git
NIFI-655:
- Starting to add support for registration. - Creating registration form.
This commit is contained in:
parent
2214592865
commit
93aa09dace
|
@ -16,6 +16,7 @@
|
|||
*/
|
||||
package org.apache.nifi.authentication;
|
||||
|
||||
import org.apache.nifi.authorization.exception.IdentityAlreadyExistsException;
|
||||
import org.apache.nifi.authorization.exception.ProviderCreationException;
|
||||
import org.apache.nifi.authorization.exception.ProviderDestructionException;
|
||||
|
||||
|
@ -36,7 +37,7 @@ public interface LoginIdentityProvider {
|
|||
*
|
||||
* @param credentials the login credentials
|
||||
*/
|
||||
void register(LoginCredentials credentials);
|
||||
void register(LoginCredentials credentials) throws IdentityAlreadyExistsException;
|
||||
|
||||
/**
|
||||
* Authenticates the specified login credentials.
|
||||
|
|
|
@ -207,6 +207,14 @@ public final class AuthorizedUsers {
|
|||
saveUsers(users);
|
||||
}
|
||||
|
||||
public synchronized void createOrUpdateUser(final FindUser finder, final CreateUser creator, final UpdateUser updater) {
|
||||
try {
|
||||
updateUser(finder, updater);
|
||||
} catch (final UnknownIdentityException uie) {
|
||||
createUser(creator);
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized void updateUser(final FindUser finder, final UpdateUser updater) {
|
||||
// update the user
|
||||
final Users users = getUsers();
|
||||
|
|
|
@ -48,7 +48,7 @@
|
|||
<xs:complexType name="User">
|
||||
<xs:complexContent>
|
||||
<xs:extension base="NiFiUser">
|
||||
<xs:attribute name="dn">
|
||||
<xs:attribute name="dn" use="required">
|
||||
<xs:simpleType>
|
||||
<xs:restriction base="xs:string">
|
||||
<xs:minLength value="1"/>
|
||||
|
@ -64,7 +64,7 @@
|
|||
<xs:complexType name="LoginUser">
|
||||
<xs:complexContent>
|
||||
<xs:extension base="NiFiUser">
|
||||
<xs:attribute name="username">
|
||||
<xs:attribute name="username" use="required">
|
||||
<xs:simpleType>
|
||||
<xs:restriction base="xs:string">
|
||||
<xs:minLength value="1"/>
|
||||
|
@ -72,7 +72,7 @@
|
|||
</xs:restriction>
|
||||
</xs:simpleType>
|
||||
</xs:attribute>
|
||||
<xs:attribute name="password">
|
||||
<xs:attribute name="password" use="required">
|
||||
<xs:simpleType>
|
||||
<xs:restriction base="xs:string">
|
||||
<xs:minLength value="1"/>
|
||||
|
@ -80,6 +80,7 @@
|
|||
</xs:restriction>
|
||||
</xs:simpleType>
|
||||
</xs:attribute>
|
||||
<xs:attribute name="pending" type="xs:boolean" use="required"/>
|
||||
</xs:extension>
|
||||
</xs:complexContent>
|
||||
</xs:complexType>
|
||||
|
|
|
@ -40,6 +40,7 @@ import org.apache.nifi.authorized.users.AuthorizedUsers.FindUsers;
|
|||
import org.apache.nifi.authorized.users.AuthorizedUsers.HasUser;
|
||||
import org.apache.nifi.authorized.users.AuthorizedUsers.UpdateUser;
|
||||
import org.apache.nifi.authorized.users.AuthorizedUsers.UpdateUsers;
|
||||
import org.apache.nifi.user.generated.LoginUser;
|
||||
import org.apache.nifi.user.generated.NiFiUser;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
@ -182,15 +183,37 @@ public class FileAuthorizationProvider implements AuthorityProvider {
|
|||
|
||||
@Override
|
||||
public void addUser(final String dn, final String group) throws IdentityAlreadyExistsException, AuthorityAccessException {
|
||||
authorizedUsers.createUser(new CreateUser() {
|
||||
authorizedUsers.createOrUpdateUser(new FindUser() {
|
||||
@Override
|
||||
public NiFiUser createUser() {
|
||||
// ensure the user doesn't already exist
|
||||
if (authorizedUsers.hasUser(new HasUserByIdentity(dn))) {
|
||||
throw new IdentityAlreadyExistsException(String.format("User identity already exists: %s", dn));
|
||||
public NiFiUser findUser(final List<NiFiUser> users) throws UnknownIdentityException {
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
|
||||
// only support adding PreAuthenticatedUser's via this API - LoginUser's are added
|
||||
// user does not exist, will create
|
||||
if (desiredUser == null) {
|
||||
throw new UnknownIdentityException("This exception will trigger the creator to be invoked.");
|
||||
}
|
||||
|
||||
// user exists, verify its still pending
|
||||
if (LoginUser.class.isAssignableFrom(desiredUser.getClass())) {
|
||||
if (((LoginUser) desiredUser).isPending()) {
|
||||
return desiredUser;
|
||||
}
|
||||
}
|
||||
|
||||
// user exists and account is valid... no good
|
||||
throw new IdentityAlreadyExistsException(String.format("User identity already exists: %s", dn));
|
||||
}
|
||||
}, new CreateUser() {
|
||||
@Override
|
||||
public NiFiUser createUser() {
|
||||
// only support adding PreAuthenticated User's via this API - LoginUser's are added
|
||||
// via the LoginIdentityProvider
|
||||
final ObjectFactory objFactory = new ObjectFactory();
|
||||
final User newUser = objFactory.createUser();
|
||||
|
@ -212,6 +235,13 @@ public class FileAuthorizationProvider implements AuthorityProvider {
|
|||
|
||||
return newUser;
|
||||
}
|
||||
}, new UpdateUser() {
|
||||
@Override
|
||||
public void updateUser(final NiFiUser user) {
|
||||
// only support updating Login Users's via this API - need to mark the account as non pending
|
||||
LoginUser loginUser = (LoginUser) user;
|
||||
loginUser.setPending(false);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -306,6 +336,13 @@ public class FileAuthorizationProvider implements AuthorityProvider {
|
|||
this.properties = properties;
|
||||
}
|
||||
|
||||
private boolean isPendingLoginUser(final NiFiUser user) {
|
||||
if (LoginUser.class.isAssignableFrom(user.getClass())) {
|
||||
return ((LoginUser) user).isPending();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public class HasUserByIdentity implements HasUser {
|
||||
|
||||
private final String identity;
|
||||
|
@ -324,7 +361,7 @@ public class FileAuthorizationProvider implements AuthorityProvider {
|
|||
// attempt to get the user and ensure it was located
|
||||
NiFiUser desiredUser = null;
|
||||
for (final NiFiUser user : users) {
|
||||
if (identity.equalsIgnoreCase(authorizedUsers.getUserIdentity(user))) {
|
||||
if (identity.equalsIgnoreCase(authorizedUsers.getUserIdentity(user)) && !isPendingLoginUser(user)) {
|
||||
desiredUser = user;
|
||||
break;
|
||||
}
|
||||
|
@ -352,7 +389,7 @@ public class FileAuthorizationProvider implements AuthorityProvider {
|
|||
// attempt to get the user and ensure it was located
|
||||
NiFiUser desiredUser = null;
|
||||
for (final NiFiUser user : users) {
|
||||
if (identity.equalsIgnoreCase(authorizedUsers.getUserIdentity(user))) {
|
||||
if (identity.equalsIgnoreCase(authorizedUsers.getUserIdentity(user)) && !isPendingLoginUser(user)) {
|
||||
desiredUser = user;
|
||||
break;
|
||||
}
|
||||
|
@ -366,7 +403,7 @@ public class FileAuthorizationProvider implements AuthorityProvider {
|
|||
}
|
||||
}
|
||||
|
||||
public static class FindUsersByGroup implements FindUsers {
|
||||
public class FindUsersByGroup implements FindUsers {
|
||||
|
||||
private final String group;
|
||||
|
||||
|
@ -384,7 +421,7 @@ public class FileAuthorizationProvider implements AuthorityProvider {
|
|||
// get all users with this group
|
||||
List<NiFiUser> userGroup = new ArrayList<>();
|
||||
for (final NiFiUser user : users) {
|
||||
if (group.equals(user.getGroup())) {
|
||||
if (group.equals(user.getGroup()) && !isPendingLoginUser(user)) {
|
||||
userGroup.add(user);
|
||||
}
|
||||
}
|
||||
|
@ -419,7 +456,7 @@ public class FileAuthorizationProvider implements AuthorityProvider {
|
|||
List<NiFiUser> userList = new ArrayList<>();
|
||||
for (final NiFiUser user : users) {
|
||||
final String userIdentity = authorizedUsers.getUserIdentity(user);
|
||||
if (copy.contains(userIdentity)) {
|
||||
if (copy.contains(userIdentity) && !isPendingLoginUser(user)) {
|
||||
copy.remove(userIdentity);
|
||||
userList.add(user);
|
||||
}
|
||||
|
|
|
@ -19,9 +19,11 @@ package org.apache.nifi.authentication;
|
|||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import org.apache.nifi.authentication.annotation.LoginIdentityProviderContext;
|
||||
import org.apache.nifi.authorization.exception.IdentityAlreadyExistsException;
|
||||
import org.apache.nifi.authorization.exception.ProviderCreationException;
|
||||
import org.apache.nifi.authorization.exception.ProviderDestructionException;
|
||||
import org.apache.nifi.authorized.users.AuthorizedUsers;
|
||||
import org.apache.nifi.authorized.users.AuthorizedUsers.CreateUser;
|
||||
import org.apache.nifi.authorized.users.AuthorizedUsers.HasUser;
|
||||
import org.apache.nifi.user.generated.LoginUser;
|
||||
import org.apache.nifi.user.generated.NiFiUser;
|
||||
|
@ -57,11 +59,43 @@ public class FileLoginIdentityProvider implements LoginIdentityProvider {
|
|||
|
||||
@Override
|
||||
public boolean supportsRegistration() {
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void register(LoginCredentials credentials) {
|
||||
public void register(final LoginCredentials credentials) throws IdentityAlreadyExistsException {
|
||||
authorizedUsers.createUser(new CreateUser() {
|
||||
@Override
|
||||
public NiFiUser createUser() {
|
||||
final HasUser hasUser = new HasUser() {
|
||||
@Override
|
||||
public boolean hasUser(List<NiFiUser> users) {
|
||||
for (final NiFiUser user : users) {
|
||||
// only consider LoginUsers
|
||||
if (LoginUser.class.isAssignableFrom(user.getClass())) {
|
||||
final LoginUser loginUser = (LoginUser) user;
|
||||
if (credentials.getUsername().equals(loginUser.getUsername())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
// if the user already exists
|
||||
if (authorizedUsers.hasUser(hasUser)) {
|
||||
throw new IdentityAlreadyExistsException(String.format("A user account for %s already exists.", credentials.getUsername()));
|
||||
}
|
||||
|
||||
// TODO - need to properly encrypt and hash the user password for storage
|
||||
final LoginUser user = new LoginUser();
|
||||
user.setUsername(credentials.getUsername());
|
||||
user.setPassword(credentials.getPassword());
|
||||
user.setPending(true);
|
||||
return user;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -78,7 +112,7 @@ public class FileLoginIdentityProvider implements LoginIdentityProvider {
|
|||
if (LoginUser.class.isAssignableFrom(user.getClass())) {
|
||||
final LoginUser loginUser = (LoginUser) user;
|
||||
|
||||
// TODO - need to properly encrypt and hash password
|
||||
// TODO - need to properly encrypt and hash the supplied password for comparison
|
||||
final String loginUserPassword = loginUser.getPassword();
|
||||
if (credentials.getUsername().equals(loginUser.getUsername()) && credentials.getPassword().equals(loginUserPassword)) {
|
||||
return true;
|
||||
|
|
|
@ -614,9 +614,12 @@ public class JettyServer implements NiFiServer {
|
|||
private SslContextFactory createSslContextFactory() {
|
||||
final SslContextFactory contextFactory = new SslContextFactory();
|
||||
|
||||
// client auth
|
||||
contextFactory.setWantClientAuth(true);
|
||||
contextFactory.setNeedClientAuth(false);
|
||||
// require client auth when not supporting login or anonymous access
|
||||
if (StringUtils.isBlank(props.getProperty(NiFiProperties.SECURITY_USER_LOGIN_IDENTITY_PROVIDER)) && props.getAnonymousAuthorities().isEmpty()) {
|
||||
contextFactory.setNeedClientAuth(true);
|
||||
} else {
|
||||
contextFactory.setWantClientAuth(true);
|
||||
}
|
||||
|
||||
/* below code sets JSSE system properties when values are provided */
|
||||
// keystore properties
|
||||
|
|
|
@ -25,6 +25,7 @@ import org.apache.nifi.web.security.anonymous.NiFiAnonymousUserFilter;
|
|||
import org.apache.nifi.web.security.NiFiAuthenticationEntryPoint;
|
||||
import org.apache.nifi.web.security.RegistrationStatusFilter;
|
||||
import org.apache.nifi.web.security.form.LoginAuthenticationFilter;
|
||||
import org.apache.nifi.web.security.form.RegistrationFilter;
|
||||
import org.apache.nifi.web.security.jwt.JwtAuthenticationFilter;
|
||||
import org.apache.nifi.web.security.jwt.JwtService;
|
||||
import org.apache.nifi.web.security.node.NodeAuthorizedUserFilter;
|
||||
|
@ -138,17 +139,22 @@ public class NiFiWebApiSecurityConfiguration extends WebSecurityConfigurerAdapte
|
|||
}
|
||||
|
||||
private Filter buildRegistrationFilter(final String url) {
|
||||
return null;
|
||||
final RegistrationFilter registrationFilter = new RegistrationFilter(url);
|
||||
registrationFilter.setJwtService(jwtService);
|
||||
registrationFilter.setLoginIdentityProvider(loginIdentityProvider);
|
||||
registrationFilter.setUserService(userService);
|
||||
return registrationFilter;
|
||||
}
|
||||
|
||||
private Filter buildRegistrationStatusFilter(final String url) {
|
||||
final RegistrationStatusFilter registrationFilter = new RegistrationStatusFilter(url);
|
||||
registrationFilter.setCertificateExtractor(certificateExtractor);
|
||||
registrationFilter.setPrincipalExtractor(principalExtractor);
|
||||
registrationFilter.setCertificateValidator(certificateValidator);
|
||||
registrationFilter.setProperties(properties);
|
||||
registrationFilter.setUserDetailsService(userDetailsService);
|
||||
return registrationFilter;
|
||||
final RegistrationStatusFilter registrationStatusFilter = new RegistrationStatusFilter(url);
|
||||
registrationStatusFilter.setCertificateExtractor(certificateExtractor);
|
||||
registrationStatusFilter.setPrincipalExtractor(principalExtractor);
|
||||
registrationStatusFilter.setCertificateValidator(certificateValidator);
|
||||
registrationStatusFilter.setProperties(properties);
|
||||
registrationStatusFilter.setJwtService(jwtService);
|
||||
registrationStatusFilter.setUserDetailsService(userDetailsService);
|
||||
return registrationStatusFilter;
|
||||
}
|
||||
|
||||
private NodeAuthorizedUserFilter buildNodeAuthorizedUserFilter() {
|
||||
|
|
|
@ -30,6 +30,7 @@ import javax.servlet.http.HttpServletResponse;
|
|||
import org.apache.nifi.authentication.LoginCredentials;
|
||||
import org.apache.nifi.util.NiFiProperties;
|
||||
import org.apache.nifi.util.StringUtils;
|
||||
import org.apache.nifi.web.security.jwt.JwtService;
|
||||
import org.apache.nifi.web.security.token.NiFiAuthenticationRequestToken;
|
||||
import org.apache.nifi.web.security.x509.X509CertificateExtractor;
|
||||
import org.apache.nifi.web.security.x509.X509CertificateValidator;
|
||||
|
@ -54,6 +55,7 @@ public class RegistrationStatusFilter extends AbstractAuthenticationProcessingFi
|
|||
private static final Logger logger = LoggerFactory.getLogger(RegistrationStatusFilter.class);
|
||||
|
||||
private NiFiProperties properties;
|
||||
private JwtService jwtService;
|
||||
private AuthenticationUserDetailsService<NiFiAuthenticationRequestToken> userDetailsService;
|
||||
private X509CertificateValidator certificateValidator;
|
||||
private X509CertificateExtractor certificateExtractor;
|
||||
|
@ -78,21 +80,22 @@ public class RegistrationStatusFilter extends AbstractAuthenticationProcessingFi
|
|||
|
||||
// if no certificate, just check the credentials
|
||||
if (certificate == null) {
|
||||
final LoginCredentials credentials = getLoginCredentials(request);
|
||||
final String principal = jwtService.getAuthentication(request);
|
||||
|
||||
// ensure we have something we can work with (certificate or crendentials)
|
||||
if (credentials == null) {
|
||||
if (principal == null) {
|
||||
throw new BadCredentialsException("Unable to check registration status as no credentials were included with the request.");
|
||||
}
|
||||
|
||||
// without a certificate, this is not a proxied request
|
||||
final List<String> chain = Arrays.asList(credentials.getUsername());
|
||||
final List<String> chain = Arrays.asList(principal);
|
||||
|
||||
// check authorization for this user
|
||||
checkAuthorization(chain);
|
||||
|
||||
// no issues with authorization
|
||||
return new RegistrationStatusAuthenticationToken(credentials);
|
||||
final LoginCredentials tokenCredentials = new LoginCredentials(principal, null);
|
||||
return new RegistrationStatusAuthenticationToken(tokenCredentials);
|
||||
} else {
|
||||
// we have a certificate so let's consider a proxy chain
|
||||
final String principal = extractPrincipal(certificate);
|
||||
|
@ -147,17 +150,6 @@ public class RegistrationStatusFilter extends AbstractAuthenticationProcessingFi
|
|||
return ProxiedEntitiesUtils.formatProxyDn(certificatePrincipal.toString());
|
||||
}
|
||||
|
||||
private LoginCredentials getLoginCredentials(HttpServletRequest request) {
|
||||
final String username = request.getParameter("username");
|
||||
final String password = request.getParameter("password");
|
||||
|
||||
if (StringUtils.isBlank(username) || StringUtils.isBlank(password)) {
|
||||
return null;
|
||||
} else {
|
||||
return new LoginCredentials(username, password);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void successfulAuthentication(final HttpServletRequest request, final HttpServletResponse response, final FilterChain chain, final Authentication authentication)
|
||||
throws IOException, ServletException {
|
||||
|
@ -238,6 +230,10 @@ public class RegistrationStatusFilter extends AbstractAuthenticationProcessingFi
|
|||
}
|
||||
}
|
||||
|
||||
public void setJwtService(JwtService jwtService) {
|
||||
this.jwtService = jwtService;
|
||||
}
|
||||
|
||||
public void setCertificateValidator(X509CertificateValidator certificateValidator) {
|
||||
this.certificateValidator = certificateValidator;
|
||||
}
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
*/
|
||||
package org.apache.nifi.web.security.form;
|
||||
|
||||
import org.apache.nifi.web.security.token.LoginAuthenticationToken;
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import java.security.cert.CertificateExpiredException;
|
||||
|
@ -36,7 +37,7 @@ import org.apache.nifi.web.security.x509.X509CertificateExtractor;
|
|||
import org.apache.nifi.web.security.x509.X509CertificateValidator;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.security.authentication.AbstractAuthenticationToken;
|
||||
import org.springframework.security.authentication.AuthenticationCredentialsNotFoundException;
|
||||
import org.springframework.security.authentication.BadCredentialsException;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.core.AuthenticationException;
|
||||
|
@ -84,42 +85,50 @@ public class LoginAuthenticationFilter extends AbstractAuthenticationProcessingF
|
|||
// look for a certificate
|
||||
final X509Certificate certificate = certificateExtractor.extractClientCertificate(request);
|
||||
|
||||
// if there is no certificate, look for an existing token
|
||||
if (certificate == null) {
|
||||
throw new PreAuthenticatedCredentialsNotFoundException("Unable to extract client certificate after processing request with no login credentials specified.");
|
||||
final String principal = jwtService.getAuthentication(request);
|
||||
|
||||
if (principal == null) {
|
||||
throw new AuthenticationCredentialsNotFoundException("Unable to issue token as issue token as no credentials were found in the request.");
|
||||
}
|
||||
|
||||
final LoginCredentials tokenCredentials = new LoginCredentials(principal, null);
|
||||
return new LoginAuthenticationToken(tokenCredentials);
|
||||
} else {
|
||||
// extract the principal
|
||||
final String principal = extractPrincipal(certificate);
|
||||
|
||||
try {
|
||||
certificateValidator.validateClientCertificate(request, certificate);
|
||||
} catch (CertificateExpiredException cee) {
|
||||
final String message = String.format("Client certificate for (%s) is expired.", principal);
|
||||
logger.info(message, cee);
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("", cee);
|
||||
}
|
||||
return null;
|
||||
} catch (CertificateNotYetValidException cnyve) {
|
||||
final String message = String.format("Client certificate for (%s) is not yet valid.", principal);
|
||||
logger.info(message, cnyve);
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("", cnyve);
|
||||
}
|
||||
return null;
|
||||
} catch (final Exception e) {
|
||||
logger.info(e.getMessage());
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("", e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
// authorize the proxy if necessary
|
||||
authorizeProxyIfNecessary(ProxiedEntitiesUtils.buildProxyChain(request, principal));
|
||||
|
||||
final LoginCredentials preAuthenticatedCredentials = new LoginCredentials(principal, null);
|
||||
return new LoginAuthenticationToken(preAuthenticatedCredentials);
|
||||
}
|
||||
|
||||
// extract the principal
|
||||
final String principal = extractPrincipal(certificate);
|
||||
|
||||
try {
|
||||
certificateValidator.validateClientCertificate(request, certificate);
|
||||
} catch (CertificateExpiredException cee) {
|
||||
final String message = String.format("Client certificate for (%s) is expired.", principal);
|
||||
logger.info(message, cee);
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("", cee);
|
||||
}
|
||||
return null;
|
||||
} catch (CertificateNotYetValidException cnyve) {
|
||||
final String message = String.format("Client certificate for (%s) is not yet valid.", principal);
|
||||
logger.info(message, cnyve);
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("", cnyve);
|
||||
}
|
||||
return null;
|
||||
} catch (final Exception e) {
|
||||
logger.info(e.getMessage());
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("", e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
// authorize the proxy if necessary
|
||||
authorizeProxyIfNecessary(ProxiedEntitiesUtils.buildProxyChain(request, principal));
|
||||
|
||||
final LoginCredentials preAuthenticatedCredentials = new LoginCredentials(principal, null);
|
||||
return new LoginAuthenticationToken(preAuthenticatedCredentials);
|
||||
} else {
|
||||
if (loginIdentityProvider.authenticate(credentials)) {
|
||||
return new LoginAuthenticationToken(credentials);
|
||||
|
@ -178,39 +187,15 @@ public class LoginAuthenticationFilter extends AbstractAuthenticationProcessingF
|
|||
|
||||
@Override
|
||||
protected void unsuccessfulAuthentication(final HttpServletRequest request, final HttpServletResponse response, final AuthenticationException failed) throws IOException, ServletException {
|
||||
// set the response status
|
||||
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
|
||||
response.setContentType("text/plain");
|
||||
|
||||
|
||||
final PrintWriter out = response.getWriter();
|
||||
out.println("Unable to authenticate.");
|
||||
}
|
||||
|
||||
/**
|
||||
* This is an Authentication Token for logging in. Once a user is authenticated, they can be issues an ID token.
|
||||
*/
|
||||
public static class LoginAuthenticationToken extends AbstractAuthenticationToken {
|
||||
|
||||
final LoginCredentials credentials;
|
||||
|
||||
public LoginAuthenticationToken(final LoginCredentials credentials) {
|
||||
super(null);
|
||||
setAuthenticated(true);
|
||||
this.credentials = credentials;
|
||||
}
|
||||
|
||||
public LoginCredentials getLoginCredentials() {
|
||||
return credentials;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getCredentials() {
|
||||
return credentials.getPassword();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getPrincipal() {
|
||||
return credentials.getUsername();
|
||||
out.println(failed.getMessage());
|
||||
|
||||
if (failed instanceof BadCredentialsException || failed instanceof AuthenticationCredentialsNotFoundException) {
|
||||
response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
|
||||
} else {
|
||||
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,160 @@
|
|||
/*
|
||||
* 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.form;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import javax.servlet.FilterChain;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import org.apache.nifi.admin.service.AccountDisabledException;
|
||||
import org.apache.nifi.admin.service.AccountNotFoundException;
|
||||
import org.apache.nifi.admin.service.AccountPendingException;
|
||||
import org.apache.nifi.admin.service.AdministrationException;
|
||||
import org.apache.nifi.admin.service.UserService;
|
||||
import org.apache.nifi.authentication.LoginCredentials;
|
||||
import org.apache.nifi.authentication.LoginIdentityProvider;
|
||||
import org.apache.nifi.authorization.exception.IdentityAlreadyExistsException;
|
||||
import org.apache.nifi.util.StringUtils;
|
||||
import org.apache.nifi.web.security.jwt.JwtService;
|
||||
import org.apache.nifi.web.security.token.LoginAuthenticationToken;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.security.authentication.AccountStatusException;
|
||||
import org.springframework.security.authentication.AuthenticationServiceException;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.core.AuthenticationException;
|
||||
import org.springframework.security.core.userdetails.UsernameNotFoundException;
|
||||
import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter;
|
||||
|
||||
/**
|
||||
* Exchanges a successful login with the configured provider for a ID token for accessing the API.
|
||||
*/
|
||||
public class RegistrationFilter extends AbstractAuthenticationProcessingFilter {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(RegistrationFilter.class);
|
||||
|
||||
private LoginIdentityProvider loginIdentityProvider;
|
||||
private JwtService jwtService;
|
||||
private UserService userService;
|
||||
|
||||
public RegistrationFilter(final String defaultFilterProcessesUrl) {
|
||||
super(defaultFilterProcessesUrl);
|
||||
|
||||
// do not continue filter chain... simply exchanging authentication for token
|
||||
setContinueChainBeforeSuccessfulAuthentication(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Authentication attemptAuthentication(final HttpServletRequest request, final HttpServletResponse response) throws AuthenticationException, IOException, ServletException {
|
||||
// only suppport registration when running securely
|
||||
if (!request.isSecure()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// look for the credentials in the request
|
||||
final LoginCredentials credentials = getLoginCredentials(request);
|
||||
|
||||
// if the credentials were not part of the request, attempt to log in with the certificate in the request
|
||||
if (credentials == null) {
|
||||
throw new UsernameNotFoundException("User login credentials not found in request.");
|
||||
} else {
|
||||
try {
|
||||
// attempt to register the user
|
||||
loginIdentityProvider.register(credentials);
|
||||
} catch (final IdentityAlreadyExistsException iaee) {
|
||||
// if the identity already exists, try to create the nifi account request
|
||||
}
|
||||
|
||||
try {
|
||||
// see if the account already exists so we're able to return the current status
|
||||
userService.checkAuthorization(credentials.getUsername());
|
||||
|
||||
// account exists and is valid
|
||||
throw new AccountStatusException(String.format("An account for %s already exists.", credentials.getUsername())) {
|
||||
};
|
||||
} catch (AdministrationException ase) {
|
||||
throw new AuthenticationServiceException(ase.getMessage(), ase);
|
||||
} catch (AccountDisabledException | AccountPendingException e) {
|
||||
throw new AccountStatusException(e.getMessage(), e) {
|
||||
};
|
||||
} catch (AccountNotFoundException anfe) {
|
||||
// create the pending user account
|
||||
userService.createPendingUserAccount(credentials.getUsername(), request.getParameter("justification"));
|
||||
|
||||
// create the login token
|
||||
return new LoginAuthenticationToken(credentials);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private LoginCredentials getLoginCredentials(HttpServletRequest request) {
|
||||
final String username = request.getParameter("username");
|
||||
final String password = request.getParameter("password");
|
||||
|
||||
if (StringUtils.isBlank(username) || StringUtils.isBlank(password)) {
|
||||
return null;
|
||||
} else {
|
||||
return new LoginCredentials(username, password);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void successfulAuthentication(final HttpServletRequest request, final HttpServletResponse response, final FilterChain chain, final Authentication authentication)
|
||||
throws IOException, ServletException {
|
||||
|
||||
// generate JWT for response
|
||||
jwtService.addToken(response, authentication);
|
||||
|
||||
// mark as successful
|
||||
response.setStatus(HttpServletResponse.SC_CREATED);
|
||||
response.setContentType("text/plain");
|
||||
response.setContentLength(0);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void unsuccessfulAuthentication(final HttpServletRequest request, final HttpServletResponse response, final AuthenticationException failed) throws IOException, ServletException {
|
||||
response.setContentType("text/plain");
|
||||
|
||||
final PrintWriter out = response.getWriter();
|
||||
out.println(failed.getMessage());
|
||||
|
||||
// set the appropriate response status
|
||||
if (failed instanceof UsernameNotFoundException) {
|
||||
response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
|
||||
} else if (failed instanceof AccountStatusException) {
|
||||
// account exists (maybe valid, pending, revoked)
|
||||
response.setStatus(HttpServletResponse.SC_FORBIDDEN);
|
||||
} else {
|
||||
response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
public void setJwtService(JwtService jwtService) {
|
||||
this.jwtService = jwtService;
|
||||
}
|
||||
|
||||
public void setLoginIdentityProvider(LoginIdentityProvider loginIdentityProvider) {
|
||||
this.loginIdentityProvider = loginIdentityProvider;
|
||||
}
|
||||
|
||||
public void setUserService(UserService userService) {
|
||||
this.userService = userService;
|
||||
}
|
||||
|
||||
}
|
|
@ -50,7 +50,7 @@ public class JwtService {
|
|||
* @param authentication The authentication to generate a token for
|
||||
*/
|
||||
public void addToken(final HttpServletResponse response, final Authentication authentication) {
|
||||
// TODO : actually create real token
|
||||
// TODO : actually create real token... in header or response body?
|
||||
|
||||
// create a token the specified authentication
|
||||
String token = authentication.getName();
|
||||
|
|
|
@ -0,0 +1,48 @@
|
|||
/*
|
||||
* 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.token;
|
||||
|
||||
import org.apache.nifi.authentication.LoginCredentials;
|
||||
import org.springframework.security.authentication.AbstractAuthenticationToken;
|
||||
|
||||
/**
|
||||
* This is an Authentication Token for logging in. Once a user is authenticated, they can be issues an ID token.
|
||||
*/
|
||||
public class LoginAuthenticationToken extends AbstractAuthenticationToken {
|
||||
|
||||
final LoginCredentials credentials;
|
||||
|
||||
public LoginAuthenticationToken(final LoginCredentials credentials) {
|
||||
super(null);
|
||||
setAuthenticated(true);
|
||||
this.credentials = credentials;
|
||||
}
|
||||
|
||||
public LoginCredentials getLoginCredentials() {
|
||||
return credentials;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getCredentials() {
|
||||
return credentials.getPassword();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getPrincipal() {
|
||||
return credentials.getUsername();
|
||||
}
|
||||
}
|
|
@ -28,6 +28,7 @@
|
|||
<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/jquery.center.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>
|
||||
|
@ -42,5 +43,8 @@
|
|||
<jsp:include page="/WEB-INF/partials/login/nifi-registration-form.jsp"/>
|
||||
<jsp:include page="/WEB-INF/partials/login/login-submission.jsp"/>
|
||||
</div>
|
||||
<jsp:include page="/WEB-INF/partials/ok-dialog.jsp"/>
|
||||
<div id="faded-background"></div>
|
||||
<div id="glass-pane"></div>
|
||||
</body>
|
||||
</html>
|
|
@ -27,6 +27,10 @@
|
|||
<div class="setting-name">Password</div>
|
||||
<div class="setting-field">
|
||||
<input type="password" id="password"/>
|
||||
<div id="create-account-message" class="hidden">
|
||||
<div style="font-style: italic;">Don't have an account?</div>
|
||||
<div><span id="create-account-link" class="link">Create one</span> to request access.</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
|
@ -16,18 +16,19 @@
|
|||
--%>
|
||||
<%@ page contentType="text/html" pageEncoding="UTF-8" session="false" %>
|
||||
<div id="user-registration-container" class="hidden">
|
||||
<div class="login-title">Log In</div>
|
||||
<div class="login-title">Create Account</div>
|
||||
<div class="setting">
|
||||
<div class="setting-name">Username</div>
|
||||
<div class="setting-field">
|
||||
<input type="text" id="username"/>
|
||||
<input type="text" id="registration-username"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="setting">
|
||||
<div class="setting-name">Password</div>
|
||||
<div class="setting-field">
|
||||
<input type="password" id="password"/><br/>
|
||||
<input type="password" id="password-confirmation" placeholder="Confirm password"/>
|
||||
<input type="password" id="registration-password" style="margin-bottom: 5px;"/>
|
||||
<br/>
|
||||
<input type="password" id="registration-password-confirmation" placeholder="Confirm password"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
|
@ -19,7 +19,7 @@
|
|||
Login Styles
|
||||
*/
|
||||
|
||||
body.login-body {
|
||||
#login-contents-container {
|
||||
position: absolute;
|
||||
top: 0px;
|
||||
left: 0px;
|
||||
|
@ -27,13 +27,8 @@ body.login-body {
|
|||
right: 0px;
|
||||
background: #fff url(../images/bg-error.png) left top no-repeat;
|
||||
font-family: Verdana, Geneva, sans-serif;
|
||||
color: #191919;
|
||||
z-index: 999999;
|
||||
}
|
||||
|
||||
#login-contents-container {
|
||||
margin-top: 100px;
|
||||
margin-left: 100px;
|
||||
padding-top: 100px;
|
||||
padding-left: 100px;
|
||||
}
|
||||
|
||||
#login-message-title {
|
||||
|
@ -61,6 +56,14 @@ body.login-body input, body.login-body textarea {
|
|||
width: 400px;
|
||||
}
|
||||
|
||||
#create-account-message {
|
||||
margin-top: 2px;
|
||||
}
|
||||
|
||||
#create-account-link {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
/*
|
||||
User Registration
|
||||
*/
|
||||
|
|
|
@ -1044,7 +1044,6 @@ nf.Canvas = (function () {
|
|||
dataType: 'json'
|
||||
});
|
||||
|
||||
|
||||
// load the identity and authorities for the current user
|
||||
var userXhr = $.Deferred(function(deferred) {
|
||||
$.when(authoritiesXhr, identityXhr).done(function (authoritiesResult, identityResult) {
|
||||
|
@ -1059,22 +1058,15 @@ nf.Canvas = (function () {
|
|||
// if the user is logged, we want to determine if they were logged in using a certificate
|
||||
if (identityResponse.identity !== 'anonymous') {
|
||||
$('#current-user').text(identityResponse.identity).show();
|
||||
|
||||
// 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.
|
||||
|
||||
// render the logout button if there is a token locally
|
||||
if (nf.Storage.getItem('jwt') !== null) {
|
||||
$('#logout-link-container').show();
|
||||
}).always(function () {
|
||||
deferred.resolve();
|
||||
});
|
||||
}
|
||||
} else {
|
||||
$('#current-user').text(nf.Canvas.ANONYMOUS_USER_TEXT).show();
|
||||
deferred.resolve();
|
||||
}
|
||||
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) {
|
||||
|
|
|
@ -44,133 +44,182 @@ nf.Login = (function () {
|
|||
// if this nifi supports registration, render the registration form
|
||||
if (supportsRegistration === true) {
|
||||
initializeUserRegistration();
|
||||
|
||||
// automatically include support for nifi registration
|
||||
initializeNiFiRegistration();
|
||||
|
||||
// hide the submit justification title
|
||||
$('#nifi-registration-title').hide();
|
||||
// show the create account message
|
||||
$('#create-account-message').show();
|
||||
|
||||
// update the submit button text
|
||||
$('#login-submission-button').text('Create');
|
||||
// toggle between login and signup
|
||||
$('#create-account-link').on('click', function () {
|
||||
showUserRegistration();
|
||||
});
|
||||
}
|
||||
|
||||
// show the login form
|
||||
};
|
||||
|
||||
var showLogin = function () {
|
||||
$('#login-container').show();
|
||||
$('#user-registration-container').hide();
|
||||
$('#nifi-registration-container').hide();
|
||||
$('#login-submission-button').text('Log in');
|
||||
};
|
||||
|
||||
var initializeUserRegistration = function () {
|
||||
|
||||
// show the user registration form
|
||||
$('#user-registration-container').show();
|
||||
};
|
||||
|
||||
var initializeNiFiRegistration = function () {
|
||||
$('#nifi-registration-justification').count({
|
||||
charCountField: '#remaining-characters'
|
||||
});
|
||||
};
|
||||
|
||||
// update the button text
|
||||
$('#login-submission-button').text('Submit');
|
||||
var showUserRegistration = function () {
|
||||
showNiFiRegistration();
|
||||
|
||||
// show the nifi registration container
|
||||
$('#nifi-registration-title').hide();
|
||||
$('#user-registration-container').show();
|
||||
$('#login-submission-button').text('Create');
|
||||
};
|
||||
|
||||
var showNiFiRegistration = function () {
|
||||
$('#login-container').hide();
|
||||
$('#nifi-registration-container').show();
|
||||
$('#login-submission-button').text('Submit');
|
||||
};
|
||||
|
||||
var initializeSubmission = function () {
|
||||
$('#login-submission-button').one('click', function () {
|
||||
$('#login-submission-button').on('click', function () {
|
||||
if ($('#login-container').is(':visible')) {
|
||||
var username = $('#username').val();
|
||||
var password = $('#password').val();
|
||||
|
||||
// login submit
|
||||
$.ajax({
|
||||
type: 'POST',
|
||||
url: '../nifi-api/token',
|
||||
data: {
|
||||
'username': username,
|
||||
'password': password
|
||||
}
|
||||
}).done(function (response, status, xhr) {
|
||||
var authorization = xhr.getResponseHeader('Authorization');
|
||||
var badToken = false;
|
||||
|
||||
// ensure there was a token in the response
|
||||
if (authorization) {
|
||||
var tokens = authorization.split(/ /);
|
||||
|
||||
// ensure the token is the appropriate length
|
||||
if (tokens.length === 2) {
|
||||
// store the jwt and reload the page
|
||||
nf.Storage.setItem('jwt', tokens[1]);
|
||||
|
||||
// reload as appropriate
|
||||
if (top !== window) {
|
||||
parent.window.location = '/nifi';
|
||||
} else {
|
||||
window.location = '/nifi';
|
||||
}
|
||||
return;
|
||||
} else {
|
||||
badToken = true;
|
||||
}
|
||||
} else {
|
||||
badToken = true;
|
||||
}
|
||||
|
||||
if (badToken === true) {
|
||||
$('#login-message-title').text('An unexpected error has occurred');
|
||||
$('#login-message').text('The id token could not be parsed.');
|
||||
|
||||
// update visibility
|
||||
$('#login-container').hide();
|
||||
$('#login-submission-container').hide();
|
||||
$('#login-message-container').show();
|
||||
}
|
||||
}).fail(function (xhr, status, error) {
|
||||
$('#login-message-title').text('An unexpected error has occurred');
|
||||
$('#login-message').text(xhr.responseText);
|
||||
|
||||
// update visibility
|
||||
$('#login-container').hide();
|
||||
$('#login-submission-container').hide();
|
||||
$('#login-message-container').show();
|
||||
});
|
||||
login();
|
||||
} else if ($('#user-registration-container').is(':visible')) {
|
||||
var justification = $('#registration-justification').val();
|
||||
|
||||
// new user account submit
|
||||
createUserAccount();
|
||||
} else if ($('#nifi-registration-container').is(':visible')) {
|
||||
// attempt to create the user account registration
|
||||
$.ajax({
|
||||
type: 'POST',
|
||||
url: config.urls.users,
|
||||
data: {
|
||||
'justification': $('#registration-justification').val()
|
||||
}
|
||||
}).done(function (response) {
|
||||
var markup = 'An administrator will process your request shortly.';
|
||||
if (isAnonymous === true) {
|
||||
markup += '<br/><br/>In the meantime you can continue accessing anonymously.';
|
||||
}
|
||||
|
||||
$('#login-message-title').text('Thanks!');
|
||||
$('#login-message').html(markup);
|
||||
}).fail(function (xhr, status, error) {
|
||||
$('#login-message-title').text('An unexpected error has occurred');
|
||||
$('#login-message').text(xhr.responseText);
|
||||
}).always(function () {
|
||||
// update form visibility
|
||||
$('#nifi-registration-container').hide();
|
||||
$('#login-submission-container').hide();
|
||||
$('#login-message-container').show();
|
||||
});
|
||||
submitJustification();
|
||||
}
|
||||
});
|
||||
|
||||
$('#login-submission-container').show();
|
||||
};
|
||||
|
||||
var login = function () {
|
||||
// login submit
|
||||
$.ajax({
|
||||
type: 'POST',
|
||||
url: config.urls.token,
|
||||
data: {
|
||||
'username': $('#username').val(),
|
||||
'password': $('#password').val()
|
||||
}
|
||||
}).done(function (response, status, xhr) {
|
||||
var authorization = xhr.getResponseHeader('Authorization');
|
||||
var badToken = false;
|
||||
|
||||
// ensure there was a token in the response
|
||||
if (authorization) {
|
||||
var tokens = authorization.split(/ /);
|
||||
|
||||
// ensure the token is the appropriate length
|
||||
if (tokens.length === 2) {
|
||||
// store the jwt and reload the page
|
||||
nf.Storage.setItem('jwt', tokens[1]);
|
||||
|
||||
// reload as appropriate
|
||||
if (top !== window) {
|
||||
parent.window.location = '/nifi';
|
||||
} else {
|
||||
window.location = '/nifi';
|
||||
}
|
||||
return;
|
||||
} else {
|
||||
badToken = true;
|
||||
}
|
||||
} else {
|
||||
badToken = true;
|
||||
}
|
||||
|
||||
if (badToken === true) {
|
||||
$('#login-message-title').text('An unexpected error has occurred');
|
||||
$('#login-message').text('The user token could not be parsed.');
|
||||
|
||||
// update visibility
|
||||
$('#login-container').hide();
|
||||
$('#login-submission-container').hide();
|
||||
$('#login-message-container').show();
|
||||
}
|
||||
}).fail(function (xhr, status, error) {
|
||||
if (xhr.status === 400) {
|
||||
nf.Dialog.showOkDialog({
|
||||
dialogContent: nf.Common.escapeHtml(xhr.responseText),
|
||||
overlayBackground: false
|
||||
});
|
||||
} else {
|
||||
$('#login-message-title').text('Unable to log in');
|
||||
$('#login-message').text(xhr.responseText);
|
||||
|
||||
// update visibility
|
||||
$('#login-container').hide();
|
||||
$('#login-submission-container').hide();
|
||||
$('#login-message-container').show();
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
var createUserAccount = function () {
|
||||
// attempt to create the user account registration
|
||||
$.ajax({
|
||||
type: 'POST',
|
||||
url: config.urls.registration,
|
||||
data: {
|
||||
'username': $('#registration-username').val(),
|
||||
'password': $('#registration-password').val(),
|
||||
'justification': $('#nifi-registration-justification').val()
|
||||
}
|
||||
}).done(function (response, status, xhr) {
|
||||
var markup = 'An administrator will process your request shortly.';
|
||||
if (isAnonymous === true) {
|
||||
markup += '<br/><br/>In the meantime you can continue accessing anonymously.';
|
||||
}
|
||||
|
||||
$('#login-message-title').text('Thanks!');
|
||||
$('#login-message').html(markup);
|
||||
}).fail(function (xhr, status, error) {
|
||||
$('#login-message-title').text('Unable to create user account');
|
||||
$('#login-message').text(xhr.responseText);
|
||||
}).always(function () {
|
||||
// update form visibility
|
||||
$('#user-registration-container').hide();
|
||||
$('#nifi-registration-container').hide();
|
||||
$('#login-submission-container').hide();
|
||||
$('#login-message-container').show();
|
||||
});
|
||||
};
|
||||
|
||||
var submitJustification = function () {
|
||||
// attempt to create the nifi account registration
|
||||
$.ajax({
|
||||
type: 'POST',
|
||||
url: config.urls.users,
|
||||
data: {
|
||||
'justification': $('#nifi-registration-justification').val()
|
||||
}
|
||||
}).done(function (response) {
|
||||
var markup = 'An administrator will process your request shortly.';
|
||||
if (isAnonymous === true) {
|
||||
markup += '<br/><br/>In the meantime you can continue accessing anonymously.';
|
||||
}
|
||||
|
||||
$('#login-message-title').text('Thanks!');
|
||||
$('#login-message').html(markup);
|
||||
}).fail(function (xhr, status, error) {
|
||||
$('#login-message-title').text('Unable to submit justification');
|
||||
$('#login-message').text(xhr.responseText);
|
||||
}).always(function () {
|
||||
// update form visibility
|
||||
$('#nifi-registration-container').hide();
|
||||
$('#login-submission-container').hide();
|
||||
$('#login-message-container').show();
|
||||
});
|
||||
};
|
||||
|
||||
return {
|
||||
/**
|
||||
* Initializes the login page.
|
||||
|
@ -202,7 +251,7 @@ nf.Login = (function () {
|
|||
|
||||
// request a token without including credentials, if successful then the user is using a certificate
|
||||
token.done(function () {
|
||||
// the user is using a certificate, see if their account is active/pending/revoked/etc
|
||||
// the user is using a certificate/token, see if their account is active/pending/revoked/etc
|
||||
$.ajax({
|
||||
type: 'GET',
|
||||
url: config.urls.registrationStatus
|
||||
|
@ -212,7 +261,6 @@ nf.Login = (function () {
|
|||
// account is active and good
|
||||
$('#login-message-title').text('Success');
|
||||
$('#login-message').text('Your account is active and you are already logged in.');
|
||||
deferred.resolve();
|
||||
}).fail(function (xhr, status, error) {
|
||||
if (xhr.status === 401) {
|
||||
// anonymous user and 401 means they need nifi registration
|
||||
|
@ -228,6 +276,7 @@ nf.Login = (function () {
|
|||
$('#login-message').text(xhr.responseText);
|
||||
}
|
||||
}
|
||||
}).always(function () {
|
||||
deferred.resolve();
|
||||
});
|
||||
}).fail(function () {
|
||||
|
@ -248,7 +297,7 @@ nf.Login = (function () {
|
|||
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
|
||||
// 401 from identity request and 200 from token means they have a certificate/token but have not yet requested an account
|
||||
needsNiFiRegistration = true;
|
||||
}).fail(function () {
|
||||
// no token granted, user needs to login with their credentials
|
||||
|
@ -271,7 +320,7 @@ nf.Login = (function () {
|
|||
}
|
||||
});
|
||||
}).promise();
|
||||
|
||||
|
||||
var loginConfigXhr = $.ajax({
|
||||
type: 'GET',
|
||||
url: config.urls.loginConfig,
|
||||
|
@ -282,7 +331,7 @@ nf.Login = (function () {
|
|||
$.when(loginConfigXhr, pageStateInit).done(function (loginResult) {
|
||||
var loginResponse = loginResult[0];
|
||||
var loginConfig = loginResponse.config;
|
||||
|
||||
|
||||
// if login is required, verify its supported
|
||||
if (loginConfig.supportsLogin === false && needsLogin === true) {
|
||||
$('#login-message-title').text('Access Denied');
|
||||
|
@ -290,13 +339,15 @@ nf.Login = (function () {
|
|||
showMessage = true;
|
||||
needsLogin = false;
|
||||
}
|
||||
|
||||
|
||||
if (showMessage === true) {
|
||||
initializeMessage();
|
||||
} else if (needsLogin === true) {
|
||||
initializeLogin(loginConfig.supportsRegistration);
|
||||
showLogin();
|
||||
} else if (needsNiFiRegistration === true) {
|
||||
initializeNiFiRegistration();
|
||||
showNiFiRegistration();
|
||||
}
|
||||
|
||||
if (needsLogin === true || needsNiFiRegistration === true) {
|
||||
|
|
Loading…
Reference in New Issue