NIFI-655: - Added an endpoint for access details including configuration, creating tokens, and checking status. - Updated DTOs and client side to utilize new endpoints.
Project: http://git-wip-us.apache.org/repos/asf/nifi/repo Commit: http://git-wip-us.apache.org/repos/asf/nifi/commit/7529694f Tree: http://git-wip-us.apache.org/repos/asf/nifi/tree/7529694f Diff: http://git-wip-us.apache.org/repos/asf/nifi/diff/7529694f Branch: refs/heads/master Commit: 7529694f23cf46f977f7f1210f91ec4636f35e3e Parents: 9ccf61a Author: Matt Gilman <[email protected]> Authored: Mon Nov 16 21:18:04 2015 -0500 Committer: Matt Gilman <[email protected]> Committed: Mon Nov 16 21:18:04 2015 -0500 ---------------------------------------------------------------------- .../web/api/dto/AccessConfigurationDTO.java | 61 +++ .../nifi/web/api/dto/AccessStatusDTO.java | 101 +++++ .../nifi/web/api/dto/LoginConfigurationDTO.java | 44 -- .../api/entity/AccessConfigurationEntity.java | 43 ++ .../nifi/web/api/entity/AccessStatusEntity.java | 43 ++ .../api/entity/LoginConfigurationEntity.java | 43 -- .../org/apache/nifi/web/NiFiServiceFacade.java | 8 - .../web/NiFiWebApiSecurityConfiguration.java | 47 +-- .../nifi/web/StandardNiFiServiceFacade.java | 17 - .../org/apache/nifi/web/api/AccessResource.java | 412 +++++++++++++++++++ .../apache/nifi/web/api/ControllerResource.java | 48 --- .../src/main/resources/nifi-web-api-context.xml | 10 +- .../web/security/RegistrationStatusFilter.java | 251 ----------- .../nifi/web/security/jwt/JwtService.java | 29 +- .../login/LoginAuthenticationFilter.java | 243 ----------- .../resources/nifi-web-security-context.xml | 2 +- .../src/main/webapp/js/nf/canvas/nf-canvas.js | 4 +- .../src/main/webapp/js/nf/login/nf-login.js | 197 +++------ .../src/main/webapp/js/nf/nf-common.js | 4 +- 19 files changed, 741 insertions(+), 866 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/nifi/blob/7529694f/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/AccessConfigurationDTO.java ---------------------------------------------------------------------- diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/AccessConfigurationDTO.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/AccessConfigurationDTO.java new file mode 100644 index 0000000..d9719b3 --- /dev/null +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/AccessConfigurationDTO.java @@ -0,0 +1,61 @@ +/* + * 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.api.dto; + +import com.wordnik.swagger.annotations.ApiModelProperty; +import javax.xml.bind.annotation.XmlType; + +/** + * Details for the access configuration. + */ +@XmlType(name = "accessConfig") +public class AccessConfigurationDTO { + + private Boolean supportsLogin; + private Boolean supportsAnonymous; + + /** + * @return Indicates whether or not this NiFi supports user login. + */ + @ApiModelProperty( + value = "Indicates whether or not this NiFi supports user login.", + readOnly = true + ) + public Boolean getSupportsLogin() { + return supportsLogin; + } + + public void setSupportsLogin(Boolean supportsLogin) { + this.supportsLogin = supportsLogin; + } + + /** + * @return Indicates whether or not this NiFi supports anonymous access. + */ + @ApiModelProperty( + value = "Indicates whether or not this NiFi supports anonymous.", + readOnly = true + ) + public Boolean getSupportsAnonymous() { + return supportsAnonymous; + } + + public void setSupportsAnonymous(Boolean supportsAnonymous) { + this.supportsAnonymous = supportsAnonymous; + } + +} http://git-wip-us.apache.org/repos/asf/nifi/blob/7529694f/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/AccessStatusDTO.java ---------------------------------------------------------------------- diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/AccessStatusDTO.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/AccessStatusDTO.java new file mode 100644 index 0000000..712da0e --- /dev/null +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/AccessStatusDTO.java @@ -0,0 +1,101 @@ +/* + * 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.api.dto; + +import com.wordnik.swagger.annotations.ApiModelProperty; +import javax.xml.bind.annotation.XmlRootElement; + +/** + * A serialized representation of this class can be placed in the entity body of a response to the API. This particular entity holds the users access status. + */ +@XmlRootElement(name = "accessStatus") +public class AccessStatusDTO { + + public static enum Status { + + UNKNOWN, + UNREGISTERED, + NOT_ACTIVE, + ACTIVE + } + + private String identity; + private String username; + private String status; + private String message; + + /** + * @return the user identity + */ + @ApiModelProperty( + value = "The user identity.", + readOnly = true + ) + public String getIdentity() { + return identity; + } + + public void setIdentity(String identity) { + this.identity = identity; + } + + /** + * @return the username + */ + @ApiModelProperty( + value = "The username.", + readOnly = true + ) + public String getUsername() { + return username; + } + + public void setUsername(String username) { + this.username = username; + } + + /** + * @return the user access status + */ + @ApiModelProperty( + value = "The user access status.", + readOnly = true + ) + public String getStatus() { + return status; + } + + public void setStatus(String status) { + this.status = status; + } + + /** + * @return additional details about the user access status + */ + @ApiModelProperty( + value = "Additional details about the user access status.", + readOnly = true + ) + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + +} http://git-wip-us.apache.org/repos/asf/nifi/blob/7529694f/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/LoginConfigurationDTO.java ---------------------------------------------------------------------- diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/LoginConfigurationDTO.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/LoginConfigurationDTO.java deleted file mode 100644 index 60f644b..0000000 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/LoginConfigurationDTO.java +++ /dev/null @@ -1,44 +0,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. - */ -package org.apache.nifi.web.api.dto; - -import com.wordnik.swagger.annotations.ApiModelProperty; -import javax.xml.bind.annotation.XmlType; - -/** - * Details for the login configuration. - */ -@XmlType(name = "loginConfig") -public class LoginConfigurationDTO { - - private Boolean supportsLogin; - - /** - * @return Indicates whether or not this NiFi supports user login. - */ - @ApiModelProperty( - value = "Indicates whether or not this NiFi supports user login.", - readOnly = true - ) - public Boolean getSupportsLogin() { - return supportsLogin; - } - - public void setSupportsLogin(Boolean supportsLogin) { - this.supportsLogin = supportsLogin; - } -} http://git-wip-us.apache.org/repos/asf/nifi/blob/7529694f/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/AccessConfigurationEntity.java ---------------------------------------------------------------------- diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/AccessConfigurationEntity.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/AccessConfigurationEntity.java new file mode 100644 index 0000000..3af0e49 --- /dev/null +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/AccessConfigurationEntity.java @@ -0,0 +1,43 @@ +/* + * 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.api.entity; + +import javax.xml.bind.annotation.XmlRootElement; +import org.apache.nifi.web.api.dto.AccessConfigurationDTO; + +/** + * A serialized representation of this class can be placed in the entity body of a request or response to or from the API. This particular entity holds a reference to a AccessConfigurationDTO. + */ +@XmlRootElement(name = "accessConfigurationEntity") +public class AccessConfigurationEntity extends Entity { + + private AccessConfigurationDTO config; + + /** + * The AccessConfigurationDTO that is being serialized. + * + * @return The AccessConfigurationDTO object + */ + public AccessConfigurationDTO getConfig() { + return config; + } + + public void setConfig(AccessConfigurationDTO config) { + this.config = config; + } + +} http://git-wip-us.apache.org/repos/asf/nifi/blob/7529694f/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/AccessStatusEntity.java ---------------------------------------------------------------------- diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/AccessStatusEntity.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/AccessStatusEntity.java new file mode 100644 index 0000000..f19a268 --- /dev/null +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/AccessStatusEntity.java @@ -0,0 +1,43 @@ +/* + * 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.api.entity; + +import javax.xml.bind.annotation.XmlRootElement; +import org.apache.nifi.web.api.dto.AccessStatusDTO; + +/** + * A serialized representation of this class can be placed in the entity body of a request or response to or from the API. This particular entity holds a reference to a AccessStatusDTO. + */ +@XmlRootElement(name = "accessStatusEntity") +public class AccessStatusEntity extends Entity { + + private AccessStatusDTO accessStatus; + + /** + * The AccessStatusDTO that is being serialized. + * + * @return The AccessStatusDTO object + */ + public AccessStatusDTO getAccessStatus() { + return accessStatus; + } + + public void setAccessStatus(AccessStatusDTO accessStatus) { + this.accessStatus = accessStatus; + } + +} http://git-wip-us.apache.org/repos/asf/nifi/blob/7529694f/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/LoginConfigurationEntity.java ---------------------------------------------------------------------- diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/LoginConfigurationEntity.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/LoginConfigurationEntity.java deleted file mode 100644 index da62d6f..0000000 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/LoginConfigurationEntity.java +++ /dev/null @@ -1,43 +0,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. - */ -package org.apache.nifi.web.api.entity; - -import javax.xml.bind.annotation.XmlRootElement; -import org.apache.nifi.web.api.dto.LoginConfigurationDTO; - -/** - * A serialized representation of this class can be placed in the entity body of a request or response to or from the API. This particular entity holds a reference to a LoginConfigurationDTO. - */ -@XmlRootElement(name = "loginConfigurationEntity") -public class LoginConfigurationEntity extends Entity { - - private LoginConfigurationDTO config; - - /** - * The LoginConfigurationDTO that is being serialized. - * - * @return The LoginConfigurationDTO object - */ - public LoginConfigurationDTO getConfig() { - return config; - } - - public void setConfig(LoginConfigurationDTO config) { - this.config = config; - } - -} http://git-wip-us.apache.org/repos/asf/nifi/blob/7529694f/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/NiFiServiceFacade.java ---------------------------------------------------------------------- diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/NiFiServiceFacade.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/NiFiServiceFacade.java index 3c64a02..f4d5821 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/NiFiServiceFacade.java +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/NiFiServiceFacade.java @@ -43,7 +43,6 @@ import org.apache.nifi.web.api.dto.ProcessGroupDTO; import org.apache.nifi.web.api.dto.ProcessorDTO; import org.apache.nifi.web.api.dto.ComponentHistoryDTO; import org.apache.nifi.web.api.dto.ControllerServiceReferencingComponentDTO; -import org.apache.nifi.web.api.dto.LoginConfigurationDTO; import org.apache.nifi.web.api.dto.PropertyDescriptorDTO; import org.apache.nifi.web.api.dto.RemoteProcessGroupDTO; import org.apache.nifi.web.api.dto.RemoteProcessGroupPortDTO; @@ -179,13 +178,6 @@ public interface NiFiServiceFacade { ControllerConfigurationDTO getControllerConfiguration(); /** - * Gets the login configuration for this controller. - * - * @return The login configuration - */ - LoginConfigurationDTO getLoginConfiguration(); - - /** * Updates the configuration for this controller. * * @param revision Revision to compare with current base revision http://git-wip-us.apache.org/repos/asf/nifi/blob/7529694f/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 20bbc55..216e311 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 @@ -16,15 +16,12 @@ */ package org.apache.nifi.web; -import javax.servlet.Filter; import org.apache.nifi.admin.service.UserService; import org.apache.nifi.authentication.LoginIdentityProvider; import org.apache.nifi.util.NiFiProperties; import org.apache.nifi.web.security.NiFiAuthenticationProvider; 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.login.LoginAuthenticationFilter; import org.apache.nifi.web.security.jwt.JwtAuthenticationFilter; import org.apache.nifi.web.security.jwt.JwtService; import org.apache.nifi.web.security.node.NodeAuthorizedUserFilter; @@ -35,7 +32,6 @@ import org.apache.nifi.web.security.x509.X509CertificateValidator; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -import org.springframework.http.HttpMethod; import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; @@ -46,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.UsernamePasswordAuthenticationFilter; import org.springframework.security.web.authentication.preauth.x509.X509PrincipalExtractor; /** @@ -72,7 +67,9 @@ public class NiFiWebApiSecurityConfiguration extends WebSecurityConfigurerAdapte @Override public void configure(WebSecurity webSecurity) throws Exception { - webSecurity.ignoring().antMatchers(HttpMethod.GET, "/controller/login/config"); + webSecurity + .ignoring() + .antMatchers("/access/**"); } @Override @@ -80,19 +77,13 @@ public class NiFiWebApiSecurityConfiguration extends WebSecurityConfigurerAdapte http .rememberMe().disable() .exceptionHandling() - .authenticationEntryPoint(new NiFiAuthenticationEntryPoint(properties)) - .and() + .authenticationEntryPoint(new NiFiAuthenticationEntryPoint(properties)) + .and() .authorizeRequests() - .anyRequest().fullyAuthenticated() - .and() + .anyRequest().fullyAuthenticated() + .and() .sessionManagement() - .sessionCreationPolicy(SessionCreationPolicy.STATELESS); - - // login authentication for /token - exchanges for JWT for subsequent API usage - http.addFilterBefore(buildLoginFilter("/token"), UsernamePasswordAuthenticationFilter.class); - - // registration status - will check the status of a user's account registration (regardless if its based on login or not) - http.addFilterBefore(buildRegistrationStatusFilter("/registration/status"), UsernamePasswordAuthenticationFilter.class); + .sessionCreationPolicy(SessionCreationPolicy.STATELESS); // cluster authorized user http.addFilterBefore(buildNodeAuthorizedUserFilter(), AnonymousAuthenticationFilter.class); @@ -121,28 +112,6 @@ public class NiFiWebApiSecurityConfiguration extends WebSecurityConfigurerAdapte auth.authenticationProvider(new NiFiAuthenticationProvider(userDetailsService)); } - private LoginAuthenticationFilter buildLoginFilter(final String url) { - final LoginAuthenticationFilter loginFilter = new LoginAuthenticationFilter(url); - loginFilter.setJwtService(jwtService); - loginFilter.setLoginIdentityProvider(loginIdentityProvider); - loginFilter.setUserDetailsService(userDetailsService); - loginFilter.setCertificateExtractor(certificateExtractor); - loginFilter.setPrincipalExtractor(principalExtractor); - loginFilter.setCertificateValidator(certificateValidator); - return loginFilter; - } - - private Filter buildRegistrationStatusFilter(final String url) { - 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() { return new NodeAuthorizedUserFilter(properties); } http://git-wip-us.apache.org/repos/asf/nifi/blob/7529694f/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/StandardNiFiServiceFacade.java ---------------------------------------------------------------------- diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/StandardNiFiServiceFacade.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/StandardNiFiServiceFacade.java index 324be87..b13077d 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/StandardNiFiServiceFacade.java +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/StandardNiFiServiceFacade.java @@ -153,7 +153,6 @@ import org.apache.nifi.web.util.SnippetUtils; import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.lang3.StringUtils; -import org.apache.nifi.authentication.LoginIdentityProvider; import org.apache.nifi.components.PropertyDescriptor; import org.apache.nifi.components.Validator; import org.apache.nifi.controller.ReportingTaskNode; @@ -164,7 +163,6 @@ import org.apache.nifi.controller.service.ControllerServiceState; import org.apache.nifi.reporting.ComponentType; import org.apache.nifi.web.api.dto.ControllerServiceDTO; import org.apache.nifi.web.api.dto.ControllerServiceReferencingComponentDTO; -import org.apache.nifi.web.api.dto.LoginConfigurationDTO; import org.apache.nifi.web.api.dto.PropertyDescriptorDTO; import org.apache.nifi.web.api.dto.ReportingTaskDTO; import org.apache.nifi.web.api.dto.status.ClusterProcessGroupStatusDTO; @@ -207,7 +205,6 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade { // administrative services private AuditService auditService; private UserService userService; - private LoginIdentityProvider loginIdentityProvider; // cluster manager private WebClusterManager clusterManager; @@ -2351,16 +2348,6 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade { } @Override - public LoginConfigurationDTO getLoginConfiguration() { - final LoginConfigurationDTO loginConfiguration = new LoginConfigurationDTO(); - - // specify whether login should be supported - loginConfiguration.setSupportsLogin(loginIdentityProvider != null); - - return loginConfiguration; - } - - @Override public ControllerConfigurationDTO getControllerConfiguration() { ControllerConfigurationDTO controllerConfig = new ControllerConfigurationDTO(); controllerConfig.setName(controllerFacade.getName()); @@ -3420,10 +3407,6 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade { this.snippetUtils = snippetUtils; } - public void setLoginIdentityProvider(LoginIdentityProvider loginIdentityProvider) { - this.loginIdentityProvider = loginIdentityProvider; - } - private boolean isPrimaryNode(String nodeId) { final Node primaryNode = clusterManager.getPrimaryNode(); return (primaryNode != null && primaryNode.getNodeId().getId().equals(nodeId)); http://git-wip-us.apache.org/repos/asf/nifi/blob/7529694f/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 new file mode 100644 index 0000000..9cb4141 --- /dev/null +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/AccessResource.java @@ -0,0 +1,412 @@ +/* + * 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.api; + +import javax.ws.rs.Consumes; +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; + +import org.apache.nifi.util.NiFiProperties; +import com.wordnik.swagger.annotations.Api; +import com.wordnik.swagger.annotations.ApiOperation; +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; +import javax.servlet.http.HttpServletRequest; +import javax.ws.rs.DefaultValue; +import javax.ws.rs.FormParam; +import javax.ws.rs.POST; +import javax.ws.rs.QueryParam; +import javax.ws.rs.core.Context; +import org.apache.nifi.admin.service.AdministrationException; +import org.apache.nifi.authentication.AuthenticationResponse; +import org.apache.nifi.authentication.LoginCredentials; +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; +import org.apache.nifi.web.api.entity.AccessStatusEntity; +import org.apache.nifi.web.api.entity.AccessConfigurationEntity; +import org.apache.nifi.web.api.request.ClientIdParameter; +import org.apache.nifi.web.security.ProxiedEntitiesUtils; +import org.apache.nifi.web.security.UntrustedProxyException; +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.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. + */ +@Path("/access") +@Api( + value = "/access", + description = "Endpoints for obtaining an access token or checking access status" +) +public class AccessResource extends ApplicationResource { + + private NiFiProperties properties; + + private X509CertificateValidator certificateValidator; + private X509CertificateExtractor certificateExtractor; + private X509PrincipalExtractor principalExtractor; + + private LoginIdentityProvider loginIdentityProvider; + private JwtService jwtService; + + private AuthenticationUserDetailsService<NiFiAuthenticationRequestToken> userDetailsService; + + /** + * Retrieves the access configuration for this NiFi. + * + * @param httpServletRequest the servlet request + * @param clientId Optional client id. If the client id is not specified, a new one will be generated. This value (whether specified or generated) is included in the response. + * @return A accessConfigurationEntity + */ + @GET + @Consumes(MediaType.WILDCARD) + @Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML}) + @Path("/config") + @ApiOperation( + value = "Retrieves the access configuration for this NiFi", + response = AccessConfigurationEntity.class + ) + public Response getLoginConfig( + @Context HttpServletRequest httpServletRequest, + @ApiParam( + value = "If the client id is not specified, new one will be generated. This value (whether specified or generated) is included in the response.", + required = false + ) + @QueryParam(CLIENT_ID) @DefaultValue(StringUtils.EMPTY) ClientIdParameter clientId) { + + final AccessConfigurationDTO accessConfiguration = new AccessConfigurationDTO(); + + // specify whether login should be supported and only support for secure requests + accessConfiguration.setSupportsLogin(loginIdentityProvider != null && httpServletRequest.isSecure()); + accessConfiguration.setSupportsAnonymous(!properties.getAnonymousAuthorities().isEmpty() || !httpServletRequest.isSecure()); + + // create the revision + final RevisionDTO revision = new RevisionDTO(); + revision.setClientId(clientId.getClientId()); + + // create the response entity + final AccessConfigurationEntity entity = new AccessConfigurationEntity(); + entity.setRevision(revision); + entity.setConfig(accessConfiguration); + + // generate the response + return clusterContext(generateOkResponse(entity)).build(); + } + + /** + * Gets the status the client's access. + * + * @param httpServletRequest the servlet request + * @param clientId Optional client id. If the client id is not specified, a new one will be generated. This value (whether specified or generated) is included in the response. + * @return A accessStatusEntity + */ + @GET + @Consumes(MediaType.WILDCARD) + @Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON}) + @Path("") + @ApiOperation( + value = "Gets the status the client's access", + response = AccessStatusEntity.class + ) + @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 = 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.") + } + ) + public Response getAccessStatus( + @Context HttpServletRequest httpServletRequest, + @ApiParam( + value = "If the client id is not specified, new one will be generated. This value (whether specified or generated) is included in the response.", + required = false + ) + @QueryParam(CLIENT_ID) @DefaultValue(StringUtils.EMPTY) ClientIdParameter clientId) { + + // only consider user specific access over https + if (!httpServletRequest.isSecure()) { + throw new IllegalStateException("User authentication/authorization is only supported when running over HTTPS."); + } + + final AccessStatusDTO accessStatus = new AccessStatusDTO(); + + try { + // look for a certificate + final X509Certificate certificate = certificateExtractor.extractClientCertificate(httpServletRequest); + + // if no certificate, just check the credentials + if (certificate == null) { + final String principal = jwtService.getAuthentication(httpServletRequest); + + // ensure we have something we can work with (certificate or crendentials) + if (principal == 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"); + } + } 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); + } + + // set the user identity + accessStatus.setIdentity(principal); + accessStatus.setUsername(CertificateUtils.extractUsername(principal)); + + // ensure the proxy chain is authorized + checkAuthorization(ProxiedEntitiesUtils.buildProxyChain(httpServletRequest, principal)); + + // no issues with authorization + accessStatus.setStatus(AccessStatusDTO.Status.ACTIVE.name()); + accessStatus.setStatus("Account is active and authorized"); + } + } catch (final UsernameNotFoundException unfe) { + accessStatus.setStatus(AccessStatusDTO.Status.UNREGISTERED.name()); + accessStatus.setMessage(String.format("Unregistered user %s", accessStatus.getIdentity())); + } catch (final AccountStatusException ase) { + accessStatus.setStatus(AccessStatusDTO.Status.NOT_ACTIVE.name()); + accessStatus.setMessage(ase.getMessage()); + } catch (final UntrustedProxyException upe) { + throw new AccessDeniedException(upe.getMessage(), upe); + } catch (final AuthenticationServiceException ase) { + throw new AdministrationException(ase.getMessage(), ase); + } + + // create the revision + final RevisionDTO revision = new RevisionDTO(); + revision.setClientId(clientId.getClientId()); + + // create the entity + final AccessStatusEntity entity = new AccessStatusEntity(); + entity.setRevision(revision); + entity.setAccessStatus(accessStatus); + + return generateOkResponse(entity).build(); + } + + /** + * Checks the status of the proxy. + * + * @param proxyChain the proxy chain + * @throws AuthenticationException if the proxy chain is not authorized + */ + private void checkAuthorization(final List<String> proxyChain) throws AuthenticationException { + userDetailsService.loadUserDetails(new NiFiAuthenticationRequestToken(proxyChain)); + } + + /** + * Creates a token for accessing the REST API via username/password. + * + * @param httpServletRequest the servlet request + * @param username the username + * @param password the password + * @return A JWT (string) + */ + @POST + @Consumes(MediaType.APPLICATION_FORM_URLENCODED) + @Produces(MediaType.TEXT_PLAIN) + @Path("/token") + @ApiOperation( + value = "Creates a token for accessing the REST API via username/password", + response = String.class + ) + @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 = 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.") + } + ) + public Response createAccessToken( + @Context HttpServletRequest httpServletRequest, + @FormParam("username") String username, + @FormParam("password") String password) { + + // only support access tokens when communicating over HTTPS + if (!httpServletRequest.isSecure()) { + throw new IllegalStateException("Access tokens are only issued over HTTPS."); + } + + // if not configuration for login, don't consider credentials + if (loginIdentityProvider == null) { + throw new IllegalStateException("Username/Password login not supported by this NiFi."); + } + + 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."); + } + + // 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()); + } + } 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()); + } 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); + } + } + + // generate JWT for response + final String token = jwtService.generateSignedToken(loginAuthenticationToken); + + // build the response + final URI uri = URI.create(generateResourceUri("access", "token")); + return generateCreatedResponse(uri, token).build(); + } + + /** + * Ensures the proxyChain is authorized before allowing the user to be authenticated. + * + * @param proxyChain the proxy chain + * @throws AuthenticationException if the proxy chain is not authorized + */ + private void authorizeProxyIfNecessary(final List<String> proxyChain) throws AuthenticationException { + if (proxyChain.size() > 1) { + try { + 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 + } 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) { + }; + } + } + } + + // setters + public void setProperties(NiFiProperties properties) { + this.properties = properties; + } + + public void setLoginIdentityProvider(LoginIdentityProvider loginIdentityProvider) { + this.loginIdentityProvider = loginIdentityProvider; + } + + public void setJwtService(JwtService jwtService) { + 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 setUserDetailsService(AuthenticationUserDetailsService<NiFiAuthenticationRequestToken> userDetailsService) { + this.userDetailsService = userDetailsService; + } + +} http://git-wip-us.apache.org/repos/asf/nifi/blob/7529694f/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ControllerResource.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/ControllerResource.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ControllerResource.java index 93f21b2..6e6739d 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ControllerResource.java +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ControllerResource.java @@ -78,10 +78,8 @@ import org.apache.nifi.web.api.request.ClientIdParameter; import org.apache.nifi.web.api.request.IntegerParameter; import org.apache.nifi.web.api.request.LongParameter; import org.apache.commons.lang3.StringUtils; -import org.apache.nifi.web.api.dto.LoginConfigurationDTO; import org.apache.nifi.web.api.entity.ControllerServiceTypesEntity; import org.apache.nifi.web.api.entity.IdentityEntity; -import org.apache.nifi.web.api.entity.LoginConfigurationEntity; import org.apache.nifi.web.api.entity.ReportingTaskTypesEntity; import org.springframework.security.access.prepost.PreAuthorize; @@ -657,52 +655,6 @@ public class ControllerResource extends ApplicationResource { } /** - * Retrieves the login configuration for this NiFi. - * - * @param httpServletRequest the servlet request - * @param clientId Optional client id. If the client id is not specified, a new one will be generated. This value (whether specified or generated) is included in the response. - * @return A loginConfigurationEntity - */ - @GET - @Consumes(MediaType.WILDCARD) - @Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML}) - @Path("/login/config") - @ApiOperation( - value = "Retrieves the login configuration for this NiFi", - response = LoginConfigurationEntity.class - ) - public Response getLoginConfig( - @Context HttpServletRequest httpServletRequest, - @ApiParam( - value = "If the client id is not specified, new one will be generated. This value (whether specified or generated) is included in the response.", - required = false - ) - @QueryParam(CLIENT_ID) @DefaultValue(StringUtils.EMPTY) ClientIdParameter clientId) { - - // replicate if cluster manager - if (properties.isClusterManager()) { - return clusterManager.applyRequest(HttpMethod.GET, getAbsolutePath(), getRequestParameters(true), getHeaders()).getResponse(); - } - - final LoginConfigurationDTO loginConfig = serviceFacade.getLoginConfiguration(); - - // only support login/registration when running securely - loginConfig.setSupportsLogin(loginConfig.getSupportsLogin() && httpServletRequest.isSecure()); - - // create the revision - final RevisionDTO revision = new RevisionDTO(); - revision.setClientId(clientId.getClientId()); - - // create the response entity - final LoginConfigurationEntity entity = new LoginConfigurationEntity(); - entity.setRevision(revision); - entity.setConfig(loginConfig); - - // generate the response - return clusterContext(generateOkResponse(entity)).build(); - } - - /** * Retrieves the configuration for this NiFi. * * @param clientId Optional client id. If the client id is not specified, a new one will be generated. This value (whether specified or generated) is included in the response. http://git-wip-us.apache.org/repos/asf/nifi/blob/7529694f/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 96c3f2b..e992dc9 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 @@ -122,7 +122,6 @@ <property name="optimisticLockingManager" ref="webOptimisticLockingManager"/> <property name="dtoFactory" ref="dtoFactory"/> <property name="clusterManager" ref="clusterManager"/> - <property name="loginIdentityProvider" ref="loginIdentityProvider"/> </bean> <!-- depecrated --> @@ -242,6 +241,15 @@ <bean id="systemDiagnosticsResource" class="org.apache.nifi.web.api.SystemDiagnosticsResource" scope="singleton"> <property name="serviceFacade" ref="serviceFacade"/> </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="loginIdentityProvider" ref="loginIdentityProvider"/> + <property name="jwtService" ref="jwtService"/> + <property name="userDetailsService" ref="userDetailsService"/> + </bean> <!-- configuration for jaxb serialization --> <bean class="org.apache.nifi.web.util.ObjectMapperResolver" scope="singleton"/> http://git-wip-us.apache.org/repos/asf/nifi/blob/7529694f/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/RegistrationStatusFilter.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/RegistrationStatusFilter.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/RegistrationStatusFilter.java deleted file mode 100644 index 606d2e3..0000000 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/RegistrationStatusFilter.java +++ /dev/null @@ -1,251 +0,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. - */ -package org.apache.nifi.web.security; - -import java.io.IOException; -import java.io.PrintWriter; -import java.security.cert.CertificateExpiredException; -import java.security.cert.CertificateNotYetValidException; -import java.security.cert.X509Certificate; -import java.util.Arrays; -import java.util.List; -import javax.servlet.FilterChain; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -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; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.security.authentication.AbstractAuthenticationToken; -import org.springframework.security.authentication.AccountStatusException; -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.userdetails.AuthenticationUserDetailsService; -import org.springframework.security.core.userdetails.UsernameNotFoundException; -import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter; -import org.springframework.security.web.authentication.preauth.x509.X509PrincipalExtractor; - -/** - * Exchanges a successful login with the configured provider for a ID token for accessing the API. - */ -public class RegistrationStatusFilter extends AbstractAuthenticationProcessingFilter { - - 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; - private X509PrincipalExtractor principalExtractor; - - public RegistrationStatusFilter(final String defaultFilterProcessesUrl) { - super(defaultFilterProcessesUrl); - - // do not continue filter chain... simply exchaning authentication for token - setContinueChainBeforeSuccessfulAuthentication(false); - } - - @Override - public Authentication attemptAuthentication(final HttpServletRequest request, final HttpServletResponse response) throws AuthenticationException, IOException, ServletException { - // only suppport login when running securely - if (!request.isSecure()) { - return null; - } - - // look for a certificate - final X509Certificate certificate = certificateExtractor.extractClientCertificate(request); - - // if no certificate, just check the credentials - if (certificate == null) { - final String principal = jwtService.getAuthentication(request); - - // ensure we have something we can work with (certificate or crendentials) - 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(principal); - - // check authorization for this user - checkAuthorization(chain); - - // no issues with authorization - 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 = principalExtractor.extractPrincipal(certificate).toString(); - - try { - // validate the certificate - 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; - } - - // ensure the proxy chain is authorized - checkAuthorization(ProxiedEntitiesUtils.buildProxyChain(request, principal)); - - // no issues with authorization - final LoginCredentials preAuthenticatedCredentials = new LoginCredentials(principal, null); - return new RegistrationStatusAuthenticationToken(preAuthenticatedCredentials); - } - } - - /** - * Checks the status of the proxy. - * - * @param proxyChain the proxy chain - * @throws AuthenticationException if the proxy chain is not authorized - */ - private void checkAuthorization(final List<String> proxyChain) throws AuthenticationException { - userDetailsService.loadUserDetails(new NiFiAuthenticationRequestToken(proxyChain)); - } - - @Override - protected void successfulAuthentication(final HttpServletRequest request, final HttpServletResponse response, final FilterChain chain, final Authentication authentication) - throws IOException, ServletException { - - // mark as successful - response.setStatus(HttpServletResponse.SC_OK); - response.setContentType("text/plain"); - response.setContentLength(0); - } - - @Override - protected void unsuccessfulAuthentication(final HttpServletRequest request, final HttpServletResponse response, final AuthenticationException ae) throws IOException, ServletException { - // set the response status - response.setContentType("text/plain"); - - // write the response message - PrintWriter out = response.getWriter(); - - // use the type of authentication exception to determine the response code - if (ae instanceof UsernameNotFoundException) { - if (properties.getSupportNewAccountRequests()) { - response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); - out.println("Not authorized."); - } else { - response.setStatus(HttpServletResponse.SC_FORBIDDEN); - out.println("Access is denied."); - } - } else if (ae instanceof AccountStatusException) { - response.setStatus(HttpServletResponse.SC_FORBIDDEN); - out.println(ae.getMessage()); - } else if (ae instanceof UntrustedProxyException) { - response.setStatus(HttpServletResponse.SC_FORBIDDEN); - out.println(ae.getMessage()); - } else if (ae instanceof AuthenticationServiceException) { - logger.error(String.format("Unable to authorize: %s", ae.getMessage()), ae); - response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); - out.println(String.format("Unable to authorize: %s", ae.getMessage())); - } else { - logger.error(String.format("Unable to authorize: %s", ae.getMessage()), ae); - response.setStatus(HttpServletResponse.SC_FORBIDDEN); - out.println("Access is denied."); - } - - // log the failure - logger.info(String.format("Rejecting access to web api: %s", ae.getMessage())); - - // optionally log the stack trace - if (logger.isDebugEnabled()) { - logger.debug(StringUtils.EMPTY, ae); - } - } - - /** - * This is an Authentication Token for logging in. Once a user is authenticated, they can be issues an ID token. - */ - public static class RegistrationStatusAuthenticationToken extends AbstractAuthenticationToken { - - final LoginCredentials credentials; - - public RegistrationStatusAuthenticationToken(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(); - } - } - - public void setJwtService(JwtService jwtService) { - 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 setUserDetailsService(AuthenticationUserDetailsService<NiFiAuthenticationRequestToken> userDetailsService) { - this.userDetailsService = userDetailsService; - } - - public void setProperties(NiFiProperties properties) { - this.properties = properties; - } - -} http://git-wip-us.apache.org/repos/asf/nifi/blob/7529694f/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/jwt/JwtService.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/jwt/JwtService.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/jwt/JwtService.java index 5dfbdfe..2f6c726 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/jwt/JwtService.java +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/jwt/JwtService.java @@ -26,12 +26,9 @@ import io.jsonwebtoken.SignatureAlgorithm; import io.jsonwebtoken.SignatureException; import io.jsonwebtoken.SigningKeyResolverAdapter; import io.jsonwebtoken.UnsupportedJwtException; -import java.io.IOException; -import java.io.PrintWriter; import java.nio.charset.StandardCharsets; import java.util.Calendar; import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; import org.apache.commons.lang3.StringUtils; import org.apache.nifi.admin.service.AdministrationException; import org.apache.nifi.admin.service.KeyService; @@ -83,35 +80,25 @@ public class JwtService { } /** - * Adds a token for the specified authentication in the specified response. + * Generates a signed JWT token from the provided (Spring Security) login authentication token. * - * @param response The response to add the token to - * @param authentication The authentication to generate a token for - * @throws java.io.IOException if an io exception occurs + * @param authenticationToken + * @return a signed JWT containing the user identity and the identity provider, Base64-encoded */ - public void addToken(final HttpServletResponse response, final LoginAuthenticationToken authentication) throws IOException { + public String generateSignedToken(final LoginAuthenticationToken authenticationToken) { // set expiration to one day from now final Calendar calendar = Calendar.getInstance(); - calendar.setTimeInMillis(calendar.getTimeInMillis() + authentication.getExpiration()); + calendar.setTimeInMillis(calendar.getTimeInMillis() + authenticationToken.getExpiration()); // create a token the specified authentication - final String identity = authentication.getPrincipal().toString(); - final String username = authentication.getName(); + final String identity = authenticationToken.getPrincipal().toString(); + final String username = authenticationToken.getName(); // get/create the key for this user final String key = keyService.getOrCreateKey(identity); final byte[] keyBytes = key.getBytes(StandardCharsets.UTF_8); // build the token - final String token = Jwts.builder().setSubject(identity).claim("preferred_username", username).setExpiration(calendar.getTime()).signWith(SignatureAlgorithm.HS512, keyBytes).compact(); - - // add the token as a response header - final PrintWriter out = response.getWriter(); - out.print(token); - - // mark the response as successful - response.setStatus(HttpServletResponse.SC_CREATED); - response.setContentType("text/plain"); + return Jwts.builder().setSubject(identity).claim("preferred_username", username).setExpiration(calendar.getTime()).signWith(SignatureAlgorithm.HS512, keyBytes).compact(); } - } http://git-wip-us.apache.org/repos/asf/nifi/blob/7529694f/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/login/LoginAuthenticationFilter.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/login/LoginAuthenticationFilter.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/login/LoginAuthenticationFilter.java deleted file mode 100644 index c90364a..0000000 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/login/LoginAuthenticationFilter.java +++ /dev/null @@ -1,243 +0,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. - */ -package org.apache.nifi.web.security.login; - -import org.apache.nifi.web.security.token.LoginAuthenticationToken; -import java.io.IOException; -import java.io.PrintWriter; -import java.security.cert.CertificateExpiredException; -import java.security.cert.CertificateNotYetValidException; -import java.security.cert.X509Certificate; -import java.util.List; -import javax.servlet.FilterChain; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import org.apache.nifi.admin.service.AdministrationException; -import org.apache.nifi.authentication.AuthenticationResponse; -import org.apache.nifi.authentication.LoginCredentials; -import org.apache.nifi.authentication.LoginIdentityProvider; -import org.apache.nifi.authentication.exception.IdentityAccessException; -import org.apache.nifi.authentication.exception.InvalidLoginCredentialsException; -import org.apache.nifi.util.StringUtils; -import org.apache.nifi.web.security.ProxiedEntitiesUtils; -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; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.security.authentication.AuthenticationCredentialsNotFoundException; -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.userdetails.AuthenticationUserDetailsService; -import org.springframework.security.core.userdetails.UsernameNotFoundException; -import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter; -import org.springframework.security.web.authentication.preauth.x509.X509PrincipalExtractor; - -/** - * Exchanges a successful login with the configured provider for a ID token for accessing the API. - */ -public class LoginAuthenticationFilter extends AbstractAuthenticationProcessingFilter { - - private static final Logger logger = LoggerFactory.getLogger(LoginAuthenticationFilter.class); - - private AuthenticationUserDetailsService<NiFiAuthenticationRequestToken> userDetailsService; - - private X509CertificateValidator certificateValidator; - private X509CertificateExtractor certificateExtractor; - private X509PrincipalExtractor principalExtractor; - - private LoginIdentityProvider loginIdentityProvider; - private JwtService jwtService; - - public LoginAuthenticationFilter(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 login 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) { - // look for a certificate - final X509Certificate certificate = certificateExtractor.extractClientCertificate(request); - - // if there is no certificate, look for an existing token - if (certificate == null) { - // if not configured for login, don't consider existing tokens - if (loginIdentityProvider == null) { - throw new BadCredentialsException("Login not supported."); - } - - final String principal = jwtService.getAuthentication(request); - - if (principal == null) { - throw new AuthenticationCredentialsNotFoundException("Unable to issue token as issue token as no credentials were found in the request."); - } - - return new LoginAuthenticationToken(principal, loginIdentityProvider.getExpiration()); - } else { - // extract the principal - final String principal = principalExtractor.extractPrincipal(certificate).toString(); - - 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)); - - return new LoginAuthenticationToken(principal, loginIdentityProvider.getExpiration()); - } - } else { - // if not configuration for login, don't consider credentials - if (loginIdentityProvider == null) { - throw new BadCredentialsException("Login not supported."); - } - - try { - // attempt to authenticate - final AuthenticationResponse authenticationResponse = loginIdentityProvider.authenticate(credentials); - - // create the authentication token - return new LoginAuthenticationToken(authenticationResponse.getUsername(), loginIdentityProvider.getExpiration()); - } catch (final InvalidLoginCredentialsException ilce) { - throw new BadCredentialsException("The supplied username and password are not valid.", ilce); - } catch (final IdentityAccessException iae) { - throw new AuthenticationServiceException(iae.getMessage(), iae); - } - } - } - - /** - * Ensures the proxyChain is authorized before allowing the user to be authenticated. - * - * @param proxyChain the proxy chain - * @throws AuthenticationException if the proxy chain is not authorized - */ - private void authorizeProxyIfNecessary(final List<String> proxyChain) throws AuthenticationException { - if (proxyChain.size() > 1) { - try { - 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 - } catch (final Exception e) { - // any other issue we're going to treat as an authentication exception which will return 401 - throw new AuthenticationException(e.getMessage(), e) { - }; - } - } - } - - 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 { - - try { - // generate JWT for response - jwtService.addToken(response, (LoginAuthenticationToken) authentication); - } catch (final AdministrationException ae) { - unsuccessfulAuthentication(request, response, new AuthenticationServiceException(ae.getMessage(), ae)); - } - } - - @Override - protected void unsuccessfulAuthentication(final HttpServletRequest request, final HttpServletResponse response, final AuthenticationException failed) throws IOException, ServletException { - if (failed instanceof BadCredentialsException || failed instanceof AuthenticationCredentialsNotFoundException) { - response.setStatus(HttpServletResponse.SC_BAD_REQUEST); - } else if (failed instanceof AuthenticationServiceException) { - response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); - } else { - response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); - } - - response.setContentType("text/plain"); - - final PrintWriter out = response.getWriter(); - out.println(failed.getMessage()); - } - - public void setJwtService(JwtService jwtService) { - this.jwtService = jwtService; - } - - public void setLoginIdentityProvider(LoginIdentityProvider loginIdentityProvider) { - this.loginIdentityProvider = loginIdentityProvider; - } - - 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 setUserDetailsService(AuthenticationUserDetailsService<NiFiAuthenticationRequestToken> userDetailsService) { - this.userDetailsService = userDetailsService; - } - -} http://git-wip-us.apache.org/repos/asf/nifi/blob/7529694f/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/resources/nifi-web-security-context.xml ---------------------------------------------------------------------- diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/resources/nifi-web-security-context.xml b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/resources/nifi-web-security-context.xml index 0ffd46c..c88d303 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/resources/nifi-web-security-context.xml +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/resources/nifi-web-security-context.xml @@ -29,7 +29,7 @@ </bean> <!-- x509 validator --> - <bean id="x509Validator" class="org.apache.nifi.web.security.x509.X509CertificateValidator"> + <bean id="certificateValidator" class="org.apache.nifi.web.security.x509.X509CertificateValidator"> <property name="ocspValidator" ref="ocspValidator"/> </bean> http://git-wip-us.apache.org/repos/asf/nifi/blob/7529694f/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-canvas.js ---------------------------------------------------------------------- diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-canvas.js b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-canvas.js index 894ade8..09a8212 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-canvas.js +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-canvas.js @@ -65,7 +65,7 @@ nf.Canvas = (function () { banners: '../nifi-api/controller/banners', controller: '../nifi-api/controller', controllerConfig: '../nifi-api/controller/config', - loginConfig: '../nifi-api/controller/login/config', + accessConfig: '../nifi-api/access/config', cluster: '../nifi-api/cluster', d3Script: 'js/d3/d3.min.js' } @@ -1090,7 +1090,7 @@ nf.Canvas = (function () { // get the login config var loginXhr = $.ajax({ type: 'GET', - url: config.urls.loginConfig, + url: config.urls.accessConfig, dataType: 'json' });
