Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
6 changed files
with
226 additions
and
37 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
34 changes: 34 additions & 0 deletions
34
...impl/src/main/java/com/evolveum/midpoint/model/impl/security/NodeAuthenticationToken.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
package com.evolveum.midpoint.model.impl.security; | ||
|
||
import java.util.Collection; | ||
|
||
import org.springframework.security.authentication.AbstractAuthenticationToken; | ||
import org.springframework.security.core.GrantedAuthority; | ||
|
||
import com.evolveum.midpoint.prism.PrismObject; | ||
import com.evolveum.midpoint.xml.ns._public.common.common_3.NodeType; | ||
|
||
public class NodeAuthenticationToken extends AbstractAuthenticationToken { | ||
|
||
private static final long serialVersionUID = 1L; | ||
|
||
private PrismObject<NodeType> node; | ||
private String remoteAddress; | ||
|
||
public NodeAuthenticationToken(PrismObject<NodeType> node, String remoteAddress, Collection<? extends GrantedAuthority> authorities) { | ||
super(authorities); | ||
this.node = node; | ||
this.remoteAddress = remoteAddress; | ||
} | ||
|
||
@Override | ||
public Object getCredentials() { | ||
return remoteAddress; | ||
} | ||
|
||
@Override | ||
public PrismObject<NodeType> getPrincipal() { | ||
return node; | ||
} | ||
|
||
} |
112 changes: 112 additions & 0 deletions
112
...model-impl/src/main/java/com/evolveum/midpoint/model/impl/security/NodeAuthenticator.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,112 @@ | ||
package com.evolveum.midpoint.model.impl.security; | ||
|
||
import java.util.ArrayList; | ||
import java.util.List; | ||
|
||
import org.apache.commons.collections4.CollectionUtils; | ||
import org.apache.commons.lang.StringUtils; | ||
import org.springframework.beans.factory.annotation.Autowired; | ||
import org.springframework.beans.factory.annotation.Qualifier; | ||
import org.springframework.security.core.context.SecurityContextHolder; | ||
import org.springframework.stereotype.Component; | ||
|
||
import com.evolveum.midpoint.prism.PrismContext; | ||
import com.evolveum.midpoint.prism.PrismObject; | ||
import com.evolveum.midpoint.prism.query.ObjectQuery; | ||
import com.evolveum.midpoint.prism.query.builder.QueryBuilder; | ||
import com.evolveum.midpoint.prism.query.builder.S_FilterEntryOrEmpty; | ||
import com.evolveum.midpoint.repo.api.RepositoryService; | ||
import com.evolveum.midpoint.schema.constants.SchemaConstants; | ||
import com.evolveum.midpoint.schema.result.OperationResult; | ||
import com.evolveum.midpoint.security.api.ConnectionEnvironment; | ||
import com.evolveum.midpoint.util.exception.SchemaException; | ||
import com.evolveum.midpoint.util.logging.LoggingUtils; | ||
import com.evolveum.midpoint.util.logging.Trace; | ||
import com.evolveum.midpoint.util.logging.TraceManager; | ||
import com.evolveum.midpoint.xml.ns._public.common.common_3.NodeType; | ||
|
||
@Component | ||
public class NodeAuthenticator { | ||
|
||
@Autowired | ||
@Qualifier("cacheRepositoryService") | ||
private RepositoryService repositoryService; | ||
@Autowired private PrismContext prismContext; | ||
|
||
|
||
@Autowired SecurityHelper securityHelper; | ||
|
||
private static final Trace LOGGER = TraceManager.getTrace(NodeAuthenticator.class); | ||
|
||
private static final String OPERATION_SEARCH_NODE = NodeAuthenticator.class.getName() + ".searchNode"; | ||
|
||
public boolean authenticate(String remoteName, String remoteAddress, String operation) { | ||
LOGGER.debug("Checking if {} is a known node", remoteName); | ||
OperationResult result = new OperationResult(OPERATION_SEARCH_NODE); | ||
|
||
ConnectionEnvironment connEnv = ConnectionEnvironment.create(SchemaConstants.CHANNEL_REST_URI); | ||
|
||
try { | ||
|
||
List<PrismObject<NodeType>> knownNodes = repositoryService.searchObjects(NodeType.class, | ||
null, null, result); | ||
|
||
List<PrismObject<NodeType>> matchingNodes = getMatchingNodes(knownNodes, remoteName, remoteAddress, operation); | ||
|
||
if (matchingNodes.size() == 1) { | ||
PrismObject<NodeType> actualNode = knownNodes.iterator().next(); | ||
LOGGER.trace( | ||
"The node {} was recognized as a known node (remote host name {} matched). Attempting to execute the requested operation: {} ", | ||
actualNode.asObjectable().getName(), actualNode.asObjectable().getHostname(), operation); | ||
NodeAuthenticationToken authNtoken = new NodeAuthenticationToken(actualNode, remoteAddress, | ||
CollectionUtils.EMPTY_COLLECTION); | ||
SecurityContextHolder.getContext().setAuthentication(authNtoken); | ||
securityHelper.auditLoginSuccess(actualNode.asObjectable(), connEnv); | ||
return true; | ||
} | ||
|
||
} catch (RuntimeException | SchemaException e) { | ||
LOGGER.error("Unhandled exception when listing nodes"); | ||
LoggingUtils.logUnexpectedException(LOGGER, "Unhandled exception when listing nodes", e); | ||
} | ||
securityHelper.auditLoginFailure(remoteName != null ? remoteName : remoteAddress, null, connEnv, "Failed to authneticate node."); | ||
return false; | ||
} | ||
|
||
private List<PrismObject<NodeType>> getMatchingNodes(List<PrismObject<NodeType>> knownNodes, String remoteName, String remoteAddress, String operation) { | ||
List<PrismObject<NodeType>> matchingNodes = new ArrayList<>(); | ||
for (PrismObject<NodeType> node : knownNodes) { | ||
NodeType actualNode = node.asObjectable(); | ||
if (remoteName != null && remoteName.equalsIgnoreCase(actualNode.getHostname())) { | ||
LOGGER.trace("The node {} was recognized as a known node (remote host name {} matched). Attempting to execute the requested operation: {} ", | ||
actualNode.getName(), actualNode.getHostname(), operation); | ||
matchingNodes.add(node); | ||
continue; | ||
} | ||
if (actualNode.getIpAddress().contains(remoteAddress)) { | ||
LOGGER.trace("The node {} was recognized as a known node (remote host address {} matched). Attempting to execute the requested operation: {} ", | ||
actualNode.getName(), remoteAddress, operation); | ||
matchingNodes.add(node); | ||
continue; | ||
} | ||
} | ||
|
||
return matchingNodes; | ||
} | ||
|
||
private ObjectQuery createQuery(String remoteName, String remoteAddress) { | ||
S_FilterEntryOrEmpty filterBuilder = QueryBuilder.queryFor(NodeType.class, prismContext); | ||
|
||
if (StringUtils.isNotBlank(remoteName)) { | ||
return filterBuilder.item(NodeType.F_HOSTNAME).eq(remoteName).build(); | ||
} | ||
|
||
|
||
if (StringUtils.isNotBlank(remoteAddress)) { | ||
return filterBuilder.item(NodeType.F_IP_ADDRESS).contains(remoteAddress).build(); | ||
} | ||
|
||
return null; | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters