blob: ff6a21883d648f585197c08d7a146509721356b9 [file] [log] [blame]
/*
* 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.registry.web.security.authentication;
import org.apache.nifi.registry.properties.NiFiRegistryProperties;
import org.apache.nifi.registry.properties.util.IdentityMapping;
import org.apache.nifi.registry.properties.util.IdentityMappingUtil;
import org.apache.nifi.registry.security.authentication.AuthenticationRequest;
import org.apache.nifi.registry.security.authentication.AuthenticationResponse;
import org.apache.nifi.registry.security.authentication.IdentityProvider;
import org.apache.nifi.registry.security.authentication.exception.InvalidCredentialsException;
import org.apache.nifi.registry.security.authorization.Authorizer;
import org.apache.nifi.registry.security.authorization.Group;
import org.apache.nifi.registry.security.authorization.ManagedAuthorizer;
import org.apache.nifi.registry.security.authorization.UserAndGroups;
import org.apache.nifi.registry.security.authorization.UserGroupProvider;
import org.apache.nifi.registry.security.authorization.user.NiFiUserDetails;
import org.apache.nifi.registry.security.authorization.user.StandardNiFiUser;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
public class IdentityAuthenticationProvider implements AuthenticationProvider {
private static final Logger LOGGER = LoggerFactory.getLogger(IdentityAuthenticationProvider.class);
protected NiFiRegistryProperties properties;
protected Authorizer authorizer;
protected final IdentityProvider identityProvider;
private List<IdentityMapping> mappings;
public IdentityAuthenticationProvider(
NiFiRegistryProperties properties,
Authorizer authorizer,
IdentityProvider identityProvider) {
this.properties = properties;
this.authorizer = authorizer;
this.identityProvider = identityProvider;
this.mappings = Collections.unmodifiableList(IdentityMappingUtil.getIdentityMappings(properties));
}
@Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
// Determine if this AuthenticationProvider's identityProvider should be able to support this AuthenticationRequest
boolean tokenOriginatedFromThisIdentityProvider = checkTokenOriginatedFromThisIdentityProvider(authentication);
if (!tokenOriginatedFromThisIdentityProvider) {
// Returning null indicates to The Spring Security AuthenticationManager that this AuthenticationProvider
// cannot authenticate this token and another provider should be tried.
return null;
}
AuthenticationRequestToken authenticationRequestToken = ((AuthenticationRequestToken)authentication);
AuthenticationRequest authenticationRequest = authenticationRequestToken.getAuthenticationRequest();
try {
AuthenticationResponse authenticationResponse = identityProvider.authenticate(authenticationRequest);
if (authenticationResponse == null) {
return null;
}
return buildAuthenticatedToken(authenticationRequestToken, authenticationResponse);
} catch (InvalidCredentialsException e) {
throw new BadCredentialsException("Identity Provider authentication failed.", e);
}
}
@Override
public boolean supports(Class<?> authenticationClazz) {
// is authenticationClazz a subclass of AuthenticationRequestWrapper?
return AuthenticationRequestToken.class.isAssignableFrom(authenticationClazz);
}
protected AuthenticationSuccessToken buildAuthenticatedToken(
AuthenticationRequestToken requestToken,
AuthenticationResponse response) {
final String mappedIdentity = mapIdentity(response.getIdentity());
return new AuthenticationSuccessToken(new NiFiUserDetails(
new StandardNiFiUser.Builder()
.identity(mappedIdentity)
.groups(getUserGroups(mappedIdentity))
.clientAddress(requestToken.getClientAddress())
.build()));
}
protected boolean checkTokenOriginatedFromThisIdentityProvider(Authentication authentication) {
return (authentication instanceof AuthenticationRequestToken
&& identityProvider.getClass().equals(((AuthenticationRequestToken) authentication).getAuthenticationRequestOrigin()));
}
protected String mapIdentity(final String identity) {
return IdentityMappingUtil.mapIdentity(identity, mappings);
}
protected Set<String> getUserGroups(final String identity) {
return getUserGroups(authorizer, identity);
}
private static Set<String> getUserGroups(final Authorizer authorizer, final String userIdentity) {
if (authorizer instanceof ManagedAuthorizer) {
final ManagedAuthorizer managedAuthorizer = (ManagedAuthorizer) authorizer;
final UserGroupProvider userGroupProvider = managedAuthorizer.getAccessPolicyProvider().getUserGroupProvider();
final UserAndGroups userAndGroups = userGroupProvider.getUserAndGroups(userIdentity);
final Set<Group> userGroups = userAndGroups.getGroups();
if (userGroups == null || userGroups.isEmpty()) {
return Collections.emptySet();
} else {
return userAndGroups.getGroups().stream().map(Group::getName).collect(Collectors.toSet());
}
} else {
return null;
}
}
}