You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nifi.apache.org by mc...@apache.org on 2015/12/01 17:43:42 UTC
[04/51] [abbrv] nifi git commit: NIFI-655: - Refactoring certificate
extraction and validation. - Refactoring how expiration is specified in the
login identity providers. - Adding unit tests for the access endpoints. -
Code clean up.
NIFI-655:
- Refactoring certificate extraction and validation.
- Refactoring how expiration is specified in the login identity providers.
- Adding unit tests for the access endpoints.
- Code clean up.
Project: http://git-wip-us.apache.org/repos/asf/nifi/repo
Commit: http://git-wip-us.apache.org/repos/asf/nifi/commit/a1962077
Tree: http://git-wip-us.apache.org/repos/asf/nifi/tree/a1962077
Diff: http://git-wip-us.apache.org/repos/asf/nifi/diff/a1962077
Branch: refs/heads/master
Commit: a196207725a37aecaccc8c7858cec3a4d1c4ff55
Parents: 7529694
Author: Matt Gilman <ma...@gmail.com>
Authored: Tue Nov 17 17:02:41 2015 -0500
Committer: Matt Gilman <ma...@gmail.com>
Committed: Tue Nov 17 17:02:41 2015 -0500
----------------------------------------------------------------------
.../authentication/AuthenticationResponse.java | 14 +-
.../authentication/LoginIdentityProvider.java | 7 -
.../web/NiFiWebApiSecurityConfiguration.java | 25 +-
.../org/apache/nifi/web/api/AccessResource.java | 188 ++++++-----
.../nifi/web/api/ApplicationResource.java | 8 +-
.../nifi/web/controller/ControllerFacade.java | 2 +-
.../src/main/resources/nifi-web-api-context.xml | 3 +-
.../accesscontrol/AccessTokenEndpointTest.java | 292 +++++++++++++++++
.../util/NiFiTestAuthorizationProvider.java | 3 +-
.../util/NiFiTestLoginIdentityProvider.java | 75 +++++
.../nifi/integration/util/NiFiTestServer.java | 9 +-
.../nifi/integration/util/NiFiTestUser.java | 229 ++++++++++++--
...he.nifi.authentication.LoginIdentityProvider | 15 +
.../access-control/controller-services.xml | 18 --
.../access-control/login-identity-providers.xml | 24 ++
.../resources/access-control/nifi.properties | 9 +-
.../access-control/reporting-tasks.xml | 17 -
.../web/security/NiFiAuthenticationFilter.java | 14 +-
.../security/NiFiAuthenticationProvider.java | 8 +-
.../nifi/web/security/ProxiedEntitiesUtils.java | 117 +++----
.../authorization/NiFiAuthorizationService.java | 15 +-
.../security/jwt/JwtAuthenticationFilter.java | 3 +-
.../nifi/web/security/jwt/JwtService.java | 2 +-
.../security/node/NodeAuthorizedUserFilter.java | 68 ++--
.../LoginIdentityProviderFactoryBean.java | 7 -
.../security/x509/X509AuthenticationFilter.java | 63 +---
.../x509/X509AuthenticationFilterOld.java | 317 -------------------
.../security/x509/X509CertificateExtractor.java | 4 +-
.../security/x509/X509CertificateValidator.java | 10 +-
.../web/security/x509/X509IdentityProvider.java | 92 ++++++
.../x509/ocsp/OcspCertificateValidator.java | 20 +-
.../resources/nifi-web-security-context.xml | 6 +
.../NiFiAuthorizationServiceTest.java | 2 +-
.../src/main/webapp/js/nf/login/nf-login.js | 2 -
.../apache/nifi/ldap/AbstractLdapProvider.java | 9 +-
35 files changed, 985 insertions(+), 712 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/nifi/blob/a1962077/nifi-api/src/main/java/org/apache/nifi/authentication/AuthenticationResponse.java
----------------------------------------------------------------------
diff --git a/nifi-api/src/main/java/org/apache/nifi/authentication/AuthenticationResponse.java b/nifi-api/src/main/java/org/apache/nifi/authentication/AuthenticationResponse.java
index 8f57810..a64947b 100644
--- a/nifi-api/src/main/java/org/apache/nifi/authentication/AuthenticationResponse.java
+++ b/nifi-api/src/main/java/org/apache/nifi/authentication/AuthenticationResponse.java
@@ -23,16 +23,19 @@ public class AuthenticationResponse {
private final String identity;
private final String username;
+ private final long expiration;
/**
* Creates an authentication response. The username and how long the authentication is valid in milliseconds
*
* @param identity The user identity
* @param username The username
+ * @param expiration The expiration in milliseconds
*/
- public AuthenticationResponse(final String identity, final String username) {
+ public AuthenticationResponse(final String identity, final String username, final long expiration) {
this.identity = identity;
this.username = username;
+ this.expiration = expiration;
}
public String getIdentity() {
@@ -43,4 +46,13 @@ public class AuthenticationResponse {
return username;
}
+ /**
+ * Returns the expiration of a given authentication in milliseconds.
+ *
+ * @return The expiration in milliseconds
+ */
+ public long getExpiration() {
+ return expiration;
+ }
+
}
http://git-wip-us.apache.org/repos/asf/nifi/blob/a1962077/nifi-api/src/main/java/org/apache/nifi/authentication/LoginIdentityProvider.java
----------------------------------------------------------------------
diff --git a/nifi-api/src/main/java/org/apache/nifi/authentication/LoginIdentityProvider.java b/nifi-api/src/main/java/org/apache/nifi/authentication/LoginIdentityProvider.java
index 5f4db40..54becb3 100644
--- a/nifi-api/src/main/java/org/apache/nifi/authentication/LoginIdentityProvider.java
+++ b/nifi-api/src/main/java/org/apache/nifi/authentication/LoginIdentityProvider.java
@@ -37,13 +37,6 @@ public interface LoginIdentityProvider {
AuthenticationResponse authenticate(LoginCredentials credentials) throws InvalidLoginCredentialsException, IdentityAccessException;
/**
- * Returns the expiration of a given authentication in milliseconds.
- *
- * @return The expiration in milliseconds
- */
- long getExpiration();
-
- /**
* Called immediately after instance creation for implementers to perform additional setup
*
* @param initializationContext in which to initialize
http://git-wip-us.apache.org/repos/asf/nifi/blob/a1962077/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 216e311..e8ed267 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
@@ -28,7 +28,7 @@ import org.apache.nifi.web.security.node.NodeAuthorizedUserFilter;
import org.apache.nifi.web.security.token.NiFiAuthenticationRequestToken;
import org.apache.nifi.web.security.x509.X509AuthenticationFilter;
import org.apache.nifi.web.security.x509.X509CertificateExtractor;
-import org.apache.nifi.web.security.x509.X509CertificateValidator;
+import org.apache.nifi.web.security.x509.X509IdentityProvider;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@@ -42,7 +42,6 @@ import org.springframework.security.config.annotation.web.configuration.WebSecur
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.core.userdetails.AuthenticationUserDetailsService;
import org.springframework.security.web.authentication.AnonymousAuthenticationFilter;
-import org.springframework.security.web.authentication.preauth.x509.X509PrincipalExtractor;
/**
* NiFi Web Api Spring security
@@ -56,9 +55,8 @@ public class NiFiWebApiSecurityConfiguration extends WebSecurityConfigurerAdapte
private UserService userService;
private AuthenticationUserDetailsService userDetailsService;
private JwtService jwtService;
- private X509CertificateValidator certificateValidator;
private X509CertificateExtractor certificateExtractor;
- private X509PrincipalExtractor principalExtractor;
+ private X509IdentityProvider certificateIdentityProvider;
private LoginIdentityProvider loginIdentityProvider;
public NiFiWebApiSecurityConfiguration() {
@@ -113,7 +111,11 @@ public class NiFiWebApiSecurityConfiguration extends WebSecurityConfigurerAdapte
}
private NodeAuthorizedUserFilter buildNodeAuthorizedUserFilter() {
- return new NodeAuthorizedUserFilter(properties);
+ final NodeAuthorizedUserFilter nodeFilter = new NodeAuthorizedUserFilter();
+ nodeFilter.setProperties(properties);
+ nodeFilter.setCertificateExtractor(certificateExtractor);
+ nodeFilter.setCertificateIdentityProvider(certificateIdentityProvider);
+ return nodeFilter;
}
private JwtAuthenticationFilter buildJwtFilter() throws Exception {
@@ -127,9 +129,8 @@ public class NiFiWebApiSecurityConfiguration extends WebSecurityConfigurerAdapte
private X509AuthenticationFilter buildX509Filter() throws Exception {
final X509AuthenticationFilter x509Filter = new X509AuthenticationFilter();
x509Filter.setProperties(properties);
- x509Filter.setPrincipalExtractor(principalExtractor);
x509Filter.setCertificateExtractor(certificateExtractor);
- x509Filter.setCertificateValidator(certificateValidator);
+ x509Filter.setCertificateIdentityProvider(certificateIdentityProvider);
x509Filter.setAuthenticationManager(authenticationManager());
return x509Filter;
}
@@ -166,17 +167,13 @@ public class NiFiWebApiSecurityConfiguration extends WebSecurityConfigurerAdapte
}
@Autowired
- public void setCertificateValidator(X509CertificateValidator certificateValidator) {
- this.certificateValidator = certificateValidator;
- }
-
- @Autowired
public void setCertificateExtractor(X509CertificateExtractor certificateExtractor) {
this.certificateExtractor = certificateExtractor;
}
@Autowired
- public void setPrincipalExtractor(X509PrincipalExtractor principalExtractor) {
- this.principalExtractor = principalExtractor;
+ public void setCertificateIdentityProvider(X509IdentityProvider certificateIdentityProvider) {
+ this.certificateIdentityProvider = certificateIdentityProvider;
}
+
}
http://git-wip-us.apache.org/repos/asf/nifi/blob/a1962077/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/AccessResource.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/AccessResource.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/AccessResource.java
index 9cb4141..67eb8b4 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/AccessResource.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/AccessResource.java
@@ -30,8 +30,6 @@ import com.wordnik.swagger.annotations.ApiParam;
import com.wordnik.swagger.annotations.ApiResponse;
import com.wordnik.swagger.annotations.ApiResponses;
import java.net.URI;
-import java.security.cert.CertificateExpiredException;
-import java.security.cert.CertificateNotYetValidException;
import java.security.cert.X509Certificate;
import java.util.Arrays;
import java.util.List;
@@ -41,6 +39,7 @@ import javax.ws.rs.FormParam;
import javax.ws.rs.POST;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.Context;
+import org.apache.commons.lang3.StringUtils;
import org.apache.nifi.admin.service.AdministrationException;
import org.apache.nifi.authentication.AuthenticationResponse;
import org.apache.nifi.authentication.LoginCredentials;
@@ -48,8 +47,6 @@ import org.apache.nifi.authentication.LoginIdentityProvider;
import org.apache.nifi.authentication.exception.IdentityAccessException;
import org.apache.nifi.authentication.exception.InvalidLoginCredentialsException;
import org.apache.nifi.security.util.CertificateUtils;
-import org.apache.nifi.util.StringUtils;
-import static org.apache.nifi.web.api.ApplicationResource.CLIENT_ID;
import org.apache.nifi.web.api.dto.AccessStatusDTO;
import org.apache.nifi.web.api.dto.AccessConfigurationDTO;
import org.apache.nifi.web.api.dto.RevisionDTO;
@@ -62,15 +59,15 @@ import org.apache.nifi.web.security.jwt.JwtService;
import org.apache.nifi.web.security.token.LoginAuthenticationToken;
import org.apache.nifi.web.security.token.NiFiAuthenticationRequestToken;
import org.apache.nifi.web.security.x509.X509CertificateExtractor;
-import org.apache.nifi.web.security.x509.X509CertificateValidator;
+import org.apache.nifi.web.security.x509.X509IdentityProvider;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.authentication.AccountStatusException;
-import org.springframework.security.authentication.AuthenticationCredentialsNotFoundException;
import org.springframework.security.authentication.AuthenticationServiceException;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.AuthenticationUserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
-import org.springframework.security.web.authentication.preauth.x509.X509PrincipalExtractor;
/**
* RESTful endpoint for managing a cluster.
@@ -82,13 +79,15 @@ import org.springframework.security.web.authentication.preauth.x509.X509Principa
)
public class AccessResource extends ApplicationResource {
- private NiFiProperties properties;
+ private static final Logger logger = LoggerFactory.getLogger(AccessResource.class);
- private X509CertificateValidator certificateValidator;
- private X509CertificateExtractor certificateExtractor;
- private X509PrincipalExtractor principalExtractor;
+ private static final String AUTHORIZATION = "Authorization";
+
+ private NiFiProperties properties;
private LoginIdentityProvider loginIdentityProvider;
+ private X509CertificateExtractor certificateExtractor;
+ private X509IdentityProvider certificateIdentityProvider;
private JwtService jwtService;
private AuthenticationUserDetailsService<NiFiAuthenticationRequestToken> userDetailsService;
@@ -172,57 +171,64 @@ public class AccessResource extends ApplicationResource {
final AccessStatusDTO accessStatus = new AccessStatusDTO();
try {
- // look for a certificate
- final X509Certificate certificate = certificateExtractor.extractClientCertificate(httpServletRequest);
+ final X509Certificate[] certificates = certificateExtractor.extractClientCertificate(httpServletRequest);
- // if no certificate, just check the credentials
- if (certificate == null) {
- final String principal = jwtService.getAuthentication(httpServletRequest);
+ // if there is not certificate, consider a token
+ if (certificates == null) {
+ // look for an authorization token
+ final String authorization = httpServletRequest.getHeader(AUTHORIZATION);
- // ensure we have something we can work with (certificate or crendentials)
- if (principal == null) {
+ // if there is no authorization header, we don't know the user
+ if (authorization == null) {
accessStatus.setStatus(AccessStatusDTO.Status.UNKNOWN.name());
accessStatus.setMessage("No credentials supplied, unknown user.");
} else {
- // set the user identity
- accessStatus.setIdentity(principal);
- accessStatus.setUsername(CertificateUtils.extractUsername(principal));
-
- // without a certificate, this is not a proxied request
- final List<String> chain = Arrays.asList(principal);
-
- // check authorization for this user
- checkAuthorization(chain);
-
- // no issues with authorization
- accessStatus.setStatus(AccessStatusDTO.Status.ACTIVE.name());
- accessStatus.setStatus("Account is active and authorized");
+ // TODO - use this token with the JWT service
+ final String token = StringUtils.substringAfterLast(authorization, " ");
+
+ // TODO - do not call this method of the jwt service
+ final String principal = jwtService.getAuthentication(httpServletRequest);
+
+ // TODO - catch jwt exception?
+ // ensure we have something we can work with (certificate or crendentials)
+ if (principal == null) {
+ throw new IllegalArgumentException("The specific token is not valid.");
+ } else {
+ // set the user identity
+ accessStatus.setIdentity(principal);
+ accessStatus.setUsername(CertificateUtils.extractUsername(principal));
+
+ // without a certificate, this is not a proxied request
+ final List<String> chain = Arrays.asList(principal);
+
+ // check authorization for this user
+ checkAuthorization(chain);
+
+ // no issues with authorization
+ accessStatus.setStatus(AccessStatusDTO.Status.ACTIVE.name());
+ accessStatus.setMessage("Account is active and authorized");
+ }
}
} else {
- // we have a certificate so let's consider a proxy chain
- final String principal = principalExtractor.extractPrincipal(certificate).toString();
-
- try {
- // validate the certificate
- certificateValidator.validateClientCertificate(httpServletRequest, certificate);
- } catch (CertificateExpiredException cee) {
- throw new IllegalArgumentException(String.format("Client certificate for (%s) is expired.", principal), cee);
- } catch (CertificateNotYetValidException cnyve) {
- throw new IllegalArgumentException(String.format("Client certificate for (%s) is not yet valid.", principal), cnyve);
- } catch (final Exception e) {
- throw new IllegalArgumentException(e.getMessage(), e);
- }
+ final AuthenticationResponse authenticationResponse = certificateIdentityProvider.authenticate(certificates);
- // set the user identity
- accessStatus.setIdentity(principal);
- accessStatus.setUsername(CertificateUtils.extractUsername(principal));
+ // get the proxy chain and ensure its populated
+ final List<String> proxyChain = ProxiedEntitiesUtils.buildProxiedEntitiesChain(httpServletRequest, authenticationResponse.getIdentity());
+ if (proxyChain.isEmpty()) {
+ logger.error(String.format("Unable to parse the proxy chain %s from the incoming request.", authenticationResponse.getIdentity()));
+ throw new IllegalArgumentException("Unable to determine the user from the incoming request.");
+ }
// ensure the proxy chain is authorized
- checkAuthorization(ProxiedEntitiesUtils.buildProxyChain(httpServletRequest, principal));
+ checkAuthorization(proxyChain);
+
+ // set the user identity
+ accessStatus.setIdentity(proxyChain.get(0));
+ accessStatus.setUsername(CertificateUtils.extractUsername(proxyChain.get(0)));
// no issues with authorization
accessStatus.setStatus(AccessStatusDTO.Status.ACTIVE.name());
- accessStatus.setStatus("Account is active and authorized");
+ accessStatus.setMessage("Account is active and authorized");
}
} catch (final UsernameNotFoundException unfe) {
accessStatus.setStatus(AccessStatusDTO.Status.UNREGISTERED.name());
@@ -277,6 +283,7 @@ public class AccessResource extends ApplicationResource {
@ApiResponses(
value = {
@ApiResponse(code = 400, message = "NiFi was unable to complete the request because it was invalid. The request should not be retried without modification."),
+ @ApiResponse(code = 403, message = "Client is not authorized to make this request."),
@ApiResponse(code = 409, message = "The request was valid but NiFi was not in the appropriate state to process it. Retrying the same request later may be successful.")
}
)
@@ -297,58 +304,42 @@ public class AccessResource extends ApplicationResource {
final LoginAuthenticationToken loginAuthenticationToken;
- // if we don't have username/password, consider JWT or x509
- if (StringUtils.isBlank(username) || StringUtils.isBlank(password)) {
- // look for a certificate
- final X509Certificate certificate = certificateExtractor.extractClientCertificate(httpServletRequest);
-
- // 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 IllegalStateException("Login not supported.");
- }
+ final X509Certificate[] certificates = certificateExtractor.extractClientCertificate(httpServletRequest);
- // look for the principal
- final String principal = jwtService.getAuthentication(httpServletRequest);
- if (principal == null) {
- throw new AuthenticationCredentialsNotFoundException("Unable to issue token as issue token as no credentials were found in the request.");
- }
-
- // create the authentication token
- loginAuthenticationToken = new LoginAuthenticationToken(principal, loginIdentityProvider.getExpiration());
- } else {
- // extract the principal
- final String principal = principalExtractor.extractPrincipal(certificate).toString();
-
- try {
- certificateValidator.validateClientCertificate(httpServletRequest, certificate);
- } catch (CertificateExpiredException cee) {
- throw new IllegalArgumentException(String.format("Client certificate for (%s) is expired.", principal), cee);
- } catch (CertificateNotYetValidException cnyve) {
- throw new IllegalArgumentException(String.format("Client certificate for (%s) is not yet valid.", principal), cnyve);
- } catch (final Exception e) {
- throw new IllegalArgumentException(e.getMessage(), e);
- }
-
- // authorize the proxy if necessary
- authorizeProxyIfNecessary(ProxiedEntitiesUtils.buildProxyChain(httpServletRequest, principal));
-
- // create the authentication token
- loginAuthenticationToken = new LoginAuthenticationToken(principal, loginIdentityProvider.getExpiration());
+ // if there is not certificate, consider login credentials
+ if (certificates == null) {
+ // ensure we have login credentials
+ if (StringUtils.isBlank(username) || StringUtils.isBlank(password)) {
+ throw new IllegalArgumentException("The username and password must be specified.");
}
- } else {
+
try {
// attempt to authenticate
final AuthenticationResponse authenticationResponse = loginIdentityProvider.authenticate(new LoginCredentials(username, password));
// create the authentication token
- loginAuthenticationToken = new LoginAuthenticationToken(authenticationResponse.getUsername(), loginIdentityProvider.getExpiration());
+ loginAuthenticationToken = new LoginAuthenticationToken(authenticationResponse.getUsername(), authenticationResponse.getExpiration());
} catch (final InvalidLoginCredentialsException ilce) {
throw new IllegalArgumentException("The supplied username and password are not valid.", ilce);
} catch (final IdentityAccessException iae) {
throw new AdministrationException(iae.getMessage(), iae);
}
+ } else {
+ // consider a certificate
+ final AuthenticationResponse authenticationResponse = certificateIdentityProvider.authenticate(certificates);
+
+ // get the proxy chain and ensure its populated
+ final List<String> proxyChain = ProxiedEntitiesUtils.buildProxiedEntitiesChain(httpServletRequest, authenticationResponse.getIdentity());
+ if (proxyChain.isEmpty()) {
+ logger.error(String.format("Unable to parse the proxy chain %s from the incoming request.", authenticationResponse.getIdentity()));
+ throw new IllegalArgumentException("Unable to determine the user from the incoming request.");
+ }
+
+ // authorize the proxy if necessary
+ authorizeProxyIfNecessary(proxyChain);
+
+ // create the authentication token
+ loginAuthenticationToken = new LoginAuthenticationToken(proxyChain.get(0), authenticationResponse.getExpiration());
}
// generate JWT for response
@@ -371,11 +362,14 @@ public class AccessResource extends ApplicationResource {
userDetailsService.loadUserDetails(new NiFiAuthenticationRequestToken(proxyChain));
} catch (final UsernameNotFoundException unfe) {
// if a username not found exception was thrown, the proxies were authorized and now
- // we can issue a new ID token to the end user
+ // we can issue a new token to the end user which they will use to identify themselves
+ // when they enter a new account request
+ } catch (final AuthenticationServiceException ase) {
+ // throw an administration exception which will return a 500
+ throw new AdministrationException(ase.getMessage(), ase);
} catch (final Exception e) {
- // any other issue we're going to treat as an authentication exception which will return 401
- throw new AdministrationException(e.getMessage(), e) {
- };
+ // any other issue we're going to treat as access denied exception which will return 403
+ throw new AccessDeniedException(e.getMessage(), e);
}
}
}
@@ -393,16 +387,12 @@ public class AccessResource extends ApplicationResource {
this.jwtService = jwtService;
}
- public void setCertificateValidator(X509CertificateValidator certificateValidator) {
- this.certificateValidator = certificateValidator;
- }
-
public void setCertificateExtractor(X509CertificateExtractor certificateExtractor) {
this.certificateExtractor = certificateExtractor;
}
- public void setPrincipalExtractor(X509PrincipalExtractor principalExtractor) {
- this.principalExtractor = principalExtractor;
+ public void setCertificateIdentityProvider(X509IdentityProvider certificateIdentityProvider) {
+ this.certificateIdentityProvider = certificateIdentityProvider;
}
public void setUserDetailsService(AuthenticationUserDetailsService<NiFiAuthenticationRequestToken> userDetailsService) {
http://git-wip-us.apache.org/repos/asf/nifi/blob/a1962077/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ApplicationResource.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ApplicationResource.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ApplicationResource.java
index 2e15d30..d0c36d4 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ApplicationResource.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ApplicationResource.java
@@ -53,6 +53,8 @@ import org.apache.nifi.web.util.WebUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.builder.ReflectionToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
+import org.apache.nifi.user.NiFiUser;
+import org.apache.nifi.web.security.user.NiFiUserUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.core.Authentication;
@@ -363,9 +365,9 @@ public abstract class ApplicationResource {
if (httpServletRequest.isSecure()) {
// add the certificate DN to the proxy chain
- final String xProxiedEntitiesChain = ProxiedEntitiesUtils.getXProxiedEntitiesChain(httpServletRequest);
- if (StringUtils.isNotBlank(xProxiedEntitiesChain)) {
- result.put(PROXIED_ENTITIES_CHAIN_HTTP_HEADER, xProxiedEntitiesChain);
+ final NiFiUser user = NiFiUserUtils.getNiFiUser();
+ if (user != null) {
+ result.put(PROXIED_ENTITIES_CHAIN_HTTP_HEADER, ProxiedEntitiesUtils.buildProxiedEntitiesChainString(user));
}
// add the user's authorities (if any) to the headers
http://git-wip-us.apache.org/repos/asf/nifi/blob/a1962077/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/controller/ControllerFacade.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/controller/ControllerFacade.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/controller/ControllerFacade.java
index 0e1b20b..a02d1fd 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/controller/ControllerFacade.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/controller/ControllerFacade.java
@@ -823,7 +823,7 @@ public class ControllerFacade {
final Map<String, String> attributes = event.getAttributes();
// calculate the dn chain
- final List<String> dnChain = ProxiedEntitiesUtils.getXProxiedEntitiesChain(user);
+ final List<String> dnChain = ProxiedEntitiesUtils.buildProxiedEntitiesChain(user);
// ensure the users in this chain are allowed to download this content
final DownloadAuthorization downloadAuthorization = userService.authorizeDownload(dnChain, attributes);
http://git-wip-us.apache.org/repos/asf/nifi/blob/a1962077/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/resources/nifi-web-api-context.xml
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/resources/nifi-web-api-context.xml b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/resources/nifi-web-api-context.xml
index e992dc9..73929d8 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/resources/nifi-web-api-context.xml
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/resources/nifi-web-api-context.xml
@@ -243,9 +243,8 @@
</bean>
<bean id="accessResource" class="org.apache.nifi.web.api.AccessResource" scope="singleton">
<property name="properties" ref="nifiProperties"/>
- <property name="certificateValidator" ref="certificateValidator"/>
<property name="certificateExtractor" ref="certificateExtractor"/>
- <property name="principalExtractor" ref="principalExtractor"/>
+ <property name="certificateIdentityProvider" ref="certificateIdentityProvider"/>
<property name="loginIdentityProvider" ref="loginIdentityProvider"/>
<property name="jwtService" ref="jwtService"/>
<property name="userDetailsService" ref="userDetailsService"/>
http://git-wip-us.apache.org/repos/asf/nifi/blob/a1962077/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/test/java/org/apache/nifi/integration/accesscontrol/AccessTokenEndpointTest.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/test/java/org/apache/nifi/integration/accesscontrol/AccessTokenEndpointTest.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/test/java/org/apache/nifi/integration/accesscontrol/AccessTokenEndpointTest.java
new file mode 100644
index 0000000..82fe73a
--- /dev/null
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/test/java/org/apache/nifi/integration/accesscontrol/AccessTokenEndpointTest.java
@@ -0,0 +1,292 @@
+/*
+ * 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.integration.accesscontrol;
+
+import com.sun.jersey.api.client.Client;
+import com.sun.jersey.api.client.ClientResponse;
+import java.io.File;
+import java.util.HashMap;
+import java.util.Map;
+import javax.net.ssl.SSLContext;
+import org.apache.commons.io.FileUtils;
+import org.apache.nifi.integration.util.NiFiTestServer;
+import org.apache.nifi.integration.util.NiFiTestUser;
+import org.apache.nifi.integration.util.SourceTestProcessor;
+import org.apache.nifi.nar.ExtensionManager;
+import org.apache.nifi.nar.NarClassLoaders;
+import org.apache.nifi.security.util.SslContextFactory;
+import org.apache.nifi.util.NiFiProperties;
+import org.apache.nifi.web.api.dto.AccessConfigurationDTO;
+import org.apache.nifi.web.api.dto.AccessStatusDTO;
+import org.apache.nifi.web.api.dto.ProcessorDTO;
+import org.apache.nifi.web.api.dto.RevisionDTO;
+import org.apache.nifi.web.api.entity.AccessConfigurationEntity;
+import org.apache.nifi.web.api.entity.AccessStatusEntity;
+import org.apache.nifi.web.api.entity.ProcessorEntity;
+import org.apache.nifi.web.util.WebUtils;
+import org.junit.AfterClass;
+import org.junit.Assert;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+/**
+ * Access token endpoint test.
+ */
+public class AccessTokenEndpointTest {
+
+ private static final String CLIENT_ID = "token-endpoint-id";
+ private static final String CONTEXT_PATH = "/nifi-api";
+ private static final String FLOW_XML_PATH = "target/test-classes/access-control/flow-admin.xml";
+
+ private static NiFiTestServer SERVER;
+ private static NiFiTestUser TOKEN_USER;
+ private static String BASE_URL;
+
+ @BeforeClass
+ public static void setup() throws Exception {
+ // configure the location of the nifi properties
+ File nifiPropertiesFile = new File("src/test/resources/access-control/nifi.properties");
+ System.setProperty(NiFiProperties.PROPERTIES_FILE_PATH, nifiPropertiesFile.getAbsolutePath());
+
+ // update the flow.xml property
+ NiFiProperties props = NiFiProperties.getInstance();
+ props.setProperty("nifi.flow.configuration.file", FLOW_XML_PATH);
+
+ // delete the database directory to avoid issues with re-registration in testRequestAccessUsingToken
+ FileUtils.deleteDirectory(props.getDatabaseRepositoryPath().toFile());
+
+ // load extensions
+ NarClassLoaders.load(props);
+ ExtensionManager.discoverExtensions();
+
+ // start the server
+ SERVER = new NiFiTestServer("src/main/webapp", CONTEXT_PATH);
+ SERVER.startServer();
+ SERVER.loadFlow();
+
+ // get the base url
+ BASE_URL = SERVER.getBaseUrl() + CONTEXT_PATH;
+
+ // create the user
+ final Client client = WebUtils.createClient(null, createTrustContext(props));
+ TOKEN_USER = new NiFiTestUser(client, null);
+ }
+
+ private static SSLContext createTrustContext(final NiFiProperties props) throws Exception {
+ return SslContextFactory.createTrustSslContext(props.getProperty(NiFiProperties.SECURITY_TRUSTSTORE),
+ props.getProperty(NiFiProperties.SECURITY_TRUSTSTORE_PASSWD).toCharArray(),
+ props.getProperty(NiFiProperties.SECURITY_TRUSTSTORE_TYPE), "TLS");
+ }
+
+ // -----------
+ // LOGIN CONIG
+ // -----------
+ /**
+ * Test getting access configuration.
+ *
+ * @throws Exception ex
+ */
+ @Test
+ public void testGetAccessConfig() throws Exception {
+ String url = BASE_URL + "/access/config";
+
+ ClientResponse response = TOKEN_USER.testGet(url);
+
+ // ensure the request is successful
+ Assert.assertEquals(200, response.getStatus());
+
+ // extract the process group
+ AccessConfigurationEntity accessConfigEntity = response.getEntity(AccessConfigurationEntity.class);
+
+ // ensure there is content
+ Assert.assertNotNull(accessConfigEntity);
+
+ // extract the process group dto
+ AccessConfigurationDTO accessConfig = accessConfigEntity.getConfig();
+
+ // verify config
+ Assert.assertTrue(accessConfig.getSupportsLogin());
+ Assert.assertFalse(accessConfig.getSupportsAnonymous());
+ }
+
+ /**
+ * Obtains a token and creates a processor using it.
+ *
+ * @throws Exception ex
+ */
+ @Test
+ public void testCreateProcessorUsingToken() throws Exception {
+ String url = BASE_URL + "/access/token";
+
+ ClientResponse response = TOKEN_USER.testCreateToken(url, "user@nifi", "whateve");
+
+ // ensure the request is successful
+ Assert.assertEquals(201, response.getStatus());
+
+ // get the token
+ String token = response.getEntity(String.class);
+
+ // attempt to create a processor with it
+ createProcessor(token);
+ }
+
+ private ProcessorDTO createProcessor(final String token) throws Exception {
+ String url = BASE_URL + "/controller/process-groups/root/processors";
+
+ // authorization header
+ Map<String, String> headers = new HashMap<>();
+ headers.put("Authorization", "Bearer " + token);
+
+ // create the processor
+ ProcessorDTO processor = new ProcessorDTO();
+ processor.setName("Copy");
+ processor.setType(SourceTestProcessor.class.getName());
+
+ // create the revision
+ final RevisionDTO revision = new RevisionDTO();
+ revision.setClientId(CLIENT_ID);
+ revision.setVersion(NiFiTestUser.REVISION);
+
+ // create the entity body
+ ProcessorEntity entity = new ProcessorEntity();
+ entity.setRevision(revision);
+ entity.setProcessor(processor);
+
+ // perform the request
+ ClientResponse response = TOKEN_USER.testPostWithHeaders(url, entity, headers);
+
+ // ensure the request is successful
+ Assert.assertEquals(201, response.getStatus());
+
+ // get the entity body
+ entity = response.getEntity(ProcessorEntity.class);
+
+ // verify creation
+ processor = entity.getProcessor();
+ Assert.assertEquals("Copy", processor.getName());
+ Assert.assertEquals("org.apache.nifi.integration.util.SourceTestProcessor", processor.getType());
+
+ return processor;
+ }
+
+ /**
+ * Verifies the response when bad credentials are specified.
+ *
+ * @throws Exception ex
+ */
+ @Test
+ public void testInvalidCredentials() throws Exception {
+ String url = BASE_URL + "/access/token";
+
+ ClientResponse response = TOKEN_USER.testCreateToken(url, "user@nifi", "not a real password");
+
+ // ensure the request is successful
+ Assert.assertEquals(400, response.getStatus());
+ }
+
+ /**
+ * Verifies the response when the user is known.
+ *
+ * @throws Exception ex
+ */
+ @Test
+ public void testUnkownUser() throws Exception {
+ String url = BASE_URL + "/access/token";
+
+ ClientResponse response = TOKEN_USER.testCreateToken(url, "not a real user", "not a real password");
+
+ // ensure the request is successful
+ Assert.assertEquals(400, response.getStatus());
+ }
+
+ /**
+ * Request access using access token.
+ *
+ * @throws Exception ex
+ */
+ @Test
+ public void testRequestAccessUsingToken() throws Exception {
+ String accessStatusUrl = BASE_URL + "/access";
+ String accessTokenUrl = BASE_URL + "/access/token";
+ String registrationUrl = BASE_URL + "/controller/users";
+
+ ClientResponse response = TOKEN_USER.testGet(accessStatusUrl);
+
+ // ensure the request is successful
+ Assert.assertEquals(200, response.getStatus());
+
+ AccessStatusEntity accessStatusEntity = response.getEntity(AccessStatusEntity.class);
+ AccessStatusDTO accessStatus = accessStatusEntity.getAccessStatus();
+
+ // verify unknown
+ Assert.assertEquals("UNKNOWN", accessStatus.getStatus());
+
+ response = TOKEN_USER.testCreateToken(accessTokenUrl, "unregistered-user@nifi", "password");
+
+ // ensure the request is successful
+ Assert.assertEquals(201, response.getStatus());
+
+ // get the token
+ String token = response.getEntity(String.class);
+
+ // authorization header
+ Map<String, String> headers = new HashMap<>();
+ headers.put("Authorization", "Bearer " + token);
+
+ // check the status with the token
+ response = TOKEN_USER.testGetWithHeaders(accessStatusUrl, null, headers);
+
+ // ensure the request is successful
+ Assert.assertEquals(200, response.getStatus());
+
+ accessStatusEntity = response.getEntity(AccessStatusEntity.class);
+ accessStatus = accessStatusEntity.getAccessStatus();
+
+ // verify unregistered
+ Assert.assertEquals("UNREGISTERED", accessStatus.getStatus());
+
+ response = TOKEN_USER.testRegisterUser(registrationUrl, "Gimme access", headers);
+
+ // ensure the request is successful
+ Assert.assertEquals(201, response.getStatus());
+
+ // check the status with the token
+ response = TOKEN_USER.testGetWithHeaders(accessStatusUrl, null, headers);
+
+ // ensure the request is successful
+ Assert.assertEquals(200, response.getStatus());
+
+ accessStatusEntity = response.getEntity(AccessStatusEntity.class);
+ accessStatus = accessStatusEntity.getAccessStatus();
+
+ // verify unregistered
+ Assert.assertEquals("NOT_ACTIVE", accessStatus.getStatus());
+ }
+
+ @AfterClass
+ public static void cleanup() throws Exception {
+ // shutdown the server
+ SERVER.shutdownServer();
+ SERVER = null;
+
+ // look for the flow.xml
+ File flow = new File(FLOW_XML_PATH);
+ if (flow.exists()) {
+ flow.delete();
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/nifi/blob/a1962077/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/test/java/org/apache/nifi/integration/util/NiFiTestAuthorizationProvider.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/test/java/org/apache/nifi/integration/util/NiFiTestAuthorizationProvider.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/test/java/org/apache/nifi/integration/util/NiFiTestAuthorizationProvider.java
index d51b7df..d29be92 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/test/java/org/apache/nifi/integration/util/NiFiTestAuthorizationProvider.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/test/java/org/apache/nifi/integration/util/NiFiTestAuthorizationProvider.java
@@ -37,7 +37,7 @@ import org.apache.nifi.authorization.DownloadAuthorization;
*/
public class NiFiTestAuthorizationProvider implements AuthorityProvider {
- private Map<String, Set<Authority>> users;
+ private final Map<String, Set<Authority>> users;
/**
* Creates a new FileAuthorizationProvider.
@@ -48,6 +48,7 @@ public class NiFiTestAuthorizationProvider implements AuthorityProvider {
users.put("CN=Lastname Firstname Middlename monitor, OU=Unknown, OU=Unknown, OU=Unknown, O=Unknown, C=Unknown", EnumSet.of(Authority.ROLE_MONITOR));
users.put("CN=Lastname Firstname Middlename dfm, OU=Unknown, OU=Unknown, OU=Unknown, O=Unknown, C=Unknown", EnumSet.of(Authority.ROLE_DFM));
users.put("CN=Lastname Firstname Middlename admin, OU=Unknown, OU=Unknown, OU=Unknown, O=Unknown, C=Unknown", EnumSet.of(Authority.ROLE_ADMIN));
+ users.put("user@nifi", EnumSet.of(Authority.ROLE_DFM));
}
@Override
http://git-wip-us.apache.org/repos/asf/nifi/blob/a1962077/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/test/java/org/apache/nifi/integration/util/NiFiTestLoginIdentityProvider.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/test/java/org/apache/nifi/integration/util/NiFiTestLoginIdentityProvider.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/test/java/org/apache/nifi/integration/util/NiFiTestLoginIdentityProvider.java
new file mode 100644
index 0000000..8ee51d9
--- /dev/null
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/test/java/org/apache/nifi/integration/util/NiFiTestLoginIdentityProvider.java
@@ -0,0 +1,75 @@
+/*
+ * 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.integration.util;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.TimeUnit;
+import org.apache.nifi.authorization.exception.ProviderCreationException;
+import org.apache.nifi.authentication.AuthenticationResponse;
+import org.apache.nifi.authentication.LoginCredentials;
+import org.apache.nifi.authentication.LoginIdentityProvider;
+import org.apache.nifi.authentication.LoginIdentityProviderConfigurationContext;
+import org.apache.nifi.authentication.LoginIdentityProviderInitializationContext;
+import org.apache.nifi.authentication.exception.IdentityAccessException;
+import org.apache.nifi.authentication.exception.InvalidLoginCredentialsException;
+
+/**
+ *
+ */
+public class NiFiTestLoginIdentityProvider implements LoginIdentityProvider {
+
+ private final Map<String, String> users;
+
+ /**
+ * Creates a new FileAuthorizationProvider.
+ */
+ public NiFiTestLoginIdentityProvider() {
+ users = new HashMap<>();
+ users.put("user@nifi", "whateve");
+ users.put("unregistered-user@nifi", "password");
+ }
+
+ private void checkUser(final String user, final String password) {
+ if (!users.containsKey(user)) {
+ throw new InvalidLoginCredentialsException("Unknown user");
+ }
+
+ if (!users.get(user).equals(password)) {
+ throw new InvalidLoginCredentialsException("Invalid password");
+ }
+ }
+
+ @Override
+ public AuthenticationResponse authenticate(LoginCredentials credentials) throws InvalidLoginCredentialsException, IdentityAccessException {
+ checkUser(credentials.getUsername(), credentials.getPassword());
+ return new AuthenticationResponse(credentials.getUsername(), credentials.getUsername(), TimeUnit.MILLISECONDS.convert(1, TimeUnit.DAYS));
+ }
+
+ @Override
+ public void initialize(LoginIdentityProviderInitializationContext initializationContext) throws ProviderCreationException {
+ }
+
+ @Override
+ public void onConfigured(LoginIdentityProviderConfigurationContext configurationContext) throws ProviderCreationException {
+ }
+
+ @Override
+ public void preDestruction() {
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/nifi/blob/a1962077/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/test/java/org/apache/nifi/integration/util/NiFiTestServer.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/test/java/org/apache/nifi/integration/util/NiFiTestServer.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/test/java/org/apache/nifi/integration/util/NiFiTestServer.java
index 42b0aab..38c2d41 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/test/java/org/apache/nifi/integration/util/NiFiTestServer.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/test/java/org/apache/nifi/integration/util/NiFiTestServer.java
@@ -78,8 +78,12 @@ public class NiFiTestServer {
private void createSecureConnector() {
org.eclipse.jetty.util.ssl.SslContextFactory contextFactory = new org.eclipse.jetty.util.ssl.SslContextFactory();
- // need client auth
- contextFactory.setNeedClientAuth(properties.getNeedClientAuth());
+ // require client auth when not supporting login or anonymous access
+ if (StringUtils.isBlank(properties.getProperty(NiFiProperties.SECURITY_USER_LOGIN_IDENTITY_PROVIDER)) && properties.getAnonymousAuthorities().isEmpty()) {
+ contextFactory.setNeedClientAuth(true);
+ } else {
+ contextFactory.setWantClientAuth(true);
+ }
/* below code sets JSSE system properties when values are provided */
// keystore properties
@@ -163,7 +167,6 @@ public class NiFiTestServer {
}
public Client getClient() {
- // create the client
return WebUtils.createClient(null, SslContextFactory.createSslContext(properties));
}
http://git-wip-us.apache.org/repos/asf/nifi/blob/a1962077/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/test/java/org/apache/nifi/integration/util/NiFiTestUser.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/test/java/org/apache/nifi/integration/util/NiFiTestUser.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/test/java/org/apache/nifi/integration/util/NiFiTestUser.java
index c0e9246..621dc09 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/test/java/org/apache/nifi/integration/util/NiFiTestUser.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/test/java/org/apache/nifi/integration/util/NiFiTestUser.java
@@ -34,9 +34,27 @@ public class NiFiTestUser {
private final Client client;
private final String proxyDn;
- public NiFiTestUser(Client client, String dn) {
+ public NiFiTestUser(Client client, String proxyDn) {
this.client = client;
- this.proxyDn = ProxiedEntitiesUtils.formatProxyDn(dn);
+ if (proxyDn != null) {
+ this.proxyDn = ProxiedEntitiesUtils.formatProxyDn(proxyDn);
+ } else {
+ this.proxyDn = null;
+ }
+ }
+
+ /**
+ * Conditionally adds the proxied entities chain.
+ *
+ * @param builder the resource builder
+ * @return the resource builder
+ */
+ private WebResource.Builder addProxiedEntities(final WebResource.Builder builder) {
+ if (proxyDn == null) {
+ return builder;
+ } else {
+ return builder.header(ProxiedEntitiesUtils.PROXY_ENTITIES_CHAIN, proxyDn);
+ }
}
/**
@@ -58,6 +76,18 @@ public class NiFiTestUser {
* @return response
*/
public ClientResponse testGet(String url, Map<String, String> queryParams) {
+ return testGetWithHeaders(url, queryParams, null);
+ }
+
+ /**
+ * Performs a GET using the specified url and query parameters.
+ *
+ * @param url url
+ * @param queryParams params
+ * @param headers http headers
+ * @return response
+ */
+ public ClientResponse testGetWithHeaders(String url, Map<String, String> queryParams, Map<String, String> headers) {
// get the resource
WebResource resource = client.resource(url);
@@ -68,8 +98,18 @@ public class NiFiTestUser {
}
}
+ // get the builder
+ WebResource.Builder builder = addProxiedEntities(resource.accept(MediaType.APPLICATION_JSON));
+
+ // append any headers
+ if (headers != null && !headers.isEmpty()) {
+ for (String key : headers.keySet()) {
+ builder = builder.header(key, headers.get(key));
+ }
+ }
+
// perform the query
- return resource.accept(MediaType.APPLICATION_JSON).header(ProxiedEntitiesUtils.PROXY_ENTITIES_CHAIN, proxyDn).get(ClientResponse.class);
+ return builder.get(ClientResponse.class);
}
/**
@@ -92,14 +132,34 @@ public class NiFiTestUser {
* @throws Exception ex
*/
public ClientResponse testPost(String url, Object entity) throws Exception {
+ return testPostWithHeaders(url, entity, null);
+ }
+
+ /**
+ * Performs a POST using the specified url and entity body.
+ *
+ * @param url url
+ * @param entity entity
+ * @param headers http headers
+ * @return response
+ * @throws Exception ex
+ */
+ public ClientResponse testPostWithHeaders(String url, Object entity, Map<String, String> headers) throws Exception {
// get the resource
- WebResource.Builder resourceBuilder = client.resource(url).accept(MediaType.APPLICATION_JSON).type(MediaType.APPLICATION_JSON).header(ProxiedEntitiesUtils.PROXY_ENTITIES_CHAIN, proxyDn);
+ WebResource.Builder resourceBuilder = addProxiedEntities(client.resource(url).accept(MediaType.APPLICATION_JSON).type(MediaType.APPLICATION_JSON));
// include the request entity
if (entity != null) {
resourceBuilder = resourceBuilder.entity(entity);
}
+ // append any headers
+ if (headers != null && !headers.isEmpty()) {
+ for (String key : headers.keySet()) {
+ resourceBuilder = resourceBuilder.header(key, headers.get(key));
+ }
+ }
+
// perform the request
return resourceBuilder.post(ClientResponse.class);
}
@@ -109,18 +169,38 @@ public class NiFiTestUser {
*
* @param url url
* @param entity entity
- * @return repsonse
+ * @return response
* @throws Exception ex
*/
public ClientResponse testPostMultiPart(String url, Object entity) throws Exception {
+ return testPostMultiPartWithHeaders(url, entity, null);
+ }
+
+ /**
+ * Performs a POST using the specified url and entity body.
+ *
+ * @param url url
+ * @param entity entity
+ * @param headers http headers
+ * @return response
+ * @throws Exception ex
+ */
+ public ClientResponse testPostMultiPartWithHeaders(String url, Object entity, Map<String, String> headers) throws Exception {
// get the resource
- WebResource.Builder resourceBuilder = client.resource(url).accept(MediaType.APPLICATION_XML).type(MediaType.MULTIPART_FORM_DATA).header(ProxiedEntitiesUtils.PROXY_ENTITIES_CHAIN, proxyDn);
+ WebResource.Builder resourceBuilder = addProxiedEntities(client.resource(url).accept(MediaType.APPLICATION_XML).type(MediaType.MULTIPART_FORM_DATA));
// include the request entity
if (entity != null) {
resourceBuilder = resourceBuilder.entity(entity);
}
+ // append any headers
+ if (headers != null && !headers.isEmpty()) {
+ for (String key : headers.keySet()) {
+ resourceBuilder = resourceBuilder.header(key, headers.get(key));
+ }
+ }
+
// perform the request
return resourceBuilder.post(ClientResponse.class);
}
@@ -134,6 +214,19 @@ public class NiFiTestUser {
* @throws java.lang.Exception ex
*/
public ClientResponse testPost(String url, Map<String, String> formData) throws Exception {
+ return testPostWithHeaders(url, formData, null);
+ }
+
+ /**
+ * Performs a POST using the specified url and form data.
+ *
+ * @param url url
+ * @param formData form data
+ * @param headers http headers
+ * @return response
+ * @throws java.lang.Exception ex
+ */
+ public ClientResponse testPostWithHeaders(String url, Map<String, String> formData, Map<String, String> headers) throws Exception {
// convert the form data
MultivaluedMapImpl entity = new MultivaluedMapImpl();
for (String key : formData.keySet()) {
@@ -141,14 +234,20 @@ public class NiFiTestUser {
}
// get the resource
- WebResource.Builder resourceBuilder
- = client.resource(url).accept(MediaType.APPLICATION_JSON).type(MediaType.APPLICATION_FORM_URLENCODED).header(ProxiedEntitiesUtils.PROXY_ENTITIES_CHAIN, proxyDn);
+ WebResource.Builder resourceBuilder = addProxiedEntities(client.resource(url).accept(MediaType.APPLICATION_JSON).type(MediaType.APPLICATION_FORM_URLENCODED));
// add the form data if necessary
if (!entity.isEmpty()) {
resourceBuilder = resourceBuilder.entity(entity);
}
+ // append any headers
+ if (headers != null && !headers.isEmpty()) {
+ for (String key : headers.keySet()) {
+ resourceBuilder = resourceBuilder.header(key, headers.get(key));
+ }
+ }
+
// perform the request
return resourceBuilder.post(ClientResponse.class);
}
@@ -162,14 +261,34 @@ public class NiFiTestUser {
* @throws java.lang.Exception ex
*/
public ClientResponse testPut(String url, Object entity) throws Exception {
+ return testPutWithHeaders(url, entity, null);
+ }
+
+ /**
+ * Performs a PUT using the specified url and entity body.
+ *
+ * @param url url
+ * @param entity entity
+ * @param headers http headers
+ * @return response
+ * @throws java.lang.Exception ex
+ */
+ public ClientResponse testPutWithHeaders(String url, Object entity, Map<String, String> headers) throws Exception {
// get the resource
- WebResource.Builder resourceBuilder = client.resource(url).accept(MediaType.APPLICATION_JSON).type(MediaType.APPLICATION_JSON).header(ProxiedEntitiesUtils.PROXY_ENTITIES_CHAIN, proxyDn);
+ WebResource.Builder resourceBuilder = addProxiedEntities(client.resource(url).accept(MediaType.APPLICATION_JSON).type(MediaType.APPLICATION_JSON));
// include the request entity
if (entity != null) {
resourceBuilder = resourceBuilder.entity(entity);
}
+ // append any headers
+ if (headers != null && !headers.isEmpty()) {
+ for (String key : headers.keySet()) {
+ resourceBuilder = resourceBuilder.header(key, headers.get(key));
+ }
+ }
+
// perform the request
return resourceBuilder.put(ClientResponse.class);
}
@@ -183,6 +302,19 @@ public class NiFiTestUser {
* @throws java.lang.Exception ex
*/
public ClientResponse testPut(String url, Map<String, String> formData) throws Exception {
+ return testPutWithHeaders(url, formData, null);
+ }
+
+ /**
+ * Performs a PUT using the specified url and form data.
+ *
+ * @param url url
+ * @param formData form data
+ * @param headers http headers
+ * @return response
+ * @throws java.lang.Exception ex
+ */
+ public ClientResponse testPutWithHeaders(String url, Map<String, String> formData, Map<String, String> headers) throws Exception {
// convert the form data
MultivaluedMapImpl entity = new MultivaluedMapImpl();
for (String key : formData.keySet()) {
@@ -190,14 +322,20 @@ public class NiFiTestUser {
}
// get the resource
- WebResource.Builder resourceBuilder
- = client.resource(url).accept(MediaType.APPLICATION_JSON).type(MediaType.APPLICATION_FORM_URLENCODED).header(ProxiedEntitiesUtils.PROXY_ENTITIES_CHAIN, proxyDn);
+ WebResource.Builder resourceBuilder = addProxiedEntities(client.resource(url).accept(MediaType.APPLICATION_JSON).type(MediaType.APPLICATION_FORM_URLENCODED));
// add the form data if necessary
if (!entity.isEmpty()) {
resourceBuilder = resourceBuilder.entity(entity);
}
+ // append any headers
+ if (headers != null && !headers.isEmpty()) {
+ for (String key : headers.keySet()) {
+ resourceBuilder = resourceBuilder.header(key, headers.get(key));
+ }
+ }
+
// perform the request
return resourceBuilder.put(ClientResponse.class);
}
@@ -210,24 +348,26 @@ public class NiFiTestUser {
* @throws java.lang.Exception ex
*/
public ClientResponse testDelete(String url) throws Exception {
- return testDelete(url, (Object) null);
+ return testDelete(url, null);
}
/**
* Performs a DELETE using the specified url and entity.
*
* @param url url
- * @param entity entity
- * @return repsonse
+ * @param headers http headers
+ * @return response
* @throws java.lang.Exception ex
*/
- public ClientResponse testDelete(String url, Object entity) throws Exception {
+ public ClientResponse testDeleteWithHeaders(String url, Map<String, String> headers) throws Exception {
// get the resource
- WebResource.Builder resourceBuilder = client.resource(url).accept(MediaType.APPLICATION_JSON).header(ProxiedEntitiesUtils.PROXY_ENTITIES_CHAIN, proxyDn);
+ WebResource.Builder resourceBuilder = addProxiedEntities(client.resource(url).accept(MediaType.APPLICATION_JSON));
- // append any query parameters
- if (entity != null) {
- resourceBuilder = resourceBuilder.entity(entity);
+ // append any headers
+ if (headers != null && !headers.isEmpty()) {
+ for (String key : headers.keySet()) {
+ resourceBuilder = resourceBuilder.header(key, headers.get(key));
+ }
}
// perform the query
@@ -254,7 +394,56 @@ public class NiFiTestUser {
}
// perform the request
- return resource.accept(MediaType.APPLICATION_JSON).type(MediaType.APPLICATION_FORM_URLENCODED).header(ProxiedEntitiesUtils.PROXY_ENTITIES_CHAIN, proxyDn).delete(ClientResponse.class);
+ return addProxiedEntities(resource.accept(MediaType.APPLICATION_JSON).type(MediaType.APPLICATION_FORM_URLENCODED)).delete(ClientResponse.class);
}
+ /**
+ * Attempts to create a token with the specified username and password.
+ *
+ * @param url the url
+ * @param username the username
+ * @param password the password
+ * @return response
+ * @throws Exception ex
+ */
+ public ClientResponse testCreateToken(String url, String username, String password) throws Exception {
+ // convert the form data
+ MultivaluedMapImpl entity = new MultivaluedMapImpl();
+ entity.add("username", username);
+ entity.add("password", password);
+
+ // get the resource
+ WebResource.Builder resourceBuilder = addProxiedEntities(client.resource(url).accept(MediaType.TEXT_PLAIN).type(MediaType.APPLICATION_FORM_URLENCODED)).entity(entity);
+
+ // perform the request
+ return resourceBuilder.post(ClientResponse.class);
+ }
+
+ /**
+ * Attempts to create a token with the specified username and password.
+ *
+ * @param url the url
+ * @param justification justification
+ * @param headers http headers
+ * @return response
+ * @throws Exception ex
+ */
+ public ClientResponse testRegisterUser(String url, String justification, Map<String, String> headers) throws Exception {
+ // convert the form data
+ MultivaluedMapImpl entity = new MultivaluedMapImpl();
+ entity.add("justification", justification);
+
+ // get the resource
+ WebResource.Builder resourceBuilder = addProxiedEntities(client.resource(url).accept(MediaType.TEXT_PLAIN).type(MediaType.APPLICATION_FORM_URLENCODED)).entity(entity);
+
+ // append any headers
+ if (headers != null && !headers.isEmpty()) {
+ for (String key : headers.keySet()) {
+ resourceBuilder = resourceBuilder.header(key, headers.get(key));
+ }
+ }
+
+ // perform the request
+ return resourceBuilder.post(ClientResponse.class);
+ }
}
http://git-wip-us.apache.org/repos/asf/nifi/blob/a1962077/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/test/resources/META-INF/services/org.apache.nifi.authentication.LoginIdentityProvider
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/test/resources/META-INF/services/org.apache.nifi.authentication.LoginIdentityProvider b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/test/resources/META-INF/services/org.apache.nifi.authentication.LoginIdentityProvider
new file mode 100644
index 0000000..4b42e4f
--- /dev/null
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/test/resources/META-INF/services/org.apache.nifi.authentication.LoginIdentityProvider
@@ -0,0 +1,15 @@
+# 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.
+org.apache.nifi.integration.util.NiFiTestLoginIdentityProvider
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/nifi/blob/a1962077/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/test/resources/access-control/controller-services.xml
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/test/resources/access-control/controller-services.xml b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/test/resources/access-control/controller-services.xml
deleted file mode 100644
index f5bd96a..0000000
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/test/resources/access-control/controller-services.xml
+++ /dev/null
@@ -1,18 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" ?>
-<!--
- 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.
--->
-<services>
-
-</services>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/nifi/blob/a1962077/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/test/resources/access-control/login-identity-providers.xml
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/test/resources/access-control/login-identity-providers.xml b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/test/resources/access-control/login-identity-providers.xml
new file mode 100644
index 0000000..04120c9
--- /dev/null
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/test/resources/access-control/login-identity-providers.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<!--
+ 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.
+-->
+<!--
+ This file lists all authority providers to use when running securely.
+-->
+<loginIdentityProviders>
+ <provider>
+ <identifier>test-provider</identifier>
+ <class>org.apache.nifi.integration.util.NiFiTestLoginIdentityProvider</class>
+ </provider>
+</loginIdentityProviders>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/nifi/blob/a1962077/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/test/resources/access-control/nifi.properties
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/test/resources/access-control/nifi.properties b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/test/resources/access-control/nifi.properties
index fc20d78..10db651 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/test/resources/access-control/nifi.properties
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/test/resources/access-control/nifi.properties
@@ -14,16 +14,15 @@
# limitations under the License.
# Core Properties #
-nifi.version=nifi 0.2.1-SNAPSHOT
+nifi.version=nifi version
nifi.flow.configuration.file=
nifi.flow.configuration.archive.dir=target/archive
nifi.flowcontroller.autoResumeState=true
nifi.flowcontroller.graceful.shutdown.period=10 sec
nifi.flowservice.writedelay.interval=2 sec
-nifi.reporting.task.configuration.file=target/test-classes/access-control/reporting-tasks.xml
-nifi.controller.service.configuration.file=target/test-classes/access-control/controller-services.xml
nifi.authority.provider.configuration.file=target/test-classes/access-control/authority-providers.xml
+nifi.login.identity.provider.configuration.file=target/test-classes/access-control/login-identity-providers.xml
nifi.templates.directory=target/test-classes/access-control/templates
nifi.ui.banner.text=TEST BANNER
nifi.ui.autorefresh.interval=30 sec
@@ -93,11 +92,11 @@ nifi.security.truststoreType=JKS
nifi.security.truststorePasswd=localtest
nifi.security.needClientAuth=true
nifi.security.user.authority.provider=test-provider
-nifi.security.user.login.identity.provider=
+nifi.security.user.login.identity.provider=test-provider
nifi.security.authorizedUsers.file=target/test-classes/access-control/users.xml
nifi.security.user.credential.cache.duration=1 hr
nifi.security.support.new.account.requests=
-nifi.security.default.user.roles=
+nifi.security.anonymous.authorities=
# cluster common properties (cluster manager and nodes must have same values) #
nifi.cluster.protocol.heartbeat.interval=5 sec
http://git-wip-us.apache.org/repos/asf/nifi/blob/a1962077/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/test/resources/access-control/reporting-tasks.xml
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/test/resources/access-control/reporting-tasks.xml b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/test/resources/access-control/reporting-tasks.xml
deleted file mode 100644
index 251735e..0000000
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/test/resources/access-control/reporting-tasks.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0"?>
-<!--
- 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.
--->
-<tasks>
-</tasks>
http://git-wip-us.apache.org/repos/asf/nifi/blob/a1962077/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/NiFiAuthenticationFilter.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/NiFiAuthenticationFilter.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/NiFiAuthenticationFilter.java
index e5e5c04..ec34ace 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/NiFiAuthenticationFilter.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/NiFiAuthenticationFilter.java
@@ -29,12 +29,14 @@ import javax.servlet.http.HttpServletResponse;
import org.apache.commons.lang3.StringUtils;
import org.apache.nifi.user.NiFiUser;
import org.apache.nifi.util.NiFiProperties;
+import org.apache.nifi.web.security.token.NiFiAuthenticationRequestToken;
import org.apache.nifi.web.security.user.NiFiUserUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.authentication.AccountStatusException;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.AuthenticationServiceException;
+import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.context.SecurityContextHolder;
@@ -85,8 +87,13 @@ public abstract class NiFiAuthenticationFilter implements Filter {
private void authenticate(final HttpServletRequest request, final HttpServletResponse response) throws IOException {
try {
- final Authentication authenticated = attemptAuthentication(request, response);
+ final NiFiAuthenticationRequestToken authenticated = attemptAuthentication(request, response);
if (authenticated != null) {
+ // log the request attempt - response details will be logged later
+ logger.info(String.format("Attempting request for (%s) %s %s (source ip: %s)",
+ ProxiedEntitiesUtils.formatProxyDn(StringUtils.join(authenticated.getChain(), "><")), request.getMethod(),
+ request.getRequestURL().toString(), request.getRemoteAddr()));
+
final Authentication authorized = authenticationManager.authenticate(authenticated);
successfulAuthorization(request, response, authorized);
}
@@ -97,7 +104,7 @@ public abstract class NiFiAuthenticationFilter implements Filter {
}
}
- public abstract Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response);
+ public abstract NiFiAuthenticationRequestToken attemptAuthentication(HttpServletRequest request, HttpServletResponse response);
protected void successfulAuthorization(HttpServletRequest request, HttpServletResponse response, Authentication authResult) {
if (logger.isDebugEnabled()) {
@@ -127,6 +134,9 @@ public abstract class NiFiAuthenticationFilter implements Filter {
response.setStatus(HttpServletResponse.SC_FORBIDDEN);
out.println("Access is denied.");
}
+ } else if (ae instanceof BadCredentialsException) {
+ response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
+ out.println(ae.getMessage());
} else if (ae instanceof AccountStatusException) {
response.setStatus(HttpServletResponse.SC_FORBIDDEN);
out.println(ae.getMessage());
http://git-wip-us.apache.org/repos/asf/nifi/blob/a1962077/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/NiFiAuthenticationProvider.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/NiFiAuthenticationProvider.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/NiFiAuthenticationProvider.java
index 79e8eb2..eb0684b 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/NiFiAuthenticationProvider.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/NiFiAuthenticationProvider.java
@@ -47,10 +47,12 @@ public class NiFiAuthenticationProvider implements AuthenticationProvider {
final UserDetails userDetails = userDetailsService.loadUserDetails(request);
// build an authentication for accesing nifi
- return new NiFiAuthorizationToken(userDetails);
+ final NiFiAuthorizationToken result = new NiFiAuthorizationToken(userDetails);
+ result.setDetails(request.getDetails());
+ return result;
} catch (final UsernameNotFoundException unfe) {
- // if the result was an authenticated new account request and it could not be authorized because the user was not found,
- // return the token so the new account could be created. this must go here to ensure that any proxies have been authorized
+ // if the authentication request is for a new account and it could not be authorized because the user was not found,
+ // return the token so the new account could be created. this must go here toe nsure that any proxies have been authorized
if (isNewAccountAuthenticationToken(request)) {
return new NewAccountAuthenticationToken(((NewAccountAuthenticationRequestToken) authentication).getNewAccountRequest());
} else {