mirror of
https://github.com/apache/nifi.git
synced 2025-02-09 03:25:04 +00:00
NIFI-8363 Added Single User Login Identity Provider and Authorizer (#4968)
* NIFI-8363 Added Single User Login Identity Provider and Authorizer - Reads and writes username and hashed password in login-identity-providers.xml - Generates random username using java.util.UUID.randomUUID() - Generates random password using java.security.SecureRandom with Base64 encoding - Writes generated password hash using bcrypt * NIFI-8363 Updated SingleUserAuthorizer to require SingleUserLoginIdentityProvider * NIFI-8363 Added handling of null login identity provider property
This commit is contained in:
parent
74531fa1ca
commit
052c60dc53
@ -0,0 +1,35 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
contributor license agreements. See the NOTICE file distributed with
|
||||
this work for additional information regarding copyright ownership.
|
||||
The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
(the "License"); you may not use this file except in compliance with
|
||||
the License. You may obtain a copy of the License at
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>org.apache.nifi</groupId>
|
||||
<artifactId>nifi-single-user-iaa-providers-bundle</artifactId>
|
||||
<version>1.14.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
<artifactId>nifi-single-user-iaa-providers-nar</artifactId>
|
||||
<packaging>nar</packaging>
|
||||
<properties>
|
||||
<maven.javadoc.skip>true</maven.javadoc.skip>
|
||||
<source.skip>true</source.skip>
|
||||
</properties>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.apache.nifi</groupId>
|
||||
<artifactId>nifi-single-user-iaa-providers</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
@ -0,0 +1,232 @@
|
||||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed 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.
|
||||
|
||||
APACHE NIFI SUBCOMPONENTS:
|
||||
|
||||
The Apache NiFi project contains subcomponents with separate copyright
|
||||
notices and license terms. Your use of the source code for the these
|
||||
subcomponents is subject to the terms and conditions of the following
|
||||
licenses.
|
||||
|
||||
The binary distribution of this product bundles 'Bouncy Castle JDK 1.5'
|
||||
under an MIT style license.
|
||||
|
||||
Copyright (c) 2000 - 2015 The Legion of the Bouncy Castle Inc. (http://www.bouncycastle.org)
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
@ -0,0 +1,21 @@
|
||||
nifi-single-user-iaa-providers-nar
|
||||
Copyright 2015-2020 The Apache Software Foundation
|
||||
|
||||
This product includes software developed at
|
||||
The Apache Software Foundation (http://www.apache.org/).
|
||||
|
||||
******************
|
||||
Apache Software License v2
|
||||
******************
|
||||
|
||||
The following binary components are provided under the Apache Software License v2
|
||||
|
||||
(ASLv2) BCrypt Password Hashing Function (at.favre.lib:bcrypt:jar:0.9.0 - https://github.com/patrickfav/bcrypt)
|
||||
The following NOTICE information applies:
|
||||
BCrypt Password Hashing Function 0.9.0
|
||||
Copyright 2018 Patrick Favre-Bulle
|
||||
|
||||
(ASLv2) Bytes Utility Library (at.favre.lib:bytes:jar:1.3.0 - https://github.com/patrickfav/bytes-java)
|
||||
The following NOTICE information applies:
|
||||
Bytes Utility Library 1.3.0
|
||||
Copyright 2017 Patrick Favre-Bulle
|
@ -0,0 +1,50 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
contributor license agreements. See the NOTICE file distributed with
|
||||
this work for additional information regarding copyright ownership.
|
||||
The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
(the "License"); you may not use this file except in compliance with
|
||||
the License. You may obtain a copy of the License at
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>org.apache.nifi</groupId>
|
||||
<artifactId>nifi-single-user-iaa-providers-bundle</artifactId>
|
||||
<version>1.14.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
<artifactId>nifi-single-user-iaa-providers</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.apache.nifi</groupId>
|
||||
<artifactId>nifi-api</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.nifi</groupId>
|
||||
<artifactId>nifi-framework-api</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.nifi</groupId>
|
||||
<artifactId>nifi-utils</artifactId>
|
||||
<version>1.14.0-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.nifi</groupId>
|
||||
<artifactId>nifi-properties</artifactId>
|
||||
<version>1.14.0-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>at.favre.lib</groupId>
|
||||
<artifactId>bcrypt</artifactId>
|
||||
<version>0.9.0</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
@ -0,0 +1,168 @@
|
||||
/*
|
||||
* 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.single.user;
|
||||
|
||||
import org.apache.nifi.authentication.AuthenticationResponse;
|
||||
import org.apache.nifi.authentication.LoginCredentials;
|
||||
import org.apache.nifi.authentication.LoginIdentityProvider;
|
||||
import org.apache.nifi.authentication.LoginIdentityProviderConfigurationContext;
|
||||
import org.apache.nifi.authentication.LoginIdentityProviderInitializationContext;
|
||||
import org.apache.nifi.authentication.annotation.LoginIdentityProviderContext;
|
||||
import org.apache.nifi.authentication.exception.InvalidLoginCredentialsException;
|
||||
import org.apache.nifi.authentication.exception.ProviderCreationException;
|
||||
import org.apache.nifi.authentication.single.user.encoder.BCryptPasswordEncoder;
|
||||
import org.apache.nifi.authentication.single.user.encoder.PasswordEncoder;
|
||||
import org.apache.nifi.authentication.single.user.writer.LoginCredentialsWriter;
|
||||
import org.apache.nifi.authentication.single.user.writer.StandardLoginCredentialsWriter;
|
||||
import org.apache.nifi.util.NiFiProperties;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.security.SecureRandom;
|
||||
import java.util.Base64;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* Single User Login Identity Provider using bcrypt password encoder
|
||||
*/
|
||||
public class SingleUserLoginIdentityProvider implements LoginIdentityProvider {
|
||||
protected static final String USERNAME_PROPERTY = "Username";
|
||||
|
||||
protected static final String PASSWORD_PROPERTY = "Password";
|
||||
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(SingleUserLoginIdentityProvider.class);
|
||||
|
||||
private static final Base64.Encoder RANDOM_BYTE_ENCODER = Base64.getEncoder().withoutPadding();
|
||||
|
||||
private static final int RANDOM_BYTE_LENGTH = 24;
|
||||
|
||||
private static final long EXPIRATION = TimeUnit.HOURS.toMillis(1);
|
||||
|
||||
protected PasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
|
||||
|
||||
private File loginIdentityProviderConfigurationFile;
|
||||
|
||||
private LoginCredentials configuredCredentials;
|
||||
|
||||
/**
|
||||
* Set NiFi Properties using method injection
|
||||
*
|
||||
* @param niFiProperties NiFi Properties
|
||||
*/
|
||||
@LoginIdentityProviderContext
|
||||
public void setProperties(final NiFiProperties niFiProperties) {
|
||||
loginIdentityProviderConfigurationFile = niFiProperties.getLoginIdentityProviderConfigurationFile();
|
||||
}
|
||||
|
||||
/**
|
||||
* Authenticate using Credentials comparing password and then username for verification
|
||||
*
|
||||
* @param credentials Login Credentials
|
||||
* @return Authentication Response
|
||||
* @throws InvalidLoginCredentialsException Thrown on unverified username or password
|
||||
*/
|
||||
@Override
|
||||
public AuthenticationResponse authenticate(final LoginCredentials credentials) throws InvalidLoginCredentialsException {
|
||||
final String password = credentials.getPassword();
|
||||
if (isPasswordVerified(password)) {
|
||||
final String username = credentials.getUsername();
|
||||
if (isUsernameVerified(username)) {
|
||||
return new AuthenticationResponse(username, username, EXPIRATION, getClass().getSimpleName());
|
||||
} else {
|
||||
throw new InvalidLoginCredentialsException("Username verification failed");
|
||||
}
|
||||
} else {
|
||||
throw new InvalidLoginCredentialsException("Password verification failed");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize Provider
|
||||
*
|
||||
* @param initializationContext Initialization Context
|
||||
*/
|
||||
@Override
|
||||
public void initialize(final LoginIdentityProviderInitializationContext initializationContext) {
|
||||
LOGGER.debug("Initializing Provider");
|
||||
}
|
||||
|
||||
/**
|
||||
* Configure Provider using Username and Password properties with support for generating random values
|
||||
*
|
||||
* @param configurationContext Configuration Context containing properties
|
||||
* @throws ProviderCreationException Thrown when unable to write Login Credentials
|
||||
*/
|
||||
@Override
|
||||
public void onConfigured(final LoginIdentityProviderConfigurationContext configurationContext) throws ProviderCreationException {
|
||||
LOGGER.debug("Configuring Provider");
|
||||
final String password = configurationContext.getProperty(PASSWORD_PROPERTY);
|
||||
if (password == null || password.length() == 0) {
|
||||
try {
|
||||
configuredCredentials = generateLoginCredentials();
|
||||
LOGGER.info("Updating Login Identity Providers Configuration [{}]", loginIdentityProviderConfigurationFile);
|
||||
final LoginCredentialsWriter loginCredentialsWriter = getLoginCredentialsWriter();
|
||||
loginCredentialsWriter.writeLoginCredentials(configuredCredentials);
|
||||
} catch (final IOException e) {
|
||||
throw new ProviderCreationException("Generating Login Credentials Failed", e);
|
||||
}
|
||||
} else {
|
||||
final String username = configurationContext.getProperty(USERNAME_PROPERTY);
|
||||
configuredCredentials = new LoginCredentials(username, password);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Destroy Provider
|
||||
*/
|
||||
@Override
|
||||
public void preDestruction() {
|
||||
LOGGER.debug("Destroying Provider");
|
||||
}
|
||||
|
||||
protected String generatePassword() {
|
||||
final SecureRandom secureRandom = new SecureRandom();
|
||||
final byte[] bytes = new byte[RANDOM_BYTE_LENGTH];
|
||||
secureRandom.nextBytes(bytes);
|
||||
return RANDOM_BYTE_ENCODER.encodeToString(bytes);
|
||||
}
|
||||
|
||||
private LoginCredentialsWriter getLoginCredentialsWriter() {
|
||||
return new StandardLoginCredentialsWriter(loginIdentityProviderConfigurationFile);
|
||||
}
|
||||
|
||||
private LoginCredentials generateLoginCredentials() throws IOException {
|
||||
final String username = UUID.randomUUID().toString();
|
||||
final String password = generatePassword();
|
||||
|
||||
final String separator = System.lineSeparator();
|
||||
LOGGER.info("{}{}Generated Username [{}]{}Generated Password [{}]{}", separator, separator, username, separator, password, separator);
|
||||
|
||||
final String hashedPassword = passwordEncoder.encode(password.toCharArray());
|
||||
return new LoginCredentials(username, hashedPassword);
|
||||
}
|
||||
|
||||
private boolean isPasswordVerified(final String password) {
|
||||
return passwordEncoder.matches(password.toCharArray(), configuredCredentials.getPassword());
|
||||
}
|
||||
|
||||
private boolean isUsernameVerified(final String username) {
|
||||
return configuredCredentials.getUsername().equals(username);
|
||||
}
|
||||
}
|
@ -0,0 +1,56 @@
|
||||
/*
|
||||
* 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.single.user.encoder;
|
||||
|
||||
import at.favre.lib.crypto.bcrypt.BCrypt;
|
||||
|
||||
/**
|
||||
* Password Encoder implementation using bcrypt hashing
|
||||
*/
|
||||
public class BCryptPasswordEncoder implements PasswordEncoder {
|
||||
private static final int DEFAULT_COST = 12;
|
||||
|
||||
private static final BCrypt.Version BCRYPT_VERSION = BCrypt.Version.VERSION_2B;
|
||||
|
||||
private static final BCrypt.Hasher HASHER = BCrypt.with(BCRYPT_VERSION);
|
||||
|
||||
private static final BCrypt.Verifyer VERIFYER = BCrypt.verifyer(BCRYPT_VERSION);
|
||||
|
||||
/**
|
||||
* Encode Password and return bcrypt hashed password
|
||||
*
|
||||
* @param password Password
|
||||
* @return bcrypt hashed password
|
||||
*/
|
||||
@Override
|
||||
public String encode(final char[] password) {
|
||||
return HASHER.hashToString(DEFAULT_COST, password);
|
||||
}
|
||||
|
||||
/**
|
||||
* Match Password against bcrypt hashed password
|
||||
*
|
||||
* @param password Password to be matched
|
||||
* @param encodedPassword bcrypt hashed password
|
||||
* @return Matched status
|
||||
*/
|
||||
@Override
|
||||
public boolean matches(final char[] password, final String encodedPassword) {
|
||||
final BCrypt.Result result = VERIFYER.verifyStrict(password, encodedPassword.toCharArray());
|
||||
return result.verified;
|
||||
}
|
||||
}
|
@ -0,0 +1,39 @@
|
||||
/*
|
||||
* 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.single.user.encoder;
|
||||
|
||||
/**
|
||||
* Password Encoder for encoding and matching passwords modeled after Spring Security PasswordEncoder
|
||||
*/
|
||||
public interface PasswordEncoder {
|
||||
/**
|
||||
* Encode Password and return hashed password
|
||||
*
|
||||
* @param password Password
|
||||
* @return Encoded Password
|
||||
*/
|
||||
String encode(char[] password);
|
||||
|
||||
/**
|
||||
* Match Password against encoded password
|
||||
*
|
||||
* @param password Password to be matched
|
||||
* @param encodedPassword Encoded representation of password for matching
|
||||
* @return Matched status
|
||||
*/
|
||||
boolean matches(char[] password, String encodedPassword);
|
||||
}
|
@ -0,0 +1,31 @@
|
||||
/*
|
||||
* 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.single.user.writer;
|
||||
|
||||
import org.apache.nifi.authentication.LoginCredentials;
|
||||
|
||||
/**
|
||||
* Writer for Login Identity Providers Configuration
|
||||
*/
|
||||
public interface LoginCredentialsWriter {
|
||||
/**
|
||||
* Write Login Credentials
|
||||
*
|
||||
* @param loginCredentials Login Credentials
|
||||
*/
|
||||
void writeLoginCredentials(LoginCredentials loginCredentials);
|
||||
}
|
@ -0,0 +1,210 @@
|
||||
/*
|
||||
* 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.single.user.writer;
|
||||
|
||||
import org.apache.nifi.authentication.LoginCredentials;
|
||||
import org.apache.nifi.authentication.single.user.SingleUserLoginIdentityProvider;
|
||||
|
||||
import javax.xml.stream.XMLEventFactory;
|
||||
import javax.xml.stream.XMLEventReader;
|
||||
import javax.xml.stream.XMLEventWriter;
|
||||
import javax.xml.stream.XMLInputFactory;
|
||||
import javax.xml.stream.XMLOutputFactory;
|
||||
import javax.xml.stream.XMLStreamException;
|
||||
import javax.xml.stream.events.Attribute;
|
||||
import javax.xml.stream.events.Characters;
|
||||
import javax.xml.stream.events.EndElement;
|
||||
import javax.xml.stream.events.StartElement;
|
||||
import javax.xml.stream.events.XMLEvent;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.io.UncheckedIOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.StandardCopyOption;
|
||||
import java.util.Iterator;
|
||||
|
||||
/**
|
||||
* Standard Login Credentials Writer updates Login Identity Providers Single User definition with Login Credentials
|
||||
*/
|
||||
public class StandardLoginCredentialsWriter implements LoginCredentialsWriter {
|
||||
|
||||
private static final String PROVIDERS_PREFIX = "login-identity-providers-";
|
||||
|
||||
private static final String PROVIDERS_SUFFIX = ".xml";
|
||||
|
||||
private static final String CLASS_TAG = "class";
|
||||
|
||||
private static final String PROVIDER_TAG = "provider";
|
||||
|
||||
private static final String PROPERTY_TAG = "property";
|
||||
|
||||
private static final String NAME_ATTRIBUTE = "name";
|
||||
|
||||
private static final String USERNAME_PROPERTY = "Username";
|
||||
|
||||
private static final String PASSWORD_PROPERTY = "Password";
|
||||
|
||||
private final XMLEventFactory eventFactory = XMLEventFactory.newFactory();
|
||||
|
||||
private final File providersFile;
|
||||
|
||||
public StandardLoginCredentialsWriter(final File providersFile) {
|
||||
this.providersFile = providersFile;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeLoginCredentials(final LoginCredentials loginCredentials) {
|
||||
try {
|
||||
final File updatedProvidersFile = File.createTempFile(PROVIDERS_PREFIX, PROVIDERS_SUFFIX);
|
||||
writeLoginCredentials(loginCredentials, updatedProvidersFile);
|
||||
Files.move(updatedProvidersFile.toPath(), providersFile.toPath(), StandardCopyOption.REPLACE_EXISTING);
|
||||
} catch (final IOException e) {
|
||||
throw new UncheckedIOException("Writing Login Identity Providers Failed", e);
|
||||
} catch (final XMLStreamException e) {
|
||||
throw new RuntimeException("Processing Login Identity Providers Failed", e);
|
||||
}
|
||||
}
|
||||
|
||||
private void writeLoginCredentials(final LoginCredentials loginCredentials, final File updatedProvidersFile) throws IOException, XMLStreamException {
|
||||
try (final OutputStream outputStream = new FileOutputStream(updatedProvidersFile)) {
|
||||
final XMLEventWriter providersWriter = getProvidersWriter(outputStream);
|
||||
try (final InputStream inputStream = new FileInputStream(providersFile)) {
|
||||
final XMLEventReader providersReader = getProvidersReader(inputStream);
|
||||
updateLoginIdentityProviders(loginCredentials, providersReader, providersWriter);
|
||||
providersReader.close();
|
||||
}
|
||||
providersWriter.close();
|
||||
}
|
||||
}
|
||||
|
||||
private void updateLoginIdentityProviders(final LoginCredentials credentials,
|
||||
final XMLEventReader providersReader,
|
||||
final XMLEventWriter providersWriter) throws XMLStreamException {
|
||||
boolean processingSingleUserProvider = false;
|
||||
|
||||
while (providersReader.hasNext()) {
|
||||
final XMLEvent event = providersReader.nextEvent();
|
||||
providersWriter.add(event);
|
||||
|
||||
if (isStartClass(event)) {
|
||||
final XMLEvent nextEvent = providersReader.nextEvent();
|
||||
providersWriter.add(nextEvent);
|
||||
if (nextEvent.isCharacters()) {
|
||||
final String providerClass = nextEvent.asCharacters().getData();
|
||||
if (SingleUserLoginIdentityProvider.class.getName().equals(providerClass)) {
|
||||
processingSingleUserProvider = true;
|
||||
}
|
||||
}
|
||||
} else if (isEndProvider(event)) {
|
||||
processingSingleUserProvider = false;
|
||||
}
|
||||
|
||||
if (processingSingleUserProvider) {
|
||||
if (isStartProperty(event, USERNAME_PROPERTY)) {
|
||||
processProperty(providersReader, providersWriter, credentials.getUsername());
|
||||
} else if (isStartProperty(event, PASSWORD_PROPERTY)) {
|
||||
processProperty(providersReader, providersWriter, credentials.getPassword());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Process Property Value and replace existing Characters when found
|
||||
*
|
||||
* @param providersReader Providers Reader
|
||||
* @param providersWriter Providers Writer
|
||||
* @param propertyValue Property Value to be added
|
||||
* @throws XMLStreamException Thrown on XMLEventReader.nextEvent()
|
||||
*/
|
||||
private void processProperty(final XMLEventReader providersReader, final XMLEventWriter providersWriter, final String propertyValue) throws XMLStreamException {
|
||||
final XMLEvent nextEvent = providersReader.nextEvent();
|
||||
|
||||
final Characters propertyCharacters = eventFactory.createCharacters(propertyValue);
|
||||
providersWriter.add(propertyCharacters);
|
||||
|
||||
if (nextEvent.isEndElement()) {
|
||||
providersWriter.add(nextEvent);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isStartClass(final XMLEvent event) {
|
||||
boolean found = false;
|
||||
|
||||
if (event.isStartElement()) {
|
||||
final StartElement startElement = event.asStartElement();
|
||||
found = CLASS_TAG.equals(startElement.getName().getLocalPart());
|
||||
}
|
||||
|
||||
return found;
|
||||
}
|
||||
|
||||
private boolean isStartProperty(final XMLEvent event, final String propertyName) {
|
||||
boolean found = false;
|
||||
|
||||
if (event.isStartElement()) {
|
||||
final StartElement startElement = event.asStartElement();
|
||||
found = PROPERTY_TAG.equals(startElement.getName().getLocalPart()) && isProperty(startElement, propertyName);
|
||||
}
|
||||
|
||||
return found;
|
||||
}
|
||||
|
||||
private boolean isProperty(final StartElement startElement, final String propertyName) {
|
||||
boolean found = false;
|
||||
|
||||
final Iterator<Attribute> attributes = startElement.getAttributes();
|
||||
while (attributes.hasNext()) {
|
||||
final Attribute attribute = attributes.next();
|
||||
if (NAME_ATTRIBUTE.equals(attribute.getName().getLocalPart())) {
|
||||
if (propertyName.equals(attribute.getValue())) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return found;
|
||||
}
|
||||
|
||||
private boolean isEndProvider(final XMLEvent event) {
|
||||
boolean found = false;
|
||||
|
||||
if (event.isEndElement()) {
|
||||
final EndElement endElement = event.asEndElement();
|
||||
found = PROVIDER_TAG.equals(endElement.getName().getLocalPart());
|
||||
}
|
||||
|
||||
return found;
|
||||
}
|
||||
|
||||
private XMLEventWriter getProvidersWriter(final OutputStream outputStream) throws XMLStreamException {
|
||||
final XMLOutputFactory outputFactory = XMLOutputFactory.newInstance();
|
||||
return outputFactory.createXMLEventWriter(outputStream);
|
||||
}
|
||||
|
||||
private XMLEventReader getProvidersReader(final InputStream inputStream) throws XMLStreamException {
|
||||
final XMLInputFactory inputFactory = XMLInputFactory.newFactory();
|
||||
inputFactory.setProperty(XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES, false);
|
||||
inputFactory.setProperty(XMLInputFactory.SUPPORT_DTD, false);
|
||||
return inputFactory.createXMLEventReader(inputStream);
|
||||
}
|
||||
}
|
@ -0,0 +1,144 @@
|
||||
/*
|
||||
* 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.authorization.single.user;
|
||||
|
||||
import org.apache.nifi.authentication.single.user.SingleUserLoginIdentityProvider;
|
||||
import org.apache.nifi.authorization.AuthorizationRequest;
|
||||
import org.apache.nifi.authorization.AuthorizationResult;
|
||||
import org.apache.nifi.authorization.Authorizer;
|
||||
import org.apache.nifi.authorization.AuthorizerConfigurationContext;
|
||||
import org.apache.nifi.authorization.AuthorizerInitializationContext;
|
||||
import org.apache.nifi.authorization.annotation.AuthorizerContext;
|
||||
import org.apache.nifi.authorization.exception.AuthorizationAccessException;
|
||||
import org.apache.nifi.authorization.exception.AuthorizerCreationException;
|
||||
import org.apache.nifi.util.NiFiProperties;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import javax.xml.stream.XMLEventReader;
|
||||
import javax.xml.stream.XMLInputFactory;
|
||||
import javax.xml.stream.XMLStreamException;
|
||||
import javax.xml.stream.events.StartElement;
|
||||
import javax.xml.stream.events.XMLEvent;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
/**
|
||||
* Single User Authorizer requires Single User Login Identity Provider to be configured and authorizes all requests
|
||||
*/
|
||||
public class SingleUserAuthorizer implements Authorizer {
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(SingleUserAuthorizer.class);
|
||||
|
||||
private static final String REQUIRED_PROVIDER = SingleUserLoginIdentityProvider.class.getName();
|
||||
|
||||
private static final String IDENTIFIER_TAG = "identifier";
|
||||
|
||||
private static final String CLASS_TAG = "class";
|
||||
|
||||
private static final String BLANK_PROVIDER = "provider";
|
||||
|
||||
/**
|
||||
* Set NiFi Properties using method injection
|
||||
*
|
||||
* @param niFiProperties NiFi Properties
|
||||
*/
|
||||
@AuthorizerContext
|
||||
public void setProperties(final NiFiProperties niFiProperties) {
|
||||
final File configuration = niFiProperties.getLoginIdentityProviderConfigurationFile();
|
||||
final String identifier = niFiProperties.getProperty(NiFiProperties.SECURITY_USER_LOGIN_IDENTITY_PROVIDER, BLANK_PROVIDER);
|
||||
if (isSingleUserLoginIdentityProviderConfigured(identifier, configuration)) {
|
||||
LOGGER.debug("Required Login Identity Provider Configured [{}]", REQUIRED_PROVIDER);
|
||||
} else {
|
||||
final String message = String.format("%s requires %s to be configured", getClass().getSimpleName(), REQUIRED_PROVIDER);
|
||||
throw new AuthorizerCreationException(message);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public AuthorizationResult authorize(final AuthorizationRequest request) throws AuthorizationAccessException {
|
||||
return AuthorizationResult.approved();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize(final AuthorizerInitializationContext initializationContext) {
|
||||
LOGGER.info("Initializing Authorizer");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onConfigured(final AuthorizerConfigurationContext configurationContext) {
|
||||
LOGGER.info("Configuring Authorizer");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void preDestruction() {
|
||||
LOGGER.info("Destroying Authorizer");
|
||||
}
|
||||
|
||||
private boolean isSingleUserLoginIdentityProviderConfigured(final String configuredIdentifier, final File configuration) {
|
||||
try (final InputStream inputStream = new FileInputStream(configuration)) {
|
||||
final XMLEventReader reader = getProvidersReader(inputStream);
|
||||
final boolean configured = isSingleUserLoginIdentityProviderConfigured(configuredIdentifier, reader);
|
||||
reader.close();
|
||||
return configured;
|
||||
} catch (final XMLStreamException | IOException e) {
|
||||
throw new AuthorizerCreationException("Failed to read Login Identity Providers Configuration", e);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isSingleUserLoginIdentityProviderConfigured(final String configuredIdentifier, final XMLEventReader reader) throws XMLStreamException {
|
||||
boolean providerConfigured = false;
|
||||
|
||||
boolean identifierFound = false;
|
||||
while (reader.hasNext()) {
|
||||
final XMLEvent event = reader.nextEvent();
|
||||
if (isStartElement(event, IDENTIFIER_TAG)) {
|
||||
final String providerIdentifier = reader.getElementText().trim();
|
||||
identifierFound = configuredIdentifier.equals(providerIdentifier);
|
||||
}
|
||||
|
||||
if (identifierFound) {
|
||||
// Compare class after finding configured provider identifier
|
||||
if (isStartElement(event, CLASS_TAG)) {
|
||||
final String providerClass = reader.getElementText().trim();
|
||||
providerConfigured = REQUIRED_PROVIDER.equals(providerClass);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return providerConfigured;
|
||||
}
|
||||
|
||||
private boolean isStartElement(final XMLEvent event, final String localElementName) {
|
||||
boolean found = false;
|
||||
|
||||
if (event.isStartElement()) {
|
||||
final StartElement startElement = event.asStartElement();
|
||||
found = localElementName.equals(startElement.getName().getLocalPart());
|
||||
}
|
||||
|
||||
return found;
|
||||
}
|
||||
|
||||
private XMLEventReader getProvidersReader(final InputStream inputStream) throws XMLStreamException {
|
||||
final XMLInputFactory inputFactory = XMLInputFactory.newFactory();
|
||||
inputFactory.setProperty(XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES, false);
|
||||
inputFactory.setProperty(XMLInputFactory.SUPPORT_DTD, false);
|
||||
return inputFactory.createXMLEventReader(inputStream);
|
||||
}
|
||||
}
|
@ -0,0 +1,15 @@
|
||||
# Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
# contributor license agreements. See the NOTICE file distributed with
|
||||
# this work for additional information regarding copyright ownership.
|
||||
# The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
# (the "License"); you may not use this file except in compliance with
|
||||
# the License. You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
org.apache.nifi.authentication.single.user.SingleUserLoginIdentityProvider
|
@ -0,0 +1,15 @@
|
||||
# Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
# contributor license agreements. See the NOTICE file distributed with
|
||||
# this work for additional information regarding copyright ownership.
|
||||
# The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
# (the "License"); you may not use this file except in compliance with
|
||||
# the License. You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
org.apache.nifi.authorization.single.user.SingleUserAuthorizer
|
@ -0,0 +1,173 @@
|
||||
/*
|
||||
* 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.single.user;
|
||||
|
||||
import org.apache.nifi.authentication.AuthenticationResponse;
|
||||
import org.apache.nifi.authentication.LoginCredentials;
|
||||
import org.apache.nifi.authentication.LoginIdentityProviderConfigurationContext;
|
||||
import org.apache.nifi.authentication.exception.InvalidLoginCredentialsException;
|
||||
import org.apache.nifi.authentication.single.user.encoder.PasswordEncoder;
|
||||
import org.apache.nifi.util.NiFiProperties;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URISyntaxException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.nio.file.StandardCopyOption;
|
||||
import java.util.Properties;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertThrows;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.mockito.Mockito.when;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class SingleUserLoginIdentityProviderTest {
|
||||
private static final String BLANK_PROVIDERS = "/conf/login-identity-providers.xml";
|
||||
|
||||
private static final String XML_SUFFIX = ".xml";
|
||||
|
||||
private static final String EMPTY_PROPERTIES_PATH = "";
|
||||
|
||||
private static final Pattern USERNAME_PATTERN = Pattern.compile("Username\">([^<]+)<");
|
||||
|
||||
private static final Pattern PASSWORD_PATTERN = Pattern.compile("Password\">([^<]+)<");
|
||||
|
||||
private static final int FIRST_GROUP = 1;
|
||||
|
||||
@Mock
|
||||
private LoginIdentityProviderConfigurationContext configurationContext;
|
||||
|
||||
private StringPasswordEncoder encoder;
|
||||
|
||||
private SingleUserLoginIdentityProvider provider;
|
||||
|
||||
@Before
|
||||
public void setProvider() {
|
||||
provider = new SingleUserLoginIdentityProvider();
|
||||
encoder = new StringPasswordEncoder();
|
||||
provider.passwordEncoder = encoder;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOnConfiguredGeneratePasswordAuthenticateSuccess() throws IOException, URISyntaxException {
|
||||
final Path configuredProvidersPath = Files.createTempFile(getClass().getSimpleName(), XML_SUFFIX);
|
||||
configuredProvidersPath.toFile().deleteOnExit();
|
||||
|
||||
final Path blankProvidersPath = Paths.get(getClass().getResource(BLANK_PROVIDERS).toURI());
|
||||
Files.copy(blankProvidersPath, configuredProvidersPath, StandardCopyOption.REPLACE_EXISTING);
|
||||
|
||||
final Properties properties = new Properties();
|
||||
properties.put(NiFiProperties.LOGIN_IDENTITY_PROVIDER_CONFIGURATION_FILE, configuredProvidersPath.toString());
|
||||
|
||||
final NiFiProperties niFiProperties = NiFiProperties.createBasicNiFiProperties(EMPTY_PROPERTIES_PATH, properties);
|
||||
provider.setProperties(niFiProperties);
|
||||
provider.onConfigured(configurationContext);
|
||||
|
||||
final String providersConfiguration = new String(Files.readAllBytes(configuredProvidersPath));
|
||||
|
||||
final Matcher usernameMatcher = USERNAME_PATTERN.matcher(providersConfiguration);
|
||||
assertTrue("Username not found", usernameMatcher.find());
|
||||
final String username = usernameMatcher.group(FIRST_GROUP);
|
||||
|
||||
final Matcher passwordMatcher = PASSWORD_PATTERN.matcher(providersConfiguration);
|
||||
assertTrue("Password not found", passwordMatcher.find());
|
||||
|
||||
final LoginCredentials loginCredentials = new LoginCredentials(username, encoder.encoded);
|
||||
final AuthenticationResponse response = provider.authenticate(loginCredentials);
|
||||
assertEquals(username, response.getUsername());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOnConfiguredAuthenticateInvalidPassword() throws URISyntaxException {
|
||||
final Path blankProvidersPath = Paths.get(getClass().getResource(BLANK_PROVIDERS).toURI());
|
||||
final Properties properties = new Properties();
|
||||
properties.put(NiFiProperties.LOGIN_IDENTITY_PROVIDER_CONFIGURATION_FILE, blankProvidersPath.toString());
|
||||
final NiFiProperties niFiProperties = NiFiProperties.createBasicNiFiProperties(EMPTY_PROPERTIES_PATH, properties);
|
||||
provider.setProperties(niFiProperties);
|
||||
|
||||
final String username = String.class.getSimpleName();
|
||||
when(configurationContext.getProperty(eq(SingleUserLoginIdentityProvider.USERNAME_PROPERTY))).thenReturn(username);
|
||||
when(configurationContext.getProperty(eq(SingleUserLoginIdentityProvider.PASSWORD_PROPERTY))).thenReturn(String.class.getName());
|
||||
provider.onConfigured(configurationContext);
|
||||
|
||||
final LoginCredentials loginCredentials = new LoginCredentials(username, LoginCredentials.class.getName());
|
||||
assertThrows(InvalidLoginCredentialsException.class, () -> provider.authenticate(loginCredentials));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOnConfiguredAuthenticateInvalidUsername() throws URISyntaxException {
|
||||
final Path blankProvidersPath = Paths.get(getClass().getResource(BLANK_PROVIDERS).toURI());
|
||||
final Properties properties = new Properties();
|
||||
properties.put(NiFiProperties.LOGIN_IDENTITY_PROVIDER_CONFIGURATION_FILE, blankProvidersPath.toString());
|
||||
final NiFiProperties niFiProperties = NiFiProperties.createBasicNiFiProperties(EMPTY_PROPERTIES_PATH, properties);
|
||||
provider.setProperties(niFiProperties);
|
||||
|
||||
final String username = String.class.getSimpleName();
|
||||
final String password = String.class.getName();
|
||||
when(configurationContext.getProperty(eq(SingleUserLoginIdentityProvider.USERNAME_PROPERTY))).thenReturn(username);
|
||||
when(configurationContext.getProperty(eq(SingleUserLoginIdentityProvider.PASSWORD_PROPERTY))).thenReturn(password);
|
||||
provider.onConfigured(configurationContext);
|
||||
|
||||
final LoginCredentials loginCredentials = new LoginCredentials(LoginCredentials.class.getName(), password);
|
||||
assertThrows(InvalidLoginCredentialsException.class, () -> provider.authenticate(loginCredentials));
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOnConfiguredAuthenticateSuccess() throws URISyntaxException {
|
||||
final Path blankProvidersPath = Paths.get(getClass().getResource(BLANK_PROVIDERS).toURI());
|
||||
final Properties properties = new Properties();
|
||||
properties.put(NiFiProperties.LOGIN_IDENTITY_PROVIDER_CONFIGURATION_FILE, blankProvidersPath.toString());
|
||||
final NiFiProperties niFiProperties = NiFiProperties.createBasicNiFiProperties(EMPTY_PROPERTIES_PATH, properties);
|
||||
provider.setProperties(niFiProperties);
|
||||
|
||||
final String username = String.class.getSimpleName();
|
||||
final String password = String.class.getName();
|
||||
when(configurationContext.getProperty(eq(SingleUserLoginIdentityProvider.USERNAME_PROPERTY))).thenReturn(username);
|
||||
when(configurationContext.getProperty(eq(SingleUserLoginIdentityProvider.PASSWORD_PROPERTY))).thenReturn(password);
|
||||
provider.onConfigured(configurationContext);
|
||||
|
||||
final LoginCredentials loginCredentials = new LoginCredentials(username, password);
|
||||
final AuthenticationResponse response = provider.authenticate(loginCredentials);
|
||||
assertEquals(username, response.getUsername());
|
||||
}
|
||||
|
||||
private static class StringPasswordEncoder implements PasswordEncoder {
|
||||
private String encoded;
|
||||
|
||||
@Override
|
||||
public String encode(final char[] password) {
|
||||
encoded = new String(password);
|
||||
return encoded;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean matches(final char[] password, final String encodedPassword) {
|
||||
return encodedPassword.equals(new String(password));
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,45 @@
|
||||
/*
|
||||
* 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.single.user.encoder;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
public class BCryptPasswordEncoderTest {
|
||||
|
||||
private static final Pattern BCRYPT_PATTERN = Pattern.compile("^\\$2b\\$12\\$.+$");
|
||||
|
||||
@Test
|
||||
public void testEncode() {
|
||||
final BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
|
||||
final String encoded = encoder.encode(String.class.getSimpleName().toCharArray());
|
||||
assertNotNull("Encoded Password not found", encoded);
|
||||
assertTrue("Encoded Password bcrypt hash not found", BCRYPT_PATTERN.matcher(encoded).matches());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEncodeMatches() {
|
||||
final BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
|
||||
final char[] password = String.class.getSimpleName().toCharArray();
|
||||
final String encoded = encoder.encode(password);
|
||||
assertTrue("Encoded Password not matched", encoder.matches(password, encoded));
|
||||
}
|
||||
}
|
@ -0,0 +1,68 @@
|
||||
/*
|
||||
* 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.single.user.writer;
|
||||
|
||||
import org.apache.nifi.authentication.LoginCredentials;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URISyntaxException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.nio.file.StandardCopyOption;
|
||||
import java.util.UUID;
|
||||
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
public class StandardLoginCredentialsWriterTest {
|
||||
private static final String BLANK_PROVIDERS = "/conf/login-identity-providers.xml";
|
||||
|
||||
private static final String POPULATED_PROVIDERS = "/conf/populated-login-identity-providers.xml";
|
||||
|
||||
private static final String XML_SUFFIX = ".xml";
|
||||
|
||||
@Test
|
||||
public void testWriteLoginCredentialsBlankProviders() throws IOException, URISyntaxException {
|
||||
final Path sourceProvidersPath = Paths.get(getClass().getResource(BLANK_PROVIDERS).toURI());
|
||||
assertCredentialsFound(sourceProvidersPath);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWriteLoginCredentialsPopulatedProviders() throws IOException, URISyntaxException {
|
||||
final Path sourceProvidersPath = Paths.get(getClass().getResource(POPULATED_PROVIDERS).toURI());
|
||||
assertCredentialsFound(sourceProvidersPath);
|
||||
}
|
||||
|
||||
private void assertCredentialsFound(final Path sourceProvidersPath) throws IOException {
|
||||
final Path configuredProvidersPath = Files.createTempFile(getClass().getSimpleName(), XML_SUFFIX);
|
||||
configuredProvidersPath.toFile().deleteOnExit();
|
||||
|
||||
Files.copy(sourceProvidersPath, configuredProvidersPath, StandardCopyOption.REPLACE_EXISTING);
|
||||
|
||||
final StandardLoginCredentialsWriter writer = new StandardLoginCredentialsWriter(configuredProvidersPath.toFile());
|
||||
|
||||
final String username = UUID.randomUUID().toString();
|
||||
final String password = UUID.randomUUID().toString();
|
||||
final LoginCredentials credentials = new LoginCredentials(username, password);
|
||||
writer.writeLoginCredentials(credentials);
|
||||
|
||||
final String configuration = new String(Files.readAllBytes(configuredProvidersPath));
|
||||
assertTrue("Username not found", configuration.contains(username));
|
||||
assertTrue("Password not found", configuration.contains(password));
|
||||
}
|
||||
}
|
@ -0,0 +1,77 @@
|
||||
/*
|
||||
* 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.authorization.single.user;
|
||||
|
||||
import org.apache.nifi.authorization.exception.AuthorizerCreationException;
|
||||
import org.apache.nifi.util.NiFiProperties;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.net.URISyntaxException;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.Properties;
|
||||
|
||||
import static org.junit.Assert.assertThrows;
|
||||
|
||||
public class SingleUserAuthorizerTest {
|
||||
private static final String BLANK_PROVIDERS = "/conf/login-identity-providers.xml";
|
||||
|
||||
private static final String UNSUPPORTED_PROVIDERS = "/conf/unsupported-login-identity-providers.xml";
|
||||
|
||||
private static final String PROVIDER_IDENTIFIER = "single-user-provider";
|
||||
|
||||
private static final String UNSUPPORTED_PROVIDER_IDENTIFIER = "unsupported-provider";
|
||||
|
||||
private static final String EMPTY_PROPERTIES_PATH = "";
|
||||
|
||||
private SingleUserAuthorizer authorizer;
|
||||
|
||||
@Before
|
||||
public void setAuthorizer() {
|
||||
authorizer = new SingleUserAuthorizer();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSetPropertiesSingleUserIdentityProviderConfigured() throws URISyntaxException {
|
||||
final Path providersPath = Paths.get(getClass().getResource(BLANK_PROVIDERS).toURI());
|
||||
final Properties properties = new Properties();
|
||||
properties.put(NiFiProperties.LOGIN_IDENTITY_PROVIDER_CONFIGURATION_FILE, providersPath.toString());
|
||||
properties.put(NiFiProperties.SECURITY_USER_LOGIN_IDENTITY_PROVIDER, PROVIDER_IDENTIFIER);
|
||||
final NiFiProperties niFiProperties = NiFiProperties.createBasicNiFiProperties(EMPTY_PROPERTIES_PATH, properties);
|
||||
authorizer.setProperties(niFiProperties);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSetPropertiesSingleUserIdentityProviderNotSpecified() throws URISyntaxException {
|
||||
final Path providersPath = Paths.get(getClass().getResource(BLANK_PROVIDERS).toURI());
|
||||
final Properties properties = new Properties();
|
||||
properties.put(NiFiProperties.LOGIN_IDENTITY_PROVIDER_CONFIGURATION_FILE, providersPath.toString());
|
||||
final NiFiProperties niFiProperties = NiFiProperties.createBasicNiFiProperties(EMPTY_PROPERTIES_PATH, properties);
|
||||
assertThrows(AuthorizerCreationException.class, () -> authorizer.setProperties(niFiProperties));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSetPropertiesAuthorizerCreationException() throws URISyntaxException {
|
||||
final Path providersPath = Paths.get(getClass().getResource(UNSUPPORTED_PROVIDERS).toURI());
|
||||
final Properties properties = new Properties();
|
||||
properties.put(NiFiProperties.LOGIN_IDENTITY_PROVIDER_CONFIGURATION_FILE, providersPath.toString());
|
||||
properties.put(NiFiProperties.SECURITY_USER_LOGIN_IDENTITY_PROVIDER, UNSUPPORTED_PROVIDER_IDENTIFIER);
|
||||
final NiFiProperties niFiProperties = NiFiProperties.createBasicNiFiProperties(EMPTY_PROPERTIES_PATH, properties);
|
||||
assertThrows(AuthorizerCreationException.class, () -> authorizer.setProperties(niFiProperties));
|
||||
}
|
||||
}
|
@ -0,0 +1,24 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<!--
|
||||
Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
contributor license agreements. See the NOTICE file distributed with
|
||||
this work for additional information regarding copyright ownership.
|
||||
The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
(the "License"); you may not use this file except in compliance with
|
||||
the License. You may obtain a copy of the License at
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<loginIdentityProviders>
|
||||
<!-- Default Single User Provider -->
|
||||
<provider>
|
||||
<identifier>single-user-provider</identifier>
|
||||
<class>org.apache.nifi.authentication.single.user.SingleUserLoginIdentityProvider</class>
|
||||
<property name="Username" />
|
||||
<property name="Password" />
|
||||
</provider>
|
||||
</loginIdentityProviders>
|
@ -0,0 +1,24 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<!--
|
||||
Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
contributor license agreements. See the NOTICE file distributed with
|
||||
this work for additional information regarding copyright ownership.
|
||||
The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
(the "License"); you may not use this file except in compliance with
|
||||
the License. You may obtain a copy of the License at
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<loginIdentityProviders>
|
||||
<!-- Default Single User Provider -->
|
||||
<provider>
|
||||
<identifier>single-user-provider</identifier>
|
||||
<class>org.apache.nifi.authentication.single.user.SingleUserLoginIdentityProvider</class>
|
||||
<property name="Username">USERNAME</property>
|
||||
<property name="Password">PASSWORD</property>
|
||||
</provider>
|
||||
</loginIdentityProviders>
|
@ -0,0 +1,21 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<!--
|
||||
Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
contributor license agreements. See the NOTICE file distributed with
|
||||
this work for additional information regarding copyright ownership.
|
||||
The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
(the "License"); you may not use this file except in compliance with
|
||||
the License. You may obtain a copy of the License at
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<loginIdentityProviders>
|
||||
<provider>
|
||||
<identifier>unsupported-provider</identifier>
|
||||
<class>org.apache.nifi.authentication.LoginIdentityProvider</class>
|
||||
</provider>
|
||||
</loginIdentityProviders>
|
@ -0,0 +1,38 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
contributor license agreements. See the NOTICE file distributed with
|
||||
this work for additional information regarding copyright ownership.
|
||||
The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
(the "License"); you may not use this file except in compliance with
|
||||
the License. You may obtain a copy of the License at
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>org.apache.nifi</groupId>
|
||||
<artifactId>nifi-nar-bundles</artifactId>
|
||||
<version>1.14.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
<artifactId>nifi-single-user-iaa-providers-bundle</artifactId>
|
||||
<packaging>pom</packaging>
|
||||
<modules>
|
||||
<module>nifi-single-user-iaa-providers</module>
|
||||
<module>nifi-single-user-iaa-providers-nar</module>
|
||||
</modules>
|
||||
<dependencyManagement>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.apache.nifi</groupId>
|
||||
<artifactId>nifi-single-user-iaa-providers</artifactId>
|
||||
<version>1.14.0-SNAPSHOT</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</dependencyManagement>
|
||||
</project>
|
@ -53,6 +53,7 @@
|
||||
<module>nifi-azure-bundle</module>
|
||||
<module>nifi-ldap-iaa-providers-bundle</module>
|
||||
<module>nifi-kerberos-iaa-providers-bundle</module>
|
||||
<module>nifi-single-user-iaa-providers-bundle</module>
|
||||
<module>nifi-riemann-bundle</module>
|
||||
<module>nifi-html-bundle</module>
|
||||
<module>nifi-scripting-bundle</module>
|
||||
|
Loading…
x
Reference in New Issue
Block a user