Skip to content

Commit

Permalink
providers clenaup, better code structure, adding new PreAuthenticated…
Browse files Browse the repository at this point in the history
…Provider.
  • Loading branch information
katkav committed Aug 4, 2023
1 parent bfc7b43 commit 46378d0
Show file tree
Hide file tree
Showing 20 changed files with 281 additions and 194 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@

import java.io.IOException;
import java.util.List;

import com.evolveum.midpoint.authentication.api.util.AuthUtil;

import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

Expand Down Expand Up @@ -35,16 +38,12 @@ public void commence(
HttpServletResponse response,
AuthenticationException authException) throws IOException {

Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
MidpointAuthentication mpAuthentication = AuthUtil.getMidpointAuthentication();

if (authentication instanceof MidpointAuthentication) {
MidpointAuthentication mpAuthentication = (MidpointAuthentication) authentication;
List<ModuleAuthentication> parallelProcessingModules =
mpAuthentication.getParallelProcessingModules();
if (!parallelProcessingModules.isEmpty()) {
for (ModuleAuthentication moduleAuthentication : parallelProcessingModules) {
response.addHeader("WWW-Authenticate", getRealmForHeader(moduleAuthentication, authException));
}
List<ModuleAuthentication> parallelProcessingModules = mpAuthentication.getParallelProcessingModules();
if (!parallelProcessingModules.isEmpty()) {
for (ModuleAuthentication moduleAuthentication : parallelProcessingModules) {
response.addHeader("WWW-Authenticate", getRealmForHeader(moduleAuthentication, authException));
}
}
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,8 +101,7 @@ protected boolean hasNoAuthorizations(MidPointPrincipal principal) {
return true;
}

protected void recordModuleAuthenticationSuccess(@NotNull MidPointPrincipal principal, @NotNull ConnectionEnvironment connEnv,
boolean audit) {
protected void recordModuleAuthenticationSuccess(@NotNull MidPointPrincipal principal, @NotNull ConnectionEnvironment connEnv) {
authenticationRecorder.recordModuleAuthenticationAttemptSuccess(principal, connEnv);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@
import com.evolveum.midpoint.authentication.api.config.MidpointAuthentication;
import com.evolveum.midpoint.authentication.api.util.AuthUtil;
import com.evolveum.midpoint.common.Clock;
import com.evolveum.midpoint.model.api.ModelAuditRecorder;
import com.evolveum.midpoint.authentication.api.evaluator.context.AbstractAuthenticationContext;
import com.evolveum.midpoint.authentication.api.evaluator.context.PreAuthenticationContext;
import com.evolveum.midpoint.model.api.util.AuthenticationEvaluatorUtil;
Expand Down Expand Up @@ -94,7 +93,7 @@ public UsernamePasswordAuthenticationToken authenticate(ConnectionEnvironment co
}

checkAuthorizations(principal, connEnv, authnCtx);
recordModuleAuthenticationSuccess(principal, connEnv, false);
recordModuleAuthenticationSuccess(principal, connEnv);
return new UsernamePasswordAuthenticationToken(principal, authnCtx.getEnteredCredential(), principal.getAuthorities());
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ public PreAuthenticatedAuthenticationToken authenticate(

if (AuthenticationEvaluatorUtil.checkRequiredAssignmentTargets(principal.getFocus(), authnCtx.getRequireAssignments())) {
PreAuthenticatedAuthenticationToken token = new PreAuthenticatedAuthenticationToken(principal, null, principal.getAuthorities());
recordModuleAuthenticationSuccess(principal, connEnv, true);
recordModuleAuthenticationSuccess(principal, connEnv);
return token;
} else {
recordModuleAuthenticationFailure(principal.getUsername(), principal, connEnv, null, "not contains required assignment");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
import com.evolveum.midpoint.authentication.impl.module.authentication.ModuleAuthenticationImpl;
import com.evolveum.midpoint.authentication.impl.module.configuration.HttpHeaderModuleWebSecurityConfiguration;
import com.evolveum.midpoint.authentication.impl.module.configurer.HttpHeaderModuleWebSecurityConfigurer;
import com.evolveum.midpoint.authentication.impl.provider.PasswordProvider;
import com.evolveum.midpoint.authentication.impl.provider.PreAuthenticatedProvider;
import com.evolveum.midpoint.xml.ns._public.common.common_3.AbstractAuthenticationModuleType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.AuthenticationSequenceModuleType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.HttpHeaderAuthenticationModuleType;
Expand All @@ -39,7 +39,7 @@ public boolean match(AbstractAuthenticationModuleType moduleType, Authentication
protected HttpHeaderModuleWebSecurityConfigurer createModuleConfigurer(HttpHeaderAuthenticationModuleType moduleType, String sequenceSuffix, AuthenticationChannel authenticationChannel, ObjectPostProcessor<Object> objectPostProcessor, ServletRequest request) {
return new HttpHeaderModuleWebSecurityConfigurer(moduleType, sequenceSuffix, authenticationChannel,
objectPostProcessor, request,
new PasswordProvider());
new PreAuthenticatedProvider());
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@

import java.util.HashMap;
import java.util.Map;

import com.evolveum.midpoint.authentication.api.util.AuthUtil;

import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

Expand Down Expand Up @@ -39,22 +42,13 @@ public class SecurityQuestionsAuthenticationFilter
private static final String SPRING_SECURITY_FORM_USER_KEY = "user";

private String getIdentifiedUsername() {
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
if(!(authentication instanceof MidpointAuthentication)) {
return "";
}

MidpointAuthentication midpointAuthentication = (MidpointAuthentication) authentication;
MidpointAuthentication midpointAuthentication = AuthUtil.getMidpointAuthentication();
Object principal = midpointAuthentication.getPrincipal();
if (!(principal instanceof MidPointPrincipal)) {
return "";
}

FocusType focus = ((MidPointPrincipal) principal).getFocus();
if (focus == null) {
return "";
}

return focus.getName().getNorm();

}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,31 +31,34 @@ public class ArchetypeSelectionAuthenticationProvider extends MidpointAbstractAu
private static final Trace LOGGER = TraceManager.getTrace(ArchetypeSelectionAuthenticationProvider.class);

@Override
protected Authentication doAuthenticate(Authentication authentication, List<ObjectReferenceType> requireAssignment, AuthenticationChannel channel, Class<? extends FocusType> focusType) {
protected Authentication doAuthenticate(
Authentication authentication,
String enteredUsername,
List<ObjectReferenceType> requireAssignment, AuthenticationChannel channel, Class<? extends FocusType> focusType) {

if (authentication instanceof ArchetypeSelectionAuthenticationToken) {
//todo process the case when no archetype oid is defined
var archetypeOid = ((ArchetypeSelectionAuthenticationToken) authentication).getArchetypeOid();
var allowUndefinedArchetype = ((ArchetypeSelectionAuthenticationToken) authentication).isAllowUndefinedArchetype();
if (StringUtils.isEmpty(archetypeOid) && !allowUndefinedArchetype) {
LOGGER.debug("No details provided: {}", authentication);
throw new BadCredentialsException(AuthUtil.generateBadCredentialsMessageKey(authentication));
}
authentication.setAuthenticated(true);
saveArchetypeToMidpointAuthentication(archetypeOid);
return authentication;

} else {
//TODO do we want to check entered username? e.g. it probably doesn't have any sense to check archetype selection
// when the user was already identified?
if (!(authentication instanceof ArchetypeSelectionAuthenticationToken)) {
LOGGER.error("Unsupported authentication {}", authentication);
throw new AuthenticationServiceException("web.security.provider.unavailable");
}

//todo process the case when no archetype oid is defined
var archetypeOid = ((ArchetypeSelectionAuthenticationToken) authentication).getArchetypeOid();
var allowUndefinedArchetype = ((ArchetypeSelectionAuthenticationToken) authentication).isAllowUndefinedArchetype();
if (StringUtils.isEmpty(archetypeOid) && !allowUndefinedArchetype) {
LOGGER.debug("No details provided: {}", authentication);
throw new BadCredentialsException(AuthUtil.generateBadCredentialsMessageKey(authentication));
}
authentication.setAuthenticated(true);
saveArchetypeToMidpointAuthentication(archetypeOid);
return authentication;

}

private void saveArchetypeToMidpointAuthentication(String archetypeOid) {
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
if (authentication instanceof MidpointAuthentication) {
((MidpointAuthentication) authentication).setArchetypeOid(archetypeOid);
}
MidpointAuthentication authentication = AuthUtil.getMidpointAuthentication();
authentication.setArchetypeOid(archetypeOid);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,27 +40,33 @@ protected AttributeVerificationEvaluatorImpl getEvaluator() {


@Override
protected Authentication doAuthenticate(Authentication authentication, List<ObjectReferenceType> requireAssignment,
protected Authentication doAuthenticate(
Authentication authentication,
String enteredUsername,
List<ObjectReferenceType> requireAssignment,
AuthenticationChannel channel, Class<? extends FocusType> focusType) {
if (!(authentication.getPrincipal() instanceof MidPointPrincipal)) {
return authentication; //TODO should not be exception?
}
String enteredUsername = ((MidPointPrincipal) authentication.getPrincipal()).getUsername();
// if (!(authentication.getPrincipal() instanceof MidPointPrincipal)) {
// return authentication; //TODO should not be exception?
// }
// String enteredUsername = ((MidPointPrincipal) authentication.getPrincipal()).getUsername();
LOGGER.trace("Authenticating username '{}'", enteredUsername);
if (enteredUsername == null) {
LOGGER.error("No username provided in the authentication token");
return authentication; //TODO should not be exception?
}

ConnectionEnvironment connEnv = createEnvironment(channel);

Authentication token;
if (authentication instanceof AttributeVerificationToken) {
Map<ItemPath, String> attrValuesMap = (Map<ItemPath, String>) authentication.getCredentials();
AttributeVerificationAuthenticationContext authContext = new AttributeVerificationAuthenticationContext(enteredUsername,
focusType, attrValuesMap, requireAssignment, channel);
token = getEvaluator().authenticate(connEnv, authContext);
} else {
if (!(authentication instanceof AttributeVerificationToken)) {
LOGGER.error("Unsupported authentication {}", authentication);
throw new AuthenticationServiceException("web.security.provider.unavailable");
}

Map<ItemPath, String> attrValuesMap = (Map<ItemPath, String>) authentication.getCredentials();
AttributeVerificationAuthenticationContext authContext = new AttributeVerificationAuthenticationContext(enteredUsername,
focusType, attrValuesMap, requireAssignment, channel);
Authentication token = getEvaluator().authenticate(connEnv, authContext);

MidPointPrincipal principal = (MidPointPrincipal) token.getPrincipal();
LOGGER.debug("User '{}' authenticated ({}), authorities: {}", authentication.getPrincipal(),
authentication.getClass().getSimpleName(), principal.getAuthorities());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,21 +70,23 @@ public boolean equals(Object obj) {
}

@Override
protected Authentication doAuthenticate(Authentication authentication, List requireAssignment, AuthenticationChannel channel, Class focusType) {
String enteredUsername = (String) authentication.getPrincipal();
protected Authentication doAuthenticate(
Authentication authentication,
String enteredUsername,
List requireAssignment, AuthenticationChannel channel, Class focusType) {
// String enteredUsername = (String) authentication.getPrincipal();
LOGGER.trace("Authenticating username '{}'", enteredUsername);

ConnectionEnvironment connEnv = ConnectionEnvironment.create(SchemaConstants.CHANNEL_REST_URI);
Authentication token;
if (authentication instanceof ClusterAuthenticationToken) {
String enteredPassword = (String) authentication.getCredentials();
NodeAuthenticationContext nodeCtx = new NodeAuthenticationContext(null, enteredUsername, enteredPassword);
token = nodeAuthenticator.authenticate(connEnv, nodeCtx);
} else {
if (!(authentication instanceof ClusterAuthenticationToken)) {
LOGGER.error("Unsupported authentication {}", authentication);
throw new AuthenticationServiceException("web.security.provider.unavailable");
}

String enteredPassword = (String) authentication.getCredentials();
NodeAuthenticationContext nodeCtx = new NodeAuthenticationContext(null, enteredUsername, enteredPassword);
Authentication token = nodeAuthenticator.authenticate(connEnv, nodeCtx);

LOGGER.debug("Node '{}' authenticated}", authentication.getPrincipal());
token.setAuthenticated(true);
return token;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,38 +54,41 @@ public Authentication authenticate(Authentication originalAuthentication) throws
}

@Override
public Authentication doAuthenticate(Authentication authentication, List<ObjectReferenceType> requireAssignment,
public Authentication doAuthenticate(
Authentication authentication,
String enteredUsername,
List<ObjectReferenceType> requireAssignment,
AuthenticationChannel channel, Class<? extends FocusType> focusType) throws AuthenticationException {

if (authentication instanceof CorrelationVerificationToken correlationVerificationToken) {
try {
ModuleAuthentication moduleAuthentication = AuthUtil.getProcessingModule();
if (!(moduleAuthentication instanceof CorrelationModuleAuthenticationImpl correlationModuleAuthentication)) {
LOGGER.error("Correlation module authentication is not set");
throw new AuthenticationServiceException("web.security.provider.unavailable");
}

CompleteCorrelationResult correlationResult = correlate(correlationVerificationToken,
determineArchetypeOid(),
correlationModuleAuthentication.getCandidateOids(),
focusType);
ObjectType owner = correlationResult.getOwner();

if (owner != null) {
return createAuthenticationToken(owner, focusType);
}

CandidateOwnersMap ownersMap = correlationResult.getCandidateOwnersMap();
correlationModuleAuthentication.addCandidateOwners(ownersMap);

return authentication;
} catch (Exception e) {
LOGGER.error("Cannot correlate user, {}", e.getMessage(), e);
//TODO what if the user was already authenticated?
if (!(authentication instanceof CorrelationVerificationToken correlationVerificationToken)) {
LOGGER.error("Unsupported authentication {}", authentication);
throw new AuthenticationServiceException("web.security.provider.unavailable");
}

try {
ModuleAuthentication moduleAuthentication = AuthUtil.getProcessingModule();
if (!(moduleAuthentication instanceof CorrelationModuleAuthenticationImpl correlationModuleAuthentication)) {
LOGGER.error("Correlation module authentication is not set");
throw new AuthenticationServiceException("web.security.provider.unavailable");
}

} else {
LOGGER.error("Unsupported authentication {}", authentication);
CompleteCorrelationResult correlationResult = correlate(correlationVerificationToken,
determineArchetypeOid(),
correlationModuleAuthentication.getCandidateOids(),
focusType);
ObjectType owner = correlationResult.getOwner();

if (owner != null) {
return createAuthenticationToken(owner, focusType);
}

CandidateOwnersMap ownersMap = correlationResult.getCandidateOwnersMap();
correlationModuleAuthentication.addCandidateOwners(ownersMap);

return authentication;
} catch (Exception e) {
LOGGER.error("Cannot correlate user, {}", e.getMessage(), e);
throw new AuthenticationServiceException("web.security.provider.unavailable");
}

Expand Down

0 comments on commit 46378d0

Please sign in to comment.