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/10/21 23:25:02 UTC
nifi git commit: NIFI-655: - Moving to token api to web-api. -
Creating an LoginProvider API for user/pass based authentication. - Creating
a module for funneling access to the authorized useres.
Repository: nifi
Updated Branches:
refs/heads/NIFI-655 d21d8f316 -> 852dbea95
NIFI-655:
- Moving to token api to web-api.
- Creating an LoginProvider API for user/pass based authentication.
- Creating a module for funneling access to the authorized useres.
Project: http://git-wip-us.apache.org/repos/asf/nifi/repo
Commit: http://git-wip-us.apache.org/repos/asf/nifi/commit/852dbea9
Tree: http://git-wip-us.apache.org/repos/asf/nifi/tree/852dbea9
Diff: http://git-wip-us.apache.org/repos/asf/nifi/diff/852dbea9
Branch: refs/heads/NIFI-655
Commit: 852dbea9501c307f50fb464c6dcfb9be6de9fb59
Parents: d21d8f3
Author: Matt Gilman <ma...@gmail.com>
Authored: Wed Oct 21 14:24:40 2015 -0700
Committer: Matt Gilman <ma...@gmail.com>
Committed: Wed Oct 21 14:24:40 2015 -0700
----------------------------------------------------------------------
nifi-login-api/pom.xml | 17 +
.../authentication/LoginIdentityProvider.java | 42 ++
.../nifi-authorized-users/pom.xml | 53 +++
.../nifi/authorized/users/AuthorizedUsers.java | 230 ++++++++++
.../src/main/xsd/users.xsd | 64 +++
.../nifi-file-authorization-provider/pom.xml | 4 +
.../FileAuthorizationProvider.java | 454 ++++++++-----------
.../nifi-web/nifi-web-api/pom.xml | 4 +
.../web/NiFiWebApiSecurityConfiguration.java | 73 ++-
.../nifi-web/nifi-web-security/pom.xml | 4 +
.../security/form/FormAuthenticationFilter.java | 20 +-
.../LoginIdentityProviderFactoryBean.java | 73 +++
.../NewAccountAuthenticationRequestToken.java | 2 +-
.../resources/nifi-web-security-context.xml | 5 +
.../nifi-framework/pom.xml | 1 +
nifi-nar-bundles/nifi-framework-bundle/pom.xml | 5 +
nifi-nar-bundles/nifi-jetty-bundle/pom.xml | 6 +
nifi-nar-bundles/pom.xml | 6 +
pom.xml | 6 +
19 files changed, 796 insertions(+), 273 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/nifi/blob/852dbea9/nifi-login-api/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-login-api/pom.xml b/nifi-login-api/pom.xml
new file mode 100644
index 0000000..a1849ce
--- /dev/null
+++ b/nifi-login-api/pom.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>org.apache.nifi</groupId>
+ <artifactId>nifi</artifactId>
+ <version>0.3.1-SNAPSHOT</version>
+ </parent>
+ <artifactId>nifi-login-api</artifactId>
+ <packaging>jar</packaging>
+ <dependencies>
+ <dependency>
+ <groupId>javax.servlet</groupId>
+ <artifactId>javax.servlet-api</artifactId>
+ </dependency>
+ </dependencies>
+</project>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/nifi/blob/852dbea9/nifi-login-api/src/main/java/org/apache/nifi/authentication/LoginIdentityProvider.java
----------------------------------------------------------------------
diff --git a/nifi-login-api/src/main/java/org/apache/nifi/authentication/LoginIdentityProvider.java b/nifi-login-api/src/main/java/org/apache/nifi/authentication/LoginIdentityProvider.java
new file mode 100644
index 0000000..c2bb18f
--- /dev/null
+++ b/nifi-login-api/src/main/java/org/apache/nifi/authentication/LoginIdentityProvider.java
@@ -0,0 +1,42 @@
+/*
+ * 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.authentication;
+
+import javax.servlet.http.HttpServletRequest;
+
+/**
+ * Identity provider that is able to authentication a user with
+ * username/password credentials.
+ */
+public interface LoginIdentityProvider {
+
+ /**
+ * Returns whether this provider supports user registration.
+ *
+ * @return whether user registration is supported
+ */
+ boolean supportsRegistration();
+
+ /**
+ * Authenticates the user making the specified request. Returns
+ * the user principal or null if the user is not authenticated.
+ *
+ * @param request the request
+ * @return the user principal
+ */
+ String authenticate(HttpServletRequest request);
+}
http://git-wip-us.apache.org/repos/asf/nifi/blob/852dbea9/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-authorized-users/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-authorized-users/pom.xml b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-authorized-users/pom.xml
new file mode 100644
index 0000000..458819e
--- /dev/null
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-authorized-users/pom.xml
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>org.apache.nifi</groupId>
+ <artifactId>nifi-framework</artifactId>
+ <version>0.3.1-SNAPSHOT</version>
+ </parent>
+ <artifactId>nifi-authorized-users</artifactId>
+ <build>
+ <resources>
+ <resource>
+ <directory>src/main/resources</directory>
+ </resource>
+ <resource>
+ <directory>src/main/xsd</directory>
+ </resource>
+ </resources>
+ <plugins>
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>jaxb2-maven-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>xjc</id>
+ <goals>
+ <goal>xjc</goal>
+ </goals>
+ <configuration>
+ <packageName>org.apache.nifi.user.generated</packageName>
+ </configuration>
+ </execution>
+ </executions>
+ <configuration>
+ <generateDirectory>${project.build.directory}/generated-sources/jaxb</generateDirectory>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-checkstyle-plugin</artifactId>
+ <configuration>
+ <excludes>**/user/generated/*.java</excludes>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.nifi</groupId>
+ <artifactId>nifi-api</artifactId>
+ </dependency>
+ </dependencies>
+</project>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/nifi/blob/852dbea9/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-authorized-users/src/main/java/org/apache/nifi/authorized/users/AuthorizedUsers.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-authorized-users/src/main/java/org/apache/nifi/authorized/users/AuthorizedUsers.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-authorized-users/src/main/java/org/apache/nifi/authorized/users/AuthorizedUsers.java
new file mode 100644
index 0000000..58c7856
--- /dev/null
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-authorized-users/src/main/java/org/apache/nifi/authorized/users/AuthorizedUsers.java
@@ -0,0 +1,230 @@
+/*
+ * 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.authorized.users;
+
+import java.io.File;
+import java.util.List;
+import javax.xml.XMLConstants;
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.JAXBElement;
+import javax.xml.bind.JAXBException;
+import javax.xml.bind.Marshaller;
+import javax.xml.bind.Unmarshaller;
+import javax.xml.transform.stream.StreamSource;
+import javax.xml.validation.Schema;
+import javax.xml.validation.SchemaFactory;
+import org.apache.nifi.authorization.exception.AuthorityAccessException;
+import org.apache.nifi.authorization.exception.UnknownIdentityException;
+import org.apache.nifi.user.generated.User;
+import org.apache.nifi.user.generated.Users;
+import org.xml.sax.SAXException;
+
+/**
+ * Access to the configured Authorized Users.
+ */
+public final class AuthorizedUsers {
+
+ private static final String USERS_XSD = "/users.xsd";
+ private static final String JAXB_GENERATED_PATH = "org.apache.nifi.user.generated";
+ private static final JAXBContext JAXB_CONTEXT = initializeJaxbContext();
+
+ /**
+ * Load the JAXBContext.
+ */
+ private static JAXBContext initializeJaxbContext() {
+ try {
+ return JAXBContext.newInstance(JAXB_GENERATED_PATH, AuthorizedUsers.class.getClassLoader());
+ } catch (JAXBException e) {
+ throw new RuntimeException("Unable to create JAXBContext.");
+ }
+ }
+
+ public static synchronized Users getUsers(final File usersFile) {
+ try {
+ // ensure the directory exists and it can be created
+ if (!usersFile.exists() && !usersFile.mkdirs()) {
+ throw new IllegalStateException("The users file does not exist and could not be created.");
+ }
+
+ // find the schema
+ final SchemaFactory schemaFactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
+ final Schema schema = schemaFactory.newSchema(AuthorizedUsers.class.getResource(USERS_XSD));
+
+ // attempt to unmarshal
+ final Unmarshaller unmarshaller = JAXB_CONTEXT.createUnmarshaller();
+ unmarshaller.setSchema(schema);
+ final JAXBElement<Users> element = unmarshaller.unmarshal(new StreamSource(usersFile), Users.class);
+ return element.getValue();
+ } catch (SAXException | JAXBException e) {
+ throw new AuthorityAccessException(e.getMessage(), e);
+ }
+ }
+
+ public static synchronized User getUser(final File usersFile, final FindUser finder) {
+ // load the users
+ final Users users = getUsers(usersFile);
+
+ // find the desired user
+ return finder.findUser(users.getUser());
+ }
+
+ public static synchronized List<User> getUsers(final File usersFile, final FindUsers finder) {
+ // load the users
+ final Users users = getUsers(usersFile);
+
+ // find the desired user
+ return finder.findUsers(users.getUser());
+ }
+
+ public static synchronized void createUser(final File usersFile, final File restoreFile, final CreateUser creator) {
+ // add the user
+ final Users users = getUsers(usersFile);
+ final List<User> userList = users.getUser();
+
+ // create the user
+ final User newUsers = creator.createUser();
+ userList.add(newUsers);
+
+ // save the users
+ saveUsers(usersFile, restoreFile, users);
+ }
+
+ public static synchronized void updateUser(final File usersFile, final File restoreFile, final FindUser finder, final UpdateUser updater) {
+ // update the user
+ final Users users = getUsers(usersFile);
+ final User user = finder.findUser(users.getUser());
+
+ // update the user
+ updater.updateUser(user);
+
+ // save the users
+ saveUsers(usersFile, restoreFile, users);
+ }
+
+ public static synchronized void updateUsers(final File usersFile, final File restoreFile, final FindUsers finder, final UpdateUsers updater) {
+ // update the user
+ final Users users = getUsers(usersFile);
+ final List<User> userToUpdate = finder.findUsers(users.getUser());
+
+ // update the user
+ updater.updateUsers(userToUpdate);
+
+ // save the users
+ saveUsers(usersFile, restoreFile, users);
+ }
+
+ public static synchronized Users removeUser(final File usersFile, final File restoreFile, final FindUser finder) {
+ // load the users
+ final Users users = getUsers(usersFile);
+ final List<User> userList = users.getUser();
+
+ // find the desired user
+ final User user = finder.findUser(userList);
+ userList.remove(user);
+
+ // save the users
+ saveUsers(usersFile, restoreFile, users);
+
+ return users;
+ }
+
+ public static synchronized Users removeUsers(final File usersFile, final File restoreFile, final FindUsers finder) {
+ // load the users
+ final Users users = getUsers(usersFile);
+ final List<User> userList = users.getUser();
+
+ // find the desired user
+ final List<User> usersToRemove = finder.findUsers(userList);
+ userList.removeAll(usersToRemove);
+
+ // save the users
+ saveUsers(usersFile, restoreFile, users);
+
+ return users;
+ }
+
+ private static synchronized void saveUsers(final File usersFile, final File restoreFile, final Users users) {
+ try {
+ final Marshaller marshaller = JAXB_CONTEXT.createMarshaller();
+ marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
+
+ // save users to restore directory before primary directory
+ if (restoreFile != null) {
+ marshaller.marshal(users, restoreFile);
+ }
+
+ // save users to primary directory
+ marshaller.marshal(users, usersFile);
+ } catch (JAXBException e) {
+ throw new AuthorityAccessException(e.getMessage(), e);
+ }
+ }
+
+ public static interface FindUser {
+
+ /**
+ * Finds the desired user. If the user cannot be found throws an UnknownIdentityException. Never returns null.
+ *
+ * @param users the users
+ * @return the desired user
+ * @throws UnknownIdentityException if the user cannot be found
+ */
+ User findUser(List<User> users) throws UnknownIdentityException;
+ }
+
+ public static interface FindUsers {
+
+ /**
+ * Finds the specified users.
+ *
+ * @param users
+ * @return
+ * @throws UnknownIdentityException
+ */
+ List<User> findUsers(List<User> users) throws UnknownIdentityException;
+ }
+
+ public static interface CreateUser {
+
+ /**
+ * Creates the user to add.
+ *
+ * @return the users to add
+ */
+ User createUser();
+ }
+
+ public static interface UpdateUser {
+
+ /**
+ * Updates the specified user.
+ *
+ * @param user the user
+ */
+ void updateUser(User user);
+ }
+
+ public static interface UpdateUsers {
+
+ /**
+ * Updates the specified users.
+ *
+ * @param users the users to update
+ */
+ void updateUsers(List<User> users);
+ }
+}
http://git-wip-us.apache.org/repos/asf/nifi/blob/852dbea9/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-authorized-users/src/main/xsd/users.xsd
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-authorized-users/src/main/xsd/users.xsd b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-authorized-users/src/main/xsd/users.xsd
new file mode 100644
index 0000000..4ee1e17
--- /dev/null
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-authorized-users/src/main/xsd/users.xsd
@@ -0,0 +1,64 @@
+<?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.
+-->
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
+ <!-- role -->
+ <xs:complexType name="Role">
+ <xs:attribute name="name">
+ <xs:simpleType>
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="ROLE_MONITOR"/>
+ <xs:enumeration value="ROLE_PROVENANCE"/>
+ <xs:enumeration value="ROLE_DFM"/>
+ <xs:enumeration value="ROLE_ADMIN"/>
+ <xs:enumeration value="ROLE_PROXY"/>
+ <xs:enumeration value="ROLE_NIFI"/>
+ </xs:restriction>
+ </xs:simpleType>
+ </xs:attribute>
+ </xs:complexType>
+
+ <!-- user -->
+ <xs:complexType name="User">
+ <xs:sequence>
+ <xs:element name="role" type="Role" minOccurs="0" maxOccurs="unbounded"/>
+ </xs:sequence>
+ <xs:attribute name="dn">
+ <xs:simpleType>
+ <xs:restriction base="xs:string">
+ <xs:minLength value="1"/>
+ <xs:pattern value=".*[^\s].*"/>
+ </xs:restriction>
+ </xs:simpleType>
+ </xs:attribute>
+ <xs:attribute name="group">
+ <xs:simpleType>
+ <xs:restriction base="xs:string">
+ <xs:minLength value="1"/>
+ <xs:pattern value=".*[^\s].*"/>
+ </xs:restriction>
+ </xs:simpleType>
+ </xs:attribute>
+ </xs:complexType>
+
+ <!-- users -->
+ <xs:element name="users">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element name="user" type="User" minOccurs="0" maxOccurs="unbounded"/>
+ </xs:sequence>
+ </xs:complexType>
+ </xs:element>
+</xs:schema>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/nifi/blob/852dbea9/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-file-authorization-provider/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-file-authorization-provider/pom.xml b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-file-authorization-provider/pom.xml
index d014262..c37378a 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-file-authorization-provider/pom.xml
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-file-authorization-provider/pom.xml
@@ -66,6 +66,10 @@
</dependency>
<dependency>
<groupId>org.apache.nifi</groupId>
+ <artifactId>nifi-authorized-users</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.nifi</groupId>
<artifactId>nifi-utils</artifactId>
</dependency>
<dependency>
http://git-wip-us.apache.org/repos/asf/nifi/blob/852dbea9/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-file-authorization-provider/src/main/java/org/apache/nifi/authorization/FileAuthorizationProvider.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-file-authorization-provider/src/main/java/org/apache/nifi/authorization/FileAuthorizationProvider.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-file-authorization-provider/src/main/java/org/apache/nifi/authorization/FileAuthorizationProvider.java
index 9c2cad5..d3e5061 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-file-authorization-provider/src/main/java/org/apache/nifi/authorization/FileAuthorizationProvider.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-file-authorization-provider/src/main/java/org/apache/nifi/authorization/FileAuthorizationProvider.java
@@ -18,21 +18,12 @@ package org.apache.nifi.authorization;
import java.io.File;
import java.io.IOException;
-import java.util.Collection;
+import java.util.ArrayList;
import java.util.EnumSet;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
-import javax.xml.XMLConstants;
-import javax.xml.bind.JAXBContext;
-import javax.xml.bind.JAXBElement;
-import javax.xml.bind.JAXBException;
-import javax.xml.bind.Marshaller;
-import javax.xml.bind.Unmarshaller;
-import javax.xml.transform.stream.StreamSource;
-import javax.xml.validation.Schema;
-import javax.xml.validation.SchemaFactory;
import org.apache.nifi.authorization.annotation.AuthorityProviderContext;
import org.apache.nifi.authorization.exception.AuthorityAccessException;
import org.apache.nifi.authorization.exception.IdentityAlreadyExistsException;
@@ -42,12 +33,17 @@ import org.apache.nifi.util.file.FileUtils;
import org.apache.nifi.user.generated.ObjectFactory;
import org.apache.nifi.user.generated.Role;
import org.apache.nifi.user.generated.User;
-import org.apache.nifi.user.generated.Users;
import org.apache.nifi.util.NiFiProperties;
import org.apache.commons.lang3.StringUtils;
+import org.apache.nifi.authorized.users.AuthorizedUsers;
+import org.apache.nifi.authorized.users.AuthorizedUsers.CreateUser;
+import org.apache.nifi.authorized.users.AuthorizedUsers.FindUser;
+import org.apache.nifi.authorized.users.AuthorizedUsers.FindUsers;
+import org.apache.nifi.authorized.users.AuthorizedUsers.UpdateUser;
+import org.apache.nifi.authorized.users.AuthorizedUsers.UpdateUsers;
+import org.apache.nifi.user.generated.Users;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import org.xml.sax.SAXException;
/**
* Provides identity checks and grants authorities.
@@ -55,25 +51,10 @@ import org.xml.sax.SAXException;
public class FileAuthorizationProvider implements AuthorityProvider {
private static final Logger logger = LoggerFactory.getLogger(FileAuthorizationProvider.class);
- private static final String USERS_XSD = "/users.xsd";
- private static final String JAXB_GENERATED_PATH = "org.apache.nifi.user.generated";
- private static final JAXBContext JAXB_CONTEXT = initializeJaxbContext();
-
- /**
- * Load the JAXBContext.
- */
- private static JAXBContext initializeJaxbContext() {
- try {
- return JAXBContext.newInstance(JAXB_GENERATED_PATH, FileAuthorizationProvider.class.getClassLoader());
- } catch (JAXBException e) {
- throw new RuntimeException("Unable to create JAXBContext.");
- }
- }
private NiFiProperties properties;
private File usersFile;
private File restoreUsersFile;
- private Users users;
private final Set<String> defaultAuthorities = new HashSet<>();
@Override
@@ -118,22 +99,6 @@ public class FileAuthorizationProvider implements AuthorityProvider {
}
- // load the users from the specified file
- if (usersFile.exists()) {
- // find the schema
- final SchemaFactory schemaFactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
- final Schema schema = schemaFactory.newSchema(FileAuthorizationProvider.class.getResource(USERS_XSD));
-
- // attempt to unmarshal
- final Unmarshaller unmarshaller = JAXB_CONTEXT.createUnmarshaller();
- unmarshaller.setSchema(schema);
- final JAXBElement<Users> element = unmarshaller.unmarshal(new StreamSource(usersFile), Users.class);
- users = element.getValue();
- } else {
- final ObjectFactory objFactory = new ObjectFactory();
- users = objFactory.createUsers();
- }
-
// attempt to load a default roles
final String rawDefaultAuthorities = configurationContext.getProperty("Default User Roles");
if (StringUtils.isNotBlank(rawDefaultAuthorities)) {
@@ -157,7 +122,7 @@ public class FileAuthorizationProvider implements AuthorityProvider {
StringUtils.join(invalidDefaultAuthorities, ", "), StringUtils.join(Authority.getRawAuthorities(), ", ")));
}
}
- } catch (IOException | ProviderCreationException | SAXException | JAXBException e) {
+ } catch (IOException | ProviderCreationException e) {
throw new ProviderCreationException(e);
}
@@ -172,64 +137,61 @@ public class FileAuthorizationProvider implements AuthorityProvider {
}
@Override
- public boolean doesDnExist(String dn) throws AuthorityAccessException {
+ public boolean doesDnExist(final String dn) throws AuthorityAccessException {
if (hasDefaultRoles()) {
return true;
}
- final User user = getUser(dn);
- return user != null;
+ return AuthorizedUsers.getUser(usersFile, new FindUserByDn(dn)) != null;
}
@Override
- public synchronized Set<Authority> getAuthorities(String dn) throws UnknownIdentityException, AuthorityAccessException {
+ public Set<Authority> getAuthorities(final String dn) throws UnknownIdentityException, AuthorityAccessException {
final Set<Authority> authorities = EnumSet.noneOf(Authority.class);
// get the user
- final User user = getUser(dn);
-
- // ensure the user was located
- if (user == null) {
- if (hasDefaultRoles()) {
- logger.debug(String.format("User DN not found: %s. Creating new user with default roles.", dn));
-
- // create the user (which will automatically add any default authorities)
- addUser(dn, null);
+ final User user = AuthorizedUsers.getUser(usersFile, new FindUser() {
+ @Override
+ public User findUser(List<User> users) {
+ final FindUser byDn = new FindUserByDn(dn);
+ User user = byDn.findUser(users);
+
+ // if the user is not found, add them and locate them
+ if (user == null) {
+ if (hasDefaultRoles()) {
+ logger.debug(String.format("User DN not found: %s. Creating new user with default roles.", dn));
+
+ // create the user (which will automatically add any default authorities)
+ addUser(dn, null);
+
+ // find the user that was just added
+ user = byDn.findUser(users);
+ } else {
+ throw new UnknownIdentityException(String.format("User DN not found: %s.", dn));
+ }
+ }
- // get the authorities for the newly created user
- authorities.addAll(getAuthorities(dn));
- } else {
- throw new UnknownIdentityException(String.format("User DN not found: %s.", dn));
- }
- } else {
- // create the authorities that this user has
- for (final Role role : user.getRole()) {
- authorities.add(Authority.valueOfAuthority(role.getName()));
+ return user;
}
+ });
+
+ // create the authorities that this user has
+ for (final Role role : user.getRole()) {
+ authorities.add(Authority.valueOfAuthority(role.getName()));
}
return authorities;
}
@Override
- public synchronized void setAuthorities(String dn, Set<Authority> authorities) throws UnknownIdentityException, AuthorityAccessException {
- // get the user
- final User user = getUser(dn);
-
- // ensure the user was located
- if (user == null) {
- throw new UnknownIdentityException(String.format("User DN not found: %s.", dn));
- }
-
- // add the user authorities
- setUserAuthorities(user, authorities);
-
- try {
- // save the file
- save();
- } catch (Exception e) {
- throw new AuthorityAccessException(e.getMessage(), e);
- }
+ public void setAuthorities(final String dn, final Set<Authority> authorities) throws UnknownIdentityException, AuthorityAccessException {
+ AuthorizedUsers.updateUser(usersFile, restoreUsersFile, new FindUserByDn(dn), new UpdateUser() {
+ @Override
+ public void updateUser(User user) {
+ // add the user authorities
+ setUserAuthorities(user, authorities);
+ }
+ });
}
private void setUserAuthorities(final User user, final Set<Authority> authorities) {
@@ -248,46 +210,45 @@ public class FileAuthorizationProvider implements AuthorityProvider {
}
@Override
- public synchronized void addUser(String dn, String group) throws IdentityAlreadyExistsException, AuthorityAccessException {
- final User user = getUser(dn);
+ public void addUser(final String dn, final String group) throws IdentityAlreadyExistsException, AuthorityAccessException {
+ AuthorizedUsers.createUser(usersFile, restoreUsersFile, new CreateUser() {
+ @Override
+ public User createUser() {
+ final User user = AuthorizedUsers.getUser(usersFile, new FindUserByDn(dn));
+
+ // ensure the user doesn't already exist
+ if (user != null) {
+ throw new IdentityAlreadyExistsException(String.format("User DN already exists: %s", dn));
+ }
- // ensure the user doesn't already exist
- if (user != null) {
- throw new IdentityAlreadyExistsException(String.format("User DN already exists: %s", dn));
- }
+ // create the new user
+ final ObjectFactory objFactory = new ObjectFactory();
+ final User newUser = objFactory.createUser();
- // create the new user
- final ObjectFactory objFactory = new ObjectFactory();
- final User newUser = objFactory.createUser();
+ // set the user properties
+ newUser.setDn(dn);
+ newUser.setGroup(group);
- // set the user properties
- newUser.setDn(dn);
- newUser.setGroup(group);
+ // add default roles if appropriate
+ if (hasDefaultRoles()) {
+ for (final String authority : defaultAuthorities) {
+ Role role = objFactory.createRole();
+ role.setName(authority);
- // add default roles if appropriate
- if (hasDefaultRoles()) {
- for (final String authority : defaultAuthorities) {
- Role role = objFactory.createRole();
- role.setName(authority);
+ // add the role
+ newUser.getRole().add(role);
+ }
+ }
- // add the role
- newUser.getRole().add(role);
+ return newUser;
}
- }
-
- // add the user
- users.getUser().add(newUser);
-
- try {
- // save the file
- save();
- } catch (Exception e) {
- throw new AuthorityAccessException(e.getMessage(), e);
- }
+ });
}
@Override
- public synchronized Set<String> getUsers(Authority authority) throws AuthorityAccessException {
+ public Set<String> getUsers(final Authority authority) throws AuthorityAccessException {
+ final Users users = AuthorizedUsers.getUsers(usersFile);
+
final Set<String> userSet = new HashSet<>();
for (final User user : users.getUser()) {
for (final Role role : user.getRole()) {
@@ -296,138 +257,61 @@ public class FileAuthorizationProvider implements AuthorityProvider {
}
}
}
+
return userSet;
}
@Override
- public synchronized void revokeUser(String dn) throws UnknownIdentityException, AuthorityAccessException {
- // get the user
- final User user = getUser(dn);
-
- // ensure the user was located
- if (user == null) {
- throw new UnknownIdentityException(String.format("User DN not found: %s.", dn));
- }
-
- // remove the specified user
- users.getUser().remove(user);
-
- try {
- // save the file
- save();
- } catch (Exception e) {
- throw new AuthorityAccessException(e.getMessage(), e);
- }
+ public void revokeUser(final String dn) throws UnknownIdentityException, AuthorityAccessException {
+ AuthorizedUsers.removeUser(usersFile, restoreUsersFile, new FindUserByDn(dn));
}
@Override
- public void setUsersGroup(Set<String> dns, String group) throws UnknownIdentityException, AuthorityAccessException {
- final Collection<User> groupedUsers = new HashSet<>();
-
- // get the specified users
- for (final String dn : dns) {
- // get the user
- final User user = getUser(dn);
-
- // ensure the user was located
- if (user == null) {
- throw new UnknownIdentityException(String.format("User DN not found: %s.", dn));
+ public void setUsersGroup(final Set<String> dns, final String group) throws UnknownIdentityException, AuthorityAccessException {
+ AuthorizedUsers.updateUsers(usersFile, restoreUsersFile, new FindUsersByDn(dns), new UpdateUsers() {
+ @Override
+ public void updateUsers(List<User> users) {
+ // update each user group
+ for (final User user : users) {
+ user.setGroup(group);
+ }
}
-
- groupedUsers.add(user);
- }
-
- // update each user group
- for (final User user : groupedUsers) {
- user.setGroup(group);
- }
-
- try {
- // save the file
- save();
- } catch (Exception e) {
- throw new AuthorityAccessException(e.getMessage(), e);
- }
+ });
}
@Override
public void ungroupUser(String dn) throws UnknownIdentityException, AuthorityAccessException {
- // get the user
- final User user = getUser(dn);
-
- // ensure the user was located
- if (user == null) {
- throw new UnknownIdentityException(String.format("User DN not found: %s.", dn));
- }
-
- // remove the users group
- user.setGroup(null);
-
- try {
- // save the file
- save();
- } catch (Exception e) {
- throw new AuthorityAccessException(e.getMessage(), e);
- }
+ AuthorizedUsers.updateUser(usersFile, restoreUsersFile, new FindUserByDn(dn), new UpdateUser() {
+ @Override
+ public void updateUser(User user) {
+ // remove the users group
+ user.setGroup(null);
+ }
+ });
}
@Override
- public void ungroup(String group) throws AuthorityAccessException {
- // get the user group
- final Collection<User> userGroup = getUserGroup(group);
-
- // ensure the user group was located
- if (userGroup == null) {
- return;
- }
-
- // update each user group
- for (final User user : userGroup) {
- user.setGroup(null);
- }
-
- try {
- // save the file
- save();
- } catch (Exception e) {
- throw new AuthorityAccessException(e.getMessage(), e);
- }
+ public void ungroup(final String group) throws AuthorityAccessException {
+ AuthorizedUsers.updateUsers(usersFile, restoreUsersFile, new FindUsersByGroup(group), new UpdateUsers() {
+ @Override
+ public void updateUsers(List<User> users) {
+ // update each user group
+ for (final User user : users) {
+ user.setGroup(null);
+ }
+ }
+ });
}
@Override
- public String getGroupForUser(String dn) throws UnknownIdentityException, AuthorityAccessException {
- // get the user
- final User user = getUser(dn);
-
- // ensure the user was located
- if (user == null) {
- throw new UnknownIdentityException(String.format("User DN not found: %s.", dn));
- }
-
+ public String getGroupForUser(final String dn) throws UnknownIdentityException, AuthorityAccessException {
+ final User user = AuthorizedUsers.getUser(usersFile, new FindUserByDn(dn));
return user.getGroup();
}
@Override
public void revokeGroup(String group) throws UnknownIdentityException, AuthorityAccessException {
- // get the user group
- final Collection<User> userGroup = getUserGroup(group);
-
- // ensure the user group was located
- if (userGroup == null) {
- throw new UnknownIdentityException(String.format("User group not found: %s.", group));
- }
-
- // remove each user in the group
- for (final User user : userGroup) {
- users.getUser().remove(user);
- }
-
- try {
- // save the file
- save();
- } catch (Exception e) {
- throw new AuthorityAccessException(e.getMessage(), e);
- }
+ AuthorizedUsers.removeUsers(usersFile, restoreUsersFile, new FindUsersByGroup(group));
}
/**
@@ -438,59 +322,107 @@ public class FileAuthorizationProvider implements AuthorityProvider {
return DownloadAuthorization.approved();
}
- private User getUser(String dn) throws UnknownIdentityException {
- // ensure the DN was specified
- if (dn == null) {
- throw new UnknownIdentityException("User DN not specified.");
- }
+ @AuthorityProviderContext
+ public void setNiFiProperties(NiFiProperties properties) {
+ this.properties = properties;
+ }
- // attempt to get the user and ensure it was located
- User desiredUser = null;
- for (final User user : users.getUser()) {
- if (dn.equalsIgnoreCase(user.getDn())) {
- desiredUser = user;
- break;
+ public static class FindUserByDn implements FindUser {
+
+ private final String dn;
+
+ public FindUserByDn(String dn) {
+ // ensure the DN was specified
+ if (dn == null) {
+ throw new UnknownIdentityException("User DN not specified.");
}
+
+ this.dn = dn;
}
- return desiredUser;
+ @Override
+ public User findUser(List<User> users) {
+ // attempt to get the user and ensure it was located
+ User desiredUser = null;
+ for (final User user : users) {
+ if (dn.equalsIgnoreCase(user.getDn())) {
+ desiredUser = user;
+ break;
+ }
+ }
+
+ if (desiredUser == null) {
+ throw new UnknownIdentityException(String.format("User DN not found: %s.", dn));
+ }
+
+ return desiredUser;
+ }
}
- private Collection<User> getUserGroup(String group) throws UnknownIdentityException {
- // ensure the DN was specified
- if (group == null) {
- throw new UnknownIdentityException("User group not specified.");
+ public static class FindUsersByGroup implements FindUsers {
+
+ private final String group;
+
+ public FindUsersByGroup(String group) {
+ // ensure the group was specified
+ if (group == null) {
+ throw new UnknownIdentityException("User group not specified.");
+ }
+
+ this.group = group;
}
- // get all users with this group
- Collection<User> userGroup = null;
- for (final User user : users.getUser()) {
- if (group.equals(user.getGroup())) {
- if (userGroup == null) {
- userGroup = new HashSet<>();
+ @Override
+ public List<User> findUsers(List<User> users) throws UnknownIdentityException {
+ // get all users with this group
+ List<User> userGroup = new ArrayList<>();
+ for (final User user : users) {
+ if (group.equals(user.getGroup())) {
+ userGroup.add(user);
}
- userGroup.add(user);
}
- }
- return userGroup;
+ // ensure the user group was located
+ if (userGroup.isEmpty()) {
+ throw new UnknownIdentityException(String.format("User group not found: %s.", group));
+ }
+
+ return userGroup;
+ }
}
- private void save() throws Exception {
- final Marshaller marshaller = JAXB_CONTEXT.createMarshaller();
- marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
+ public static class FindUsersByDn implements FindUsers {
+
+ private final Set<String> dns;
+
+ public FindUsersByDn(Set<String> dns) {
+ // ensure the group was specified
+ if (dns == null) {
+ throw new UnknownIdentityException("User group not specified.");
+ }
- // save users to restore directory before primary directory
- if (restoreUsersFile != null) {
- marshaller.marshal(users, restoreUsersFile);
+ this.dns = dns;
}
- // save users to primary directory
- marshaller.marshal(users, usersFile);
- }
+ @Override
+ public List<User> findUsers(List<User> users) throws UnknownIdentityException {
+ final Set<String> copy = new HashSet<>(dns);
- @AuthorityProviderContext
- public void setNiFiProperties(NiFiProperties properties) {
- this.properties = properties;
+ // get all users with this group
+ List<User> userList = new ArrayList<>();
+ for (final User user : users) {
+ if (copy.contains(user.getDn())) {
+ copy.remove(user.getDn());
+ userList.add(user);
+ }
+ }
+
+ if (!copy.isEmpty()) {
+ throw new UnknownIdentityException("Unable to find users with DNs: " + StringUtils.join(copy, ", "));
+ }
+
+ return userList;
+ }
}
+
}
http://git-wip-us.apache.org/repos/asf/nifi/blob/852dbea9/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/pom.xml b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/pom.xml
index a74dfb0..1ba5dab 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/pom.xml
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/pom.xml
@@ -146,6 +146,10 @@
</dependency>
<dependency>
<groupId>org.apache.nifi</groupId>
+ <artifactId>nifi-login-api</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.nifi</groupId>
<artifactId>nifi-nar-utils</artifactId>
</dependency>
<dependency>
http://git-wip-us.apache.org/repos/asf/nifi/blob/852dbea9/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 0317f19..7341545 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,11 +16,17 @@
*/
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.form.FormAuthenticationFilter;
+import org.apache.nifi.web.security.jwt.JwtAuthenticationFilter;
+import org.apache.nifi.web.security.jwt.JwtAuthenticationProvider;
+import org.apache.nifi.web.security.jwt.JwtService;
import org.apache.nifi.web.security.node.NodeAuthorizedUserFilter;
import org.apache.nifi.web.security.x509.SubjectDnX509PrincipalExtractor;
import org.apache.nifi.web.security.x509.X509AuthenticationFilter;
@@ -40,6 +46,7 @@ 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;
/**
* NiFi Web Api Spring security
@@ -52,6 +59,8 @@ public class NiFiWebApiSecurityConfiguration extends WebSecurityConfigurerAdapte
private NiFiProperties properties;
private UserService userService;
private AuthenticationUserDetailsService userDetailsService;
+ private JwtService jwtService;
+ private LoginIdentityProvider loginIdentityProvider;
public NiFiWebApiSecurityConfiguration() {
super(true); // disable defaults
@@ -61,7 +70,7 @@ public class NiFiWebApiSecurityConfiguration extends WebSecurityConfigurerAdapte
protected void configure(HttpSecurity http) throws Exception {
http
.rememberMe().disable()
- .exceptionHandling()
+ .exceptionHandling()
.authenticationEntryPoint(new NiFiAuthenticationEntryPoint())
.and()
.authorizeRequests()
@@ -70,13 +79,26 @@ public class NiFiWebApiSecurityConfiguration extends WebSecurityConfigurerAdapte
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS);
- // cluster - authorized user
- final NodeAuthorizedUserFilter authorizedUserFilter = new NodeAuthorizedUserFilter(properties);
- http.addFilterBefore(authorizedUserFilter, AnonymousAuthenticationFilter.class);
+ // verify that login authentication is enabled
+ if (loginIdentityProvider != null) {
+ // login authentication for /token - exchanges for JWT for subsequent API usage
+ http.addFilterBefore(buildFormLoginFilter("/token"), UsernamePasswordAuthenticationFilter.class);
+
+ // login registration
+ if (loginIdentityProvider.supportsRegistration()) {
+ http.addFilterBefore(buildRegistrationFilter("/registration"), UsernamePasswordAuthenticationFilter.class);
+ }
+ }
+
+ // cluster authorized user
+ http.addFilterBefore(buildNodeAuthorizedUserFilter(), AnonymousAuthenticationFilter.class);
// x509
http.addFilterBefore(buildX509Filter(), AnonymousAuthenticationFilter.class);
+ // jwt
+ http.addFilterBefore(buildJwtFilter(), AnonymousAuthenticationFilter.class);
+
// anonymous
http.anonymous().authenticationFilter(buildAnonymousFilter());
}
@@ -90,11 +112,37 @@ public class NiFiWebApiSecurityConfiguration extends WebSecurityConfigurerAdapte
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
- // x509
+ // TODO - dont think we need different authenticationproviders...
final AuthenticationProvider x509AuthenticationProvider = new NiFiAuthenticationProvider(new X509AuthenticationProvider(), userDetailsService);
-
+ final AuthenticationProvider jwtAuthenticationProvider = new NiFiAuthenticationProvider(new JwtAuthenticationProvider(), userDetailsService);
+
auth
- .authenticationProvider(x509AuthenticationProvider);
+ .authenticationProvider(x509AuthenticationProvider)
+ .authenticationProvider(jwtAuthenticationProvider)
+ .inMemoryAuthentication()
+ .withUser("user").password("password").roles("USER");
+ }
+
+ private FormAuthenticationFilter buildFormLoginFilter(final String url) {
+ final FormAuthenticationFilter loginFilter = new FormAuthenticationFilter(url);
+ loginFilter.setJwtService(jwtService);
+ loginFilter.setLoginIdentityProvider(loginIdentityProvider);
+ return loginFilter;
+ }
+
+ private Filter buildRegistrationFilter(final String url) {
+ return null;
+ }
+
+ private NodeAuthorizedUserFilter buildNodeAuthorizedUserFilter() {
+ return new NodeAuthorizedUserFilter(properties);
+ }
+
+ private JwtAuthenticationFilter buildJwtFilter() throws Exception {
+ final JwtAuthenticationFilter jwtFilter = new JwtAuthenticationFilter();
+ jwtFilter.setJwtService(jwtService);
+ jwtFilter.setAuthenticationManager(authenticationManager());
+ return jwtFilter;
}
private X509AuthenticationFilter buildX509Filter() throws Exception {
@@ -111,7 +159,7 @@ public class NiFiWebApiSecurityConfiguration extends WebSecurityConfigurerAdapte
anonymousFilter.setUserService(userService);
return anonymousFilter;
}
-
+
@Autowired
public void setUserDetailsService(AuthenticationUserDetailsService userDetailsService) {
this.userDetailsService = userDetailsService;
@@ -127,4 +175,13 @@ public class NiFiWebApiSecurityConfiguration extends WebSecurityConfigurerAdapte
this.properties = properties;
}
+ @Autowired
+ public void setJwtService(JwtService jwtService) {
+ this.jwtService = jwtService;
+ }
+
+ @Autowired
+ public void setLoginIdentityProvider(LoginIdentityProvider loginIdentityProvider) {
+ this.loginIdentityProvider = loginIdentityProvider;
+ }
}
http://git-wip-us.apache.org/repos/asf/nifi/blob/852dbea9/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/pom.xml b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/pom.xml
index 59d81e1..4956095 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/pom.xml
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/pom.xml
@@ -33,6 +33,10 @@
</dependency>
<dependency>
<groupId>org.apache.nifi</groupId>
+ <artifactId>nifi-login-api</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.nifi</groupId>
<artifactId>nifi-web-utils</artifactId>
</dependency>
<dependency>
http://git-wip-us.apache.org/repos/asf/nifi/blob/852dbea9/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/form/FormAuthenticationFilter.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/form/FormAuthenticationFilter.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/form/FormAuthenticationFilter.java
index 46e74f3..e60c7d1 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/form/FormAuthenticationFilter.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/form/FormAuthenticationFilter.java
@@ -22,6 +22,7 @@ import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
+import org.apache.nifi.authentication.LoginIdentityProvider;
import org.apache.nifi.web.security.jwt.JwtService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -31,22 +32,31 @@ import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter;
/**
+ * Exchanges a successful login with the configured provider for a ID token for accessing the API.
*/
public class FormAuthenticationFilter extends AbstractAuthenticationProcessingFilter {
private static final Logger logger = LoggerFactory.getLogger(FormAuthenticationFilter.class);
private JwtService jwtService;
+ private LoginIdentityProvider loginIdentityProvider;
public FormAuthenticationFilter(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 {
- final String username = request.getParameter("username");
- final String password = request.getParameter("password");
- return getAuthenticationManager().authenticate(new UsernamePasswordAuthenticationToken(username, password));
+ final String principal = loginIdentityProvider.authenticate(request);
+
+ if (principal == null) {
+ return null;
+ }
+
+ return new UsernamePasswordAuthenticationToken(principal, null);
}
@Override
@@ -71,4 +81,8 @@ public class FormAuthenticationFilter extends AbstractAuthenticationProcessingFi
this.jwtService = jwtService;
}
+ public void setLoginIdentityProvider(LoginIdentityProvider loginIdentityProvider) {
+ this.loginIdentityProvider = loginIdentityProvider;
+ }
+
}
http://git-wip-us.apache.org/repos/asf/nifi/blob/852dbea9/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/spring/LoginIdentityProviderFactoryBean.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/spring/LoginIdentityProviderFactoryBean.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/spring/LoginIdentityProviderFactoryBean.java
new file mode 100644
index 0000000..7a09f93
--- /dev/null
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/spring/LoginIdentityProviderFactoryBean.java
@@ -0,0 +1,73 @@
+/*
+ * 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.spring;
+
+import javax.servlet.http.HttpServletRequest;
+import org.apache.nifi.authentication.LoginIdentityProvider;
+import org.apache.nifi.util.NiFiProperties;
+import org.springframework.beans.BeansException;
+import org.springframework.beans.factory.FactoryBean;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.ApplicationContextAware;
+
+/**
+ *
+ */
+public class LoginIdentityProviderFactoryBean implements FactoryBean, ApplicationContextAware {
+
+ private ApplicationContext context;
+ private NiFiProperties properties;
+ private LoginIdentityProvider provider;
+
+ @Override
+ public Object getObject() throws Exception {
+// if (provider == null) {
+// provider = new LoginIdentityProvider() {
+// @Override
+// public boolean supportsRegistration() {
+// return false;
+// }
+//
+// @Override
+// public String authenticate(HttpServletRequest request) {
+// return "Yo!";
+// }
+// };
+// }
+
+ return provider;
+ }
+
+ @Override
+ public Class getObjectType() {
+ return LoginIdentityProvider.class;
+ }
+
+ @Override
+ public boolean isSingleton() {
+ return true;
+ }
+
+ public void setProperties(NiFiProperties properties) {
+ this.properties = properties;
+ }
+
+ @Override
+ public void setApplicationContext(ApplicationContext context) throws BeansException {
+ this.context = context;
+ }
+}
http://git-wip-us.apache.org/repos/asf/nifi/blob/852dbea9/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/token/NewAccountAuthenticationRequestToken.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/token/NewAccountAuthenticationRequestToken.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/token/NewAccountAuthenticationRequestToken.java
index 41cc0c0..6fee4ec 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/token/NewAccountAuthenticationRequestToken.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/token/NewAccountAuthenticationRequestToken.java
@@ -19,7 +19,7 @@ package org.apache.nifi.web.security.token;
import org.apache.nifi.web.security.user.NewAccountRequest;
/**
- * This is an Authentication Token for a user that is request authentication in order to submit a new account request.
+ * This is an Authentication Token for a user that is requesting authentication in order to submit a new account request.
*/
public class NewAccountAuthenticationRequestToken extends NiFiAuthenticationRequestToken {
http://git-wip-us.apache.org/repos/asf/nifi/blob/852dbea9/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 b201364..5f4e1b2 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
@@ -63,6 +63,11 @@
<!-- jwt service -->
<bean id="jwtService" class="org.apache.nifi.web.security.jwt.JwtService"></bean>
+ <!-- login identity provider -->
+ <bean id="loginIdentityProvider" class="org.apache.nifi.web.security.spring.LoginIdentityProviderFactoryBean">
+ <property name="properties" ref="nifiProperties"/>
+ </bean>
+
<!-- performs ocsp certificate validation -->
<!-- <bean id="ocspCertificateValidator" class="org.apache.nifi.web.security.x509.ocsp.OcspCertificateValidator">
<constructor-arg ref="nifiProperties"/>
http://git-wip-us.apache.org/repos/asf/nifi/blob/852dbea9/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/pom.xml b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/pom.xml
index b6f3f9c..61d1b17 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/pom.xml
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/pom.xml
@@ -40,6 +40,7 @@
<module>nifi-web</module>
<module>nifi-resources</module>
<module>nifi-documentation</module>
+ <module>nifi-authorized-users</module>
</modules>
<dependencies>
<dependency>
http://git-wip-us.apache.org/repos/asf/nifi/blob/852dbea9/nifi-nar-bundles/nifi-framework-bundle/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/pom.xml b/nifi-nar-bundles/nifi-framework-bundle/pom.xml
index f78e497..3f90b49 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/pom.xml
+++ b/nifi-nar-bundles/nifi-framework-bundle/pom.xml
@@ -60,6 +60,11 @@
</dependency>
<dependency>
<groupId>org.apache.nifi</groupId>
+ <artifactId>nifi-authorized-users</artifactId>
+ <version>0.3.1-SNAPSHOT</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.nifi</groupId>
<artifactId>nifi-client-dto</artifactId>
<version>0.3.1-SNAPSHOT</version>
</dependency>
http://git-wip-us.apache.org/repos/asf/nifi/blob/852dbea9/nifi-nar-bundles/nifi-jetty-bundle/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-jetty-bundle/pom.xml b/nifi-nar-bundles/nifi-jetty-bundle/pom.xml
index 3cdb3b8..287cd4d 100644
--- a/nifi-nar-bundles/nifi-jetty-bundle/pom.xml
+++ b/nifi-nar-bundles/nifi-jetty-bundle/pom.xml
@@ -73,5 +73,11 @@
<artifactId>jetty-jsp-jdt</artifactId>
<scope>compile</scope>
</dependency>
+ <dependency>
+ <groupId>org.apache.nifi</groupId>
+ <artifactId>nifi-login-api</artifactId>
+ <version>0.3.1-SNAPSHOT</version>
+ <scope>compile</scope>
+ </dependency>
</dependencies>
</project>
http://git-wip-us.apache.org/repos/asf/nifi/blob/852dbea9/nifi-nar-bundles/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/pom.xml b/nifi-nar-bundles/pom.xml
index 841818a..fb24aa8 100644
--- a/nifi-nar-bundles/pom.xml
+++ b/nifi-nar-bundles/pom.xml
@@ -113,6 +113,12 @@
</dependency>
<dependency>
<groupId>org.apache.nifi</groupId>
+ <artifactId>nifi-login-api</artifactId>
+ <version>0.3.1-SNAPSHOT</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.nifi</groupId>
<artifactId>nifi-runtime</artifactId>
<version>0.3.1-SNAPSHOT</version>
<scope>provided</scope>
http://git-wip-us.apache.org/repos/asf/nifi/blob/852dbea9/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index 94a3e96..b32583e 100644
--- a/pom.xml
+++ b/pom.xml
@@ -32,6 +32,7 @@
<module>nifi-docs</module>
<module>nifi-maven-archetypes</module>
<module>nifi-external</module>
+ <module>nifi-login-api</module>
</modules>
<url>http://nifi.apache.org</url>
<organization>
@@ -687,6 +688,11 @@
</dependency>
<dependency>
<groupId>org.apache.nifi</groupId>
+ <artifactId>nifi-login-api</artifactId>
+ <version>0.3.1-SNAPSHOT</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.nifi</groupId>
<artifactId>nifi-utils</artifactId>
<version>0.3.1-SNAPSHOT</version>
</dependency>