Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

NIFI-9849 Refactor SAML Support with Spring Security 5 #6145

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,22 @@

import org.apache.commons.lang3.StringUtils;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

/**
* Request URI Builder encapsulates URI construction handling supported HTTP proxy request headers
*/
public class RequestUriBuilder {
private static final String ALLOWED_CONTEXT_PATHS_PARAMETER = "allowedContextPaths";

private static final String COMMA_SEPARATOR = ",";

private final String scheme;

private final String host;
Expand All @@ -44,6 +51,17 @@ private RequestUriBuilder(final String scheme, final String host, final int port
this.contextPath = contextPath;
}

/**
* Return Builder from HTTP Servlet Request using Scheme, Host, Port, and Context Path reading from headers
*
* @param httpServletRequest HTTP Servlet Request
* @return Request URI Builder
*/
public static RequestUriBuilder fromHttpServletRequest(final HttpServletRequest httpServletRequest) {
final List<String> allowedContextPaths = getAllowedContextPathsConfigured(httpServletRequest);
return fromHttpServletRequest(httpServletRequest, allowedContextPaths);
}

/**
* Return Builder from HTTP Servlet Request using Scheme, Host, Port, and Context Path reading from headers
*
Expand Down Expand Up @@ -85,4 +103,11 @@ public URI build() {
throw new IllegalArgumentException("Build URI Failed", e);
}
}

private static List<String> getAllowedContextPathsConfigured(final HttpServletRequest httpServletRequest) {
final ServletContext servletContext = httpServletRequest.getServletContext();
final String allowedContextPathsParameter = servletContext.getInitParameter(ALLOWED_CONTEXT_PATHS_PARAMETER);
final String[] allowedContextPathsParsed = StringUtils.split(allowedContextPathsParameter, COMMA_SEPARATOR);
return allowedContextPathsParsed == null ? Collections.emptyList() : Arrays.asList(allowedContextPathsParsed);
}
}
22 changes: 18 additions & 4 deletions nifi-docs/src/main/asciidoc/administration-guide.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -468,26 +468,40 @@ JSON Web Key (JWK) provided through the jwks_uri in the metadata found at the di

To enable authentication via SAML the following properties must be configured in _nifi.properties_.

Configuring a Metadata URL and an Entity Identifier enables Apache NiFi to act as a SAML 2.0 Relying Party, allowing users
to authenticate using an account managed through a SAML 2.0 Asserting Party.

[options="header"]
|==================================================================================================================================================
| Property Name | Description
|`nifi.security.user.saml.idp.metadata.url` | The URL for obtaining the identity provider's metadata. The metadata can be retrieved from the identity provider via `http://` or `https://`, or a local file can be referenced using `file://` .
|`nifi.security.user.saml.sp.entity.id`| The entity id of the service provider (i.e. NiFi). This value will be used as the `Issuer` for SAML authentication requests and should be a valid URI. In some cases the service provider entity id must be registered ahead of time with the identity provider.
|`nifi.security.user.saml.identity.attribute.name`| The name of a SAML assertion attribute containing the user'sidentity. This property is optional and if not specified, or if the attribute is not found, then the NameID of the Subject will be used.
|`nifi.security.user.saml.group.attribute.name`| The name of a SAML assertion attribute containing group names the user belongs to. This property is optional, but if populated the groups will be passed along to the authorization process.
|`nifi.security.user.saml.metadata.signing.enabled`| Enables signing of the generated service provider metadata. The default value is `false`.
|`nifi.security.user.saml.request.signing.enabled`| Controls the value of `AuthnRequestsSigned` in the generated service provider metadata from `nifi-api/access/saml/metadata`. This indicates that the service provider (i.e. NiFi) should not sign authentication requests sent to the identity provider, but the requests may still need to be signed if the identity provider indicates `WantAuthnRequestSigned=true`. The default value is `false`.
|`nifi.security.user.saml.want.assertions.signed`| Controls the value of `WantAssertionsSigned` in the generated service provider metadata from `nifi-api/access/saml/metadata`. This indicates that the identity provider should sign assertions, but some identity providers may provide their own configuration for controlling whether assertions are signed. The default value is `true`.
|`nifi.security.user.saml.signature.algorithm`| The algorithm to use when signing SAML messages. Reference the link:https://git.shibboleth.net/view/?p=java-xmltooling.git;a=blob;f=src/main/java/org/opensaml/xml/signature/SignatureConstants.java[Open SAML Signature Constants] for a list of valid values. If not specified, a default of SHA-256 will be used. The default value is `http://www.w3.org/2001/04/xmldsig-more#rsa-sha256`.
|`nifi.security.user.saml.signature.digest.algorithm`| The digest algorithm to use when signing SAML messages. Reference the link:https://git.shibboleth.net/view/?p=java-xmltooling.git;a=blob;f=src/main/java/org/opensaml/xml/signature/SignatureConstants.java[Open SAML Signature Constants] for a list of valid values. If not specified, a default of SHA-256 will be used. The default value is `http://www.w3.org/2001/04/xmlenc#sha256`.
|`nifi.security.user.saml.message.logging.enabled`| Enables logging of SAML messages for debugging purposes. The default value is `false`.
|`nifi.security.user.saml.authentication.expiration`| The expiration of the NiFi JWT that will be produced from a successful SAML authentication response. The default value is `12 hours`.
|`nifi.security.user.saml.single.logout.enabled`| Enables SAML SingleLogout which causes a logout from NiFi to logout of the identity provider. By default, a logout of NiFi will only remove the NiFi JWT. The default value is `false`.
|`nifi.security.user.saml.http.client.truststore.strategy`| The truststore strategy when the IDP metadata URL begins with https. A value of `JDK` indicates to use the JDK's default truststore. A value of`NIFI`indicates to use the truststore specified by `nifi.security.truststore`.
|`nifi.security.user.saml.http.client.truststore.strategy`| The truststore strategy when the IDP metadata URL begins with https. A value of `JDK` indicates to use the JDK's default truststore. A value of `NIFI` indicates to use the truststore specified by `nifi.security.truststore`.
|`nifi.security.user.saml.http.client.connect.timeout`| The connection timeout when communicating with the SAML IDP. The default value is `30 secs`.
|`nifi.security.user.saml.http.client.read.timeout`| The read timeout when communicating with the SAML IDP. The default value is `30 secs`.
|==================================================================================================================================================

==== SAML REST Resources

SAML authentication enables the following REST API resources for integration with a SAML 2.0 Asserting Party:

[options="header"]
|======================================
| Resource Path | Description
| /nifi-api/access/saml/local-logout/request | Complete SAML 2.0 Logout processing without communicating with the Asserting Party
| /nifi-api/access/saml/login/consumer | Process SAML 2.0 Login Requests assertions using HTTP-POST or HTTP-REDIRECT binding
| /nifi-api/access/saml/metadata | Retrieve SAML 2.0 entity descriptor metadata as XML
| /nifi-api/access/saml/single-logout/consumer | Process SAML 2.0 Single Logout Request assertions using HTTP-POST or HTTP-REDIRECT binding. Requires Single Logout to be enabled.
| /nifi-api/access/saml/single-logout/request | Complete SAML 2.0 Single Logout processing initiating a request to the Asserting Party. Requires Single Logout to be enabled.
|======================================

[[apache_knox]]
=== Apache Knox

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,17 +43,6 @@ public class IdpDataSourceFactoryBean implements FactoryBean<JdbcConnectionPool>
// idp tables
// ----------

private static final String IDP_CREDENTIAL_TABLE_NAME = "IDENTITY_PROVIDER_CREDENTIAL";

private static final String CREATE_IDP_CREDENTIAL_TABLE = "CREATE TABLE " + IDP_CREDENTIAL_TABLE_NAME + " ("
+ "ID INT NOT NULL PRIMARY KEY AUTO_INCREMENT, "
+ "IDENTITY VARCHAR2(4096) NOT NULL, "
+ "IDP_TYPE VARCHAR2(200) NOT NULL, "
+ "CREDENTIAL BLOB NOT NULL, "
+ "CREATED TIMESTAMP NOT NULL, "
+ "CONSTRAINT UK__IDENTITY UNIQUE (IDENTITY)"
+ ")";

private static final String IDP_USER_GROUP_TABLE_NAME = "IDENTITY_PROVIDER_USER_GROUP";

private static final String CREATE_IDP_USER_GROUP_TABLE = "CREATE TABLE " + IDP_USER_GROUP_TABLE_NAME + " ("
Expand Down Expand Up @@ -108,9 +97,8 @@ public JdbcConnectionPool getObject() throws Exception {
statement = connection.createStatement();

// determine if the idp tables need to be created
rs = connection.getMetaData().getTables(null, null, IDP_CREDENTIAL_TABLE_NAME, null);
rs = connection.getMetaData().getTables(null, null, IDP_USER_GROUP_TABLE_NAME, null);
if (!rs.next()) {
statement.execute(CREATE_IDP_CREDENTIAL_TABLE);
statement.execute(CREATE_IDP_USER_GROUP_TABLE);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,6 @@ public interface DAOFactory {

ActionDAO getActionDAO();

IdpCredentialDAO getIdpCredentialDAO();

IdpUserGroupDAO getIdpUserGroupDAO();

}
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@

import org.apache.nifi.admin.dao.ActionDAO;
import org.apache.nifi.admin.dao.DAOFactory;
import org.apache.nifi.admin.dao.IdpCredentialDAO;
import org.apache.nifi.admin.dao.IdpUserGroupDAO;

import java.sql.Connection;
Expand All @@ -39,11 +38,6 @@ public ActionDAO getActionDAO() {
return new StandardActionDAO(connection);
}

@Override
public IdpCredentialDAO getIdpCredentialDAO() {
return new StandardIdpCredentialDAO(connection);
}

@Override
public IdpUserGroupDAO getIdpUserGroupDAO() {
return new StandardIdpUserGroupDAO(connection);
Expand Down

This file was deleted.