mirror of https://github.com/apache/nifi.git
NIFI-13232 Add Authentication Configuration REST API method (#8834)
* NIFI-13232 Added Authentication Configuration REST API method * NIFI-13236 Moved logoutSupported from Configuration to Current User * NIFI-13232 Added externalLoginRequired field This closes #8834
This commit is contained in:
parent
b27fc46b60
commit
226ac9671f
|
@ -0,0 +1,85 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.nifi.web.api.dto;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.xml.bind.annotation.XmlType;
|
||||
|
||||
/**
|
||||
* Authentication Configuration endpoint and status information
|
||||
*/
|
||||
@XmlType(name = "authenticationConfiguration")
|
||||
public class AuthenticationConfigurationDTO {
|
||||
|
||||
private boolean externalLoginRequired;
|
||||
|
||||
private boolean loginSupported;
|
||||
|
||||
private String loginUri;
|
||||
|
||||
private String logoutUri;
|
||||
|
||||
@Schema(
|
||||
description = "Whether the system requires login through an external Identity Provider",
|
||||
accessMode = Schema.AccessMode.READ_ONLY
|
||||
)
|
||||
public boolean isExternalLoginRequired() {
|
||||
return externalLoginRequired;
|
||||
}
|
||||
|
||||
public void setExternalLoginRequired(final boolean externalLoginRequired) {
|
||||
this.externalLoginRequired = externalLoginRequired;
|
||||
}
|
||||
|
||||
@Schema(
|
||||
description = "Whether the system is configured to support login operations",
|
||||
accessMode = Schema.AccessMode.READ_ONLY
|
||||
)
|
||||
public boolean isLoginSupported() {
|
||||
return loginSupported;
|
||||
}
|
||||
|
||||
public void setLoginSupported(final boolean loginSupported) {
|
||||
this.loginSupported = loginSupported;
|
||||
}
|
||||
|
||||
@Schema(
|
||||
description = "Location for initiating login processing",
|
||||
accessMode = Schema.AccessMode.READ_ONLY,
|
||||
nullable = true
|
||||
)
|
||||
public String getLoginUri() {
|
||||
return loginUri;
|
||||
}
|
||||
|
||||
public void setLoginUri(final String loginUri) {
|
||||
this.loginUri = loginUri;
|
||||
}
|
||||
|
||||
@Schema(
|
||||
description = "Location for initiating logout processing",
|
||||
accessMode = Schema.AccessMode.READ_ONLY,
|
||||
nullable = true
|
||||
)
|
||||
public String getLogoutUri() {
|
||||
return logoutUri;
|
||||
}
|
||||
|
||||
public void setLogoutUri(final String logoutUri) {
|
||||
this.logoutUri = logoutUri;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.nifi.web.api.entity;
|
||||
|
||||
import jakarta.xml.bind.annotation.XmlRootElement;
|
||||
import org.apache.nifi.web.api.dto.AuthenticationConfigurationDTO;
|
||||
|
||||
@XmlRootElement(name = "authenticationConfigurationEntity")
|
||||
public class AuthenticationConfigurationEntity extends Entity {
|
||||
|
||||
private AuthenticationConfigurationDTO authenticationConfiguration;
|
||||
|
||||
public AuthenticationConfigurationDTO getAuthenticationConfiguration() {
|
||||
return authenticationConfiguration;
|
||||
}
|
||||
|
||||
public void setAuthenticationConfiguration(final AuthenticationConfigurationDTO authenticationConfiguration) {
|
||||
this.authenticationConfiguration = authenticationConfiguration;
|
||||
}
|
||||
}
|
|
@ -31,6 +31,7 @@ public class CurrentUserEntity extends Entity {
|
|||
|
||||
private String identity;
|
||||
private boolean anonymous;
|
||||
private boolean logoutSupported;
|
||||
|
||||
private PermissionsDTO provenancePermissions;
|
||||
private PermissionsDTO countersPermissions;
|
||||
|
@ -68,6 +69,18 @@ public class CurrentUserEntity extends Entity {
|
|||
this.anonymous = anonymous;
|
||||
}
|
||||
|
||||
@Schema(
|
||||
description = "Whether the system is configured to support logout operations based on current user authentication status",
|
||||
accessMode = Schema.AccessMode.READ_ONLY
|
||||
)
|
||||
public boolean isLogoutSupported() {
|
||||
return logoutSupported;
|
||||
}
|
||||
|
||||
public void setLogoutSupported(final boolean logoutSupported) {
|
||||
this.logoutSupported = logoutSupported;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return if the use can query provenance
|
||||
*/
|
||||
|
|
|
@ -23,6 +23,7 @@ import org.springframework.security.core.context.SecurityContextHolder;
|
|||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
* Utility methods for retrieving information about the current application user.
|
||||
|
@ -89,4 +90,27 @@ public final class NiFiUserUtils {
|
|||
return proxyChain;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Authentication Credentials from the current Spring Security Context Authentication object
|
||||
*
|
||||
* @return Optional Credentials from Spring Security Context
|
||||
*/
|
||||
public static Optional<Object> getAuthenticationCredentials() {
|
||||
final Optional<Object> authenticationCredentials;
|
||||
|
||||
final SecurityContext securityContext = SecurityContextHolder.getContext();
|
||||
if (securityContext == null) {
|
||||
authenticationCredentials = Optional.empty();
|
||||
} else {
|
||||
final Authentication authentication = securityContext.getAuthentication();
|
||||
if (authentication == null) {
|
||||
authenticationCredentials = Optional.empty();
|
||||
} else {
|
||||
final Object credentials = authentication.getCredentials();
|
||||
authenticationCredentials = Optional.ofNullable(credentials);
|
||||
}
|
||||
}
|
||||
|
||||
return authenticationCredentials;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,14 +19,18 @@ package org.apache.nifi.web;
|
|||
import org.apache.nifi.admin.service.AuditService;
|
||||
import org.apache.nifi.admin.service.EntityStoreAuditService;
|
||||
import org.apache.nifi.util.NiFiProperties;
|
||||
import org.apache.nifi.web.configuration.AuthenticationConfiguration;
|
||||
import org.apache.nifi.web.security.configuration.WebSecurityConfiguration;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.context.annotation.ImportResource;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import java.io.File;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
|
||||
/**
|
||||
* Web Application Spring Configuration
|
||||
|
@ -41,6 +45,23 @@ import java.io.File;
|
|||
"classpath:nifi-cluster-protocol-context.xml",
|
||||
"classpath:nifi-web-api-context.xml"})
|
||||
public class NiFiWebApiConfiguration {
|
||||
private static final URI OAUTH2_AUTHORIZATION_URI = getPathUri("/nifi-api/oauth2/authorization/consumer");
|
||||
|
||||
private static final URI OIDC_LOGOUT_URI = getPathUri("/nifi-api/access/oidc/logout");
|
||||
|
||||
private static final URI SAML2_AUTHENTICATE_URI = getPathUri("/nifi-api/saml2/authenticate/consumer");
|
||||
|
||||
private static final URI SAML_LOCAL_LOGOUT_URI = getPathUri("/nifi-api/access/saml/local-logout/request");
|
||||
|
||||
private static final URI SAML_SINGLE_LOGOUT_URI = getPathUri("/nifi-api/access/saml/single-logout/request");
|
||||
|
||||
private static final URI LOGIN_FORM_URI = getLoginFormUri();
|
||||
|
||||
private static final URI LOGOUT_COMPLETE_URI = getPathUri("/nifi-api/access/logout/complete");
|
||||
|
||||
private static final String UI_PATH = "/nf/";
|
||||
|
||||
private static final String LOGIN_FRAGMENT = "/login";
|
||||
|
||||
public NiFiWebApiConfiguration() {
|
||||
super();
|
||||
|
@ -58,4 +79,61 @@ public class NiFiWebApiConfiguration {
|
|||
final File databaseDirectory = properties.getDatabaseRepositoryPath().toFile();
|
||||
return new EntityStoreAuditService(databaseDirectory);
|
||||
}
|
||||
|
||||
@Autowired
|
||||
@Bean
|
||||
public AuthenticationConfiguration authenticationConfiguration(final NiFiProperties properties) {
|
||||
final URI loginUri;
|
||||
final URI logoutUri;
|
||||
final boolean externalLoginRequired;
|
||||
|
||||
// HTTPS is required for authentication
|
||||
if (properties.isHTTPSConfigured()) {
|
||||
final String loginIdentityProvider = properties.getProperty(NiFiProperties.SECURITY_USER_LOGIN_IDENTITY_PROVIDER);
|
||||
if (properties.isOidcEnabled()) {
|
||||
externalLoginRequired = true;
|
||||
loginUri = OAUTH2_AUTHORIZATION_URI;
|
||||
logoutUri = OIDC_LOGOUT_URI;
|
||||
} else if (properties.isSamlEnabled()) {
|
||||
externalLoginRequired = true;
|
||||
loginUri = SAML2_AUTHENTICATE_URI;
|
||||
if (properties.isSamlSingleLogoutEnabled()) {
|
||||
logoutUri = SAML_SINGLE_LOGOUT_URI;
|
||||
} else {
|
||||
logoutUri = SAML_LOCAL_LOGOUT_URI;
|
||||
}
|
||||
} else if (StringUtils.hasText(loginIdentityProvider)) {
|
||||
externalLoginRequired = false;
|
||||
loginUri = LOGIN_FORM_URI;
|
||||
logoutUri = LOGOUT_COMPLETE_URI;
|
||||
} else {
|
||||
externalLoginRequired = false;
|
||||
loginUri = null;
|
||||
logoutUri = null;
|
||||
}
|
||||
} else {
|
||||
externalLoginRequired = false;
|
||||
loginUri = null;
|
||||
logoutUri = null;
|
||||
}
|
||||
|
||||
final boolean loginSupported = loginUri != null;
|
||||
return new AuthenticationConfiguration(externalLoginRequired, loginSupported, loginUri, logoutUri);
|
||||
}
|
||||
|
||||
private static URI getPathUri(final String path) {
|
||||
try {
|
||||
return new URI(null, null, path, null);
|
||||
} catch (final URISyntaxException e) {
|
||||
throw new IllegalArgumentException("Path URI construction failed", e);
|
||||
}
|
||||
}
|
||||
|
||||
private static URI getLoginFormUri() {
|
||||
try {
|
||||
return new URI(null, null, UI_PATH, LOGIN_FRAGMENT);
|
||||
} catch (final URISyntaxException e) {
|
||||
throw new IllegalArgumentException("Path Fragment URI construction failed", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -98,6 +98,7 @@ public class NiFiWebApiResourceConfig extends ResourceConfig {
|
|||
register(ctx.getBean("systemDiagnosticsResource"));
|
||||
register(ctx.getBean("accessResource"));
|
||||
register(ctx.getBean("accessPolicyResource"));
|
||||
register(ctx.getBean("authenticationResource"));
|
||||
register(ctx.getBean("tenantsResource"));
|
||||
register(ctx.getBean("versionsResource"));
|
||||
register(ctx.getBean("parameterContextResource"));
|
||||
|
|
|
@ -377,6 +377,8 @@ import org.slf4j.LoggerFactory;
|
|||
|
||||
import jakarta.ws.rs.WebApplicationException;
|
||||
import jakarta.ws.rs.core.Response;
|
||||
import org.springframework.security.oauth2.core.OAuth2Token;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
|
@ -4777,6 +4779,7 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
|
|||
final CurrentUserEntity entity = new CurrentUserEntity();
|
||||
entity.setIdentity(user.getIdentity());
|
||||
entity.setAnonymous(user.isAnonymous());
|
||||
entity.setLogoutSupported(isLogoutSupported());
|
||||
entity.setProvenancePermissions(dtoFactory.createPermissionsDto(authorizableLookup.getProvenance()));
|
||||
entity.setCountersPermissions(dtoFactory.createPermissionsDto(authorizableLookup.getCounters()));
|
||||
entity.setTenantsPermissions(dtoFactory.createPermissionsDto(authorizableLookup.getTenant()));
|
||||
|
@ -6651,6 +6654,13 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
|
|||
return propertyDescriptor;
|
||||
}
|
||||
|
||||
private boolean isLogoutSupported() {
|
||||
// Logout is supported when authenticated using a JSON Web Token
|
||||
return NiFiUserUtils.getAuthenticationCredentials()
|
||||
.map(credentials -> credentials instanceof OAuth2Token)
|
||||
.orElse(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void verifyPublicInputPortUniqueness(final String portId, final String portName) {
|
||||
inputPortDAO.verifyPublicPortUniqueness(portId, portName);
|
||||
|
|
|
@ -0,0 +1,105 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.nifi.web.api;
|
||||
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.media.Content;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import io.swagger.v3.oas.annotations.responses.ApiResponse;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.ws.rs.Consumes;
|
||||
import jakarta.ws.rs.GET;
|
||||
import jakarta.ws.rs.Path;
|
||||
import jakarta.ws.rs.Produces;
|
||||
import jakarta.ws.rs.core.MediaType;
|
||||
import jakarta.ws.rs.core.Response;
|
||||
import org.apache.nifi.cluster.coordination.ClusterCoordinator;
|
||||
import org.apache.nifi.cluster.coordination.http.replication.RequestReplicator;
|
||||
import org.apache.nifi.controller.FlowController;
|
||||
import org.apache.nifi.util.NiFiProperties;
|
||||
import org.apache.nifi.web.api.dto.AuthenticationConfigurationDTO;
|
||||
import org.apache.nifi.web.api.entity.AccessConfigurationEntity;
|
||||
import org.apache.nifi.web.api.entity.AuthenticationConfigurationEntity;
|
||||
import org.apache.nifi.web.configuration.AuthenticationConfiguration;
|
||||
import org.apache.nifi.web.util.RequestUriBuilder;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.Objects;
|
||||
|
||||
@Path("/authentication")
|
||||
@Tag(name = "Authentication")
|
||||
public class AuthenticationResource extends ApplicationResource {
|
||||
private final AuthenticationConfiguration authenticationConfiguration;
|
||||
|
||||
public AuthenticationResource(
|
||||
final AuthenticationConfiguration authenticationConfiguration,
|
||||
final NiFiProperties properties,
|
||||
final RequestReplicator requestReplicator,
|
||||
final ClusterCoordinator clusterCoordinator,
|
||||
final FlowController flowController
|
||||
) {
|
||||
this.authenticationConfiguration = Objects.requireNonNull(authenticationConfiguration);
|
||||
setProperties(properties);
|
||||
setRequestReplicator(requestReplicator);
|
||||
setClusterCoordinator(clusterCoordinator);
|
||||
setFlowController(flowController);
|
||||
}
|
||||
|
||||
@GET
|
||||
@Consumes(MediaType.WILDCARD)
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@Path("/configuration")
|
||||
@Operation(
|
||||
summary = "Retrieves the authentication configuration endpoint and status information",
|
||||
responses = @ApiResponse(content = @Content(schema = @Schema(implementation = AccessConfigurationEntity.class)))
|
||||
)
|
||||
public Response getAuthenticationConfiguration() {
|
||||
final AuthenticationConfigurationDTO configuration = new AuthenticationConfigurationDTO();
|
||||
configuration.setExternalLoginRequired(authenticationConfiguration.externalLoginRequired());
|
||||
configuration.setLoginSupported(authenticationConfiguration.loginSupported());
|
||||
|
||||
final URI configuredLoginUri = authenticationConfiguration.loginUri();
|
||||
if (configuredLoginUri != null) {
|
||||
final String loginUri = getAuthenticationUri(configuredLoginUri);
|
||||
configuration.setLoginUri(loginUri);
|
||||
}
|
||||
|
||||
final URI configuredLogoutUri = authenticationConfiguration.logoutUri();
|
||||
if (configuredLogoutUri != null) {
|
||||
final String logoutUri = getAuthenticationUri(configuredLogoutUri);
|
||||
configuration.setLogoutUri(logoutUri);
|
||||
}
|
||||
|
||||
final AuthenticationConfigurationEntity entity = new AuthenticationConfigurationEntity();
|
||||
entity.setAuthenticationConfiguration(configuration);
|
||||
|
||||
return generateOkResponse(entity).build();
|
||||
}
|
||||
|
||||
private String getAuthenticationUri(final URI configuredUri) {
|
||||
final RequestUriBuilder builder = RequestUriBuilder.fromHttpServletRequest(httpServletRequest);
|
||||
builder.path(configuredUri.getPath());
|
||||
|
||||
final String fragment = configuredUri.getFragment();
|
||||
if (StringUtils.hasText(fragment)) {
|
||||
builder.fragment(fragment);
|
||||
}
|
||||
|
||||
return builder.build().toString();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
* 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.configuration;
|
||||
|
||||
import java.net.URI;
|
||||
|
||||
/**
|
||||
* Authentication Configuration based on configured application properties
|
||||
*
|
||||
* @param externalLoginRequired Whether login through an external Identity Provider is required
|
||||
* @param loginSupported Whether login operations are supported
|
||||
* @param loginUri Optional URI for login operations
|
||||
* @param logoutUri Optional URI for logout operations
|
||||
*/
|
||||
public record AuthenticationConfiguration(
|
||||
boolean externalLoginRequired,
|
||||
boolean loginSupported,
|
||||
URI loginUri,
|
||||
URI logoutUri
|
||||
) {
|
||||
}
|
|
@ -630,6 +630,13 @@
|
|||
<constructor-arg ref="requestReplicator" />
|
||||
<constructor-arg ref="flowController" />
|
||||
</bean>
|
||||
<bean id="authenticationResource" class="org.apache.nifi.web.api.AuthenticationResource" scope="singleton">
|
||||
<constructor-arg ref="authenticationConfiguration"/>
|
||||
<constructor-arg ref="nifiProperties"/>
|
||||
<constructor-arg ref="clusterCoordinator"/>
|
||||
<constructor-arg ref="requestReplicator" />
|
||||
<constructor-arg ref="flowController" />
|
||||
</bean>
|
||||
<bean id="tenantsResource" class="org.apache.nifi.web.api.TenantsResource" scope="singleton">
|
||||
<constructor-arg ref="serviceFacade"/>
|
||||
<constructor-arg ref="authorizer"/>
|
||||
|
|
|
@ -118,7 +118,8 @@ public class WebSecurityConfiguration {
|
|||
"/access/kerberos",
|
||||
"/access/knox/callback",
|
||||
"/access/knox/request",
|
||||
"/access/logout/complete"
|
||||
"/access/logout/complete",
|
||||
"/authentication/configuration"
|
||||
).permitAll()
|
||||
.anyRequest().authenticated()
|
||||
)
|
||||
|
|
|
@ -56,7 +56,7 @@ public class StandardJwtAuthenticationConverter implements Converter<Jwt, NiFiAu
|
|||
@Override
|
||||
public NiFiAuthenticationToken convert(final Jwt jwt) {
|
||||
final NiFiUser user = getUser(jwt);
|
||||
return new NiFiAuthenticationToken(new NiFiUserDetails(user));
|
||||
return new NiFiAuthenticationToken(new NiFiUserDetails(user), jwt);
|
||||
}
|
||||
|
||||
private NiFiUser getUser(final Jwt jwt) {
|
||||
|
|
|
@ -26,16 +26,34 @@ public class NiFiAuthenticationToken extends AbstractAuthenticationToken {
|
|||
|
||||
final UserDetails nifiUserDetails;
|
||||
|
||||
public NiFiAuthenticationToken(final UserDetails nifiUserDetails) {
|
||||
super(nifiUserDetails.getAuthorities());
|
||||
private final Object credentials;
|
||||
|
||||
/**
|
||||
* Token constructor with User Details and without additional credentials
|
||||
*
|
||||
* @param userDetails Spring Security User Details
|
||||
*/
|
||||
public NiFiAuthenticationToken(final UserDetails userDetails) {
|
||||
this(userDetails, userDetails.getPassword());
|
||||
}
|
||||
|
||||
/**
|
||||
* Token constructor with User Details and optional credentials from authentication processing
|
||||
*
|
||||
* @param userDetails Spring Security User Details
|
||||
* @param credentials Optional credentials from authentication processing
|
||||
*/
|
||||
public NiFiAuthenticationToken(final UserDetails userDetails, final Object credentials) {
|
||||
super(userDetails.getAuthorities());
|
||||
super.setAuthenticated(true);
|
||||
setDetails(nifiUserDetails);
|
||||
this.nifiUserDetails = nifiUserDetails;
|
||||
setDetails(userDetails);
|
||||
this.nifiUserDetails = userDetails;
|
||||
this.credentials = credentials;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getCredentials() {
|
||||
return nifiUserDetails.getPassword();
|
||||
return credentials;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -39,6 +39,7 @@ import org.slf4j.LoggerFactory;
|
|||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.core.AuthenticationException;
|
||||
|
||||
import java.security.cert.X509Certificate;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
@ -80,16 +81,18 @@ public class X509AuthenticationProvider extends NiFiAuthenticationProvider {
|
|||
final X509AuthenticationRequestToken request = (X509AuthenticationRequestToken) authentication;
|
||||
|
||||
// attempt to authenticate if certificates were found
|
||||
final X509Certificate[] certificates = request.getCertificates();;
|
||||
final AuthenticationResponse authenticationResponse;
|
||||
try {
|
||||
authenticationResponse = certificateIdentityProvider.authenticate(request.getCertificates());
|
||||
authenticationResponse = certificateIdentityProvider.authenticate(certificates);
|
||||
} catch (final IllegalArgumentException iae) {
|
||||
throw new InvalidAuthenticationException(iae.getMessage(), iae);
|
||||
}
|
||||
|
||||
if (StringUtils.isBlank(request.getProxiedEntitiesChain())) {
|
||||
final String mappedIdentity = mapIdentity(authenticationResponse.getIdentity());
|
||||
return new NiFiAuthenticationToken(new NiFiUserDetails(new Builder().identity(mappedIdentity).groups(getUserGroups(mappedIdentity)).clientAddress(request.getClientAddress()).build()));
|
||||
final NiFiUser user = new Builder().identity(mappedIdentity).groups(getUserGroups(mappedIdentity)).clientAddress(request.getClientAddress()).build();
|
||||
return new NiFiAuthenticationToken(new NiFiUserDetails(user), certificates);
|
||||
} else {
|
||||
// get the idp groups for the end-user that were sent over in the X-ProxiedEntityGroups header
|
||||
final Set<String> endUserIdpGroups = ProxiedEntitiesUtils.tokenizeProxiedEntityGroups(request.getProxiedEntityGroups());
|
||||
|
@ -139,7 +142,7 @@ public class X509AuthenticationProvider extends NiFiAuthenticationProvider {
|
|||
logProxyChain(proxy);
|
||||
}
|
||||
|
||||
return new NiFiAuthenticationToken(new NiFiUserDetails(proxy));
|
||||
return new NiFiAuthenticationToken(new NiFiUserDetails(proxy), certificates);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue