Skip to content

Commit

Permalink
another fixes to correctly handle authentication flow
Browse files Browse the repository at this point in the history
  • Loading branch information
katkav committed Feb 21, 2023
1 parent c86781e commit 5f5aabf
Show file tree
Hide file tree
Showing 14 changed files with 106 additions and 73 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import org.apache.wicket.ajax.attributes.AjaxRequestAttributes;
import org.apache.wicket.ajax.attributes.ThrottlingSettings;
import org.apache.wicket.ajax.form.AjaxFormComponentUpdatingBehavior;
import org.apache.wicket.feedback.FeedbackMessage;
import org.apache.wicket.markup.html.form.FormComponent;
import org.apache.wicket.markup.html.form.PasswordTextField;
import org.apache.wicket.markup.html.form.TextField;
Expand All @@ -29,6 +30,8 @@
import org.jetbrains.annotations.NotNull;

import java.time.Duration;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

public class PasswordHintPanel extends InputPanel {
Expand Down Expand Up @@ -60,6 +63,15 @@ private void initLayout() {
add(hint);
}

public List<FeedbackMessage> collectHintFeedbackMessages() {
List<FeedbackMessage> feedbackMessages = new ArrayList<>();
FormComponent hintInput = getBaseFormComponent();
if (hintInput.getFeedbackMessages() != null && hintInput.getFeedbackMessages().hasMessage(0)) {
feedbackMessages.addAll(hintInput.getFeedbackMessages().messages(null));
}
return feedbackMessages;
}

public FormComponent getBaseFormComponent() {
return (FormComponent) get(ID_HINT);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
import com.evolveum.midpoint.xml.ns._public.common.common_3.FocusType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.UserType;

import org.apache.wicket.markup.html.pages.RedirectPage;
import org.apache.wicket.model.IModel;
import org.apache.wicket.model.LoadableDetachableModel;

Expand Down Expand Up @@ -106,9 +107,8 @@ protected void finishChangePassword(final OperationResult result, AjaxRequestTar
}

showResult(result);
target.add(getFeedbackPanel());
AuthUtil.clearMidpointAuthentication();
setResponsePage(getMidpointApplication().getHomePage());
setResponsePage(new RedirectPage("/"));
} else if (showFeedback) {
showResult(result);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ public PageSecurityQuestions() {

@Override
protected void initModels() {
answerModel = () -> generateAnswer();
answerModel = Model.of();
userModel = new LoadableDetachableModel<>() {
@Override
protected UserType load() {
Expand Down Expand Up @@ -167,6 +167,7 @@ protected void populateItem(ListItem<SecurityQuestionDto> item) {

@Override
protected void onUpdate(AjaxRequestTarget target) {
answerModel.setObject(generateAnswer());
target.add(getHiddenAnswer());
}
});
Expand All @@ -176,20 +177,22 @@ protected void onUpdate(AjaxRequestTarget target) {
questionsView.setOutputMarkupId(true);
questionsContainer.add(questionsView);

AjaxButton back = new AjaxButton(ID_BACK_2_BUTTON) {

private static final long serialVersionUID = 1L;

@Override
public void onClick(AjaxRequestTarget target) {
userModel.detach();
questionsModel.setObject(new ArrayList<SecurityQuestionDto>());
getHiddenUsername().getModel().setObject(null);
getHiddenAnswer().getModel().setObject(null);
target.add(getMainForm());
}
};
questionsContainer.add(back);
questionsContainer.add(createBackButton(ID_BACK_2_BUTTON));
// AjaxButton back = new AjaxButton(ID_BACK_2_BUTTON) {
//
// private static final long serialVersionUID = 1L;
//
// @Override
// public void onClick(AjaxRequestTarget target) {
// userModel.detach();
// questionsModel.setObject(new ArrayList<SecurityQuestionDto>());
// getHiddenUsername().getModel().setObject(null);
// getHiddenAnswer().getModel().setObject(null);
// target.add(getMainForm());
// }
// };
// questionsContainer.add(back);
}

private String generateAnswer() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -136,10 +136,6 @@ public boolean isEnabled() {
PasswordPanel passwordPanel = new PasswordPanel(ID_PASSWORD_PANEL, Model.of(newPasswordValue), false, true, getModelObject().asPrismObject()) {
private static final long serialVersionUID = 1L;

// @Override
// protected <F extends FocusType> ValuePolicyType getValuePolicy(PrismObject<F> object) {
// return null;//getModelObject().getFocusPolicy();
// }

@Override
protected void updatePasswordValidation(AjaxRequestTarget target) {
Expand Down Expand Up @@ -187,6 +183,7 @@ protected List<StringLimitationResult> load() {
@Override
public void onError(AjaxRequestTarget target) {
List<FeedbackMessage> feedbackMessages = passwordPanel.collectPasswordFieldsFeedbackMessages();
feedbackMessages.addAll(hint.collectHintFeedbackMessages());
if (CollectionUtils.isNotEmpty(feedbackMessages)) {
StringBuilder sb = new StringBuilder();
feedbackMessages.forEach(m -> sb.append(m.getMessage()).append("\n"));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@
*/
package com.evolveum.midpoint.authentication.impl.filter;

import com.evolveum.midpoint.authentication.api.util.AuthUtil;
import com.evolveum.midpoint.authentication.impl.module.authentication.token.AttributeVerificationToken;
import com.evolveum.midpoint.model.api.authentication.GuiProfiledPrincipal;
import com.evolveum.midpoint.prism.path.ItemPath;

import com.evolveum.midpoint.security.api.SecurityUtil;
Expand Down Expand Up @@ -40,8 +42,10 @@ protected AbstractAuthenticationToken createAuthenticationToken(Map<ItemPath, St
@Override
protected void validateRequest(HttpServletRequest request) {
super.validateRequest(request);

Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
if (authentication == null || authentication.getPrincipal() == null) {
GuiProfiledPrincipal principal = AuthUtil.getPrincipalUser(authentication);
if (principal == null) {
throw new AuthenticationServiceException(
"Authentication method not supported: " + request.getMethod());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,14 @@
*/
package com.evolveum.midpoint.authentication.impl.filter;

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

import com.evolveum.midpoint.authentication.impl.module.authentication.token.HintAuthenticationToken;
import com.evolveum.midpoint.model.api.authentication.GuiProfiledPrincipal;

import com.evolveum.midpoint.prism.path.ItemPath;

import org.springframework.security.authentication.AbstractAuthenticationToken;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.AuthenticationServiceException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
Expand All @@ -17,55 +25,36 @@

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Map;

public class HintAuthenticationFilter extends UsernamePasswordAuthenticationFilter {
public class HintAuthenticationFilter extends MidpointFocusVerificationFilter {

private static final AntPathRequestMatcher DEFAULT_ANT_PATH_REQUEST_MATCHER = new AntPathRequestMatcher("/hint", "POST");
private static final String SPRING_SECURITY_FORM_ATTRIBUTE_VALUES_KEY = "attributeValues";

public HintAuthenticationFilter() {
super();
super(DEFAULT_ANT_PATH_REQUEST_MATCHER);
}

public HintAuthenticationFilter(AuthenticationManager authenticationManager) {
super(authenticationManager);
super(DEFAULT_ANT_PATH_REQUEST_MATCHER, authenticationManager);
}

public Authentication attemptAuthentication(
HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {
if (!request.getMethod().equals("POST")) {
@Override
protected void validateRequest(HttpServletRequest request) {
super.validateRequest(request);
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
GuiProfiledPrincipal principal = AuthUtil.getPrincipalUser(authentication);
if (principal == null) {
throw new AuthenticationServiceException(
"Authentication method not supported: " + request.getMethod());
}
}

@Override
protected AbstractAuthenticationToken createAuthenticationToken(Map<ItemPath, String> attributeValues) {
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
if (authentication == null || authentication.getPrincipal() == null) {
return authentication;
}

// Map<ItemPath, String> attributeValues = obtainAttributeValues(request);
UsernamePasswordAuthenticationToken authRequest =
new UsernamePasswordAuthenticationToken(authentication.getPrincipal(), authentication.getCredentials());

return this.getAuthenticationManager().authenticate(authRequest);
return new HintAuthenticationToken(authentication.getPrincipal(), authentication.getCredentials());
}

// protected Map<ItemPath, String> obtainAttributeValues(HttpServletRequest request) {
// String attrValuesString = request.getParameter(SPRING_SECURITY_FORM_ATTRIBUTE_VALUES_KEY);
// if (StringUtils.isEmpty(attrValuesString)) {
// return null;
// }
//
// JSONArray attributeValuesArray = new JSONArray(attrValuesString);
// Map<ItemPath, String> attributeValuesMap = new HashMap<>();
// for (int i = 0; i < attributeValuesArray.length(); i++) {
// JSONObject entry = attributeValuesArray.getJSONObject(i);
//
// ItemPath path = ItemPath.create(entry.get(AuthConstants.ATTR_VERIFICATION_J_PATH));
// String value = entry.getString(AuthConstants.ATTR_VERIFICATION_J_VALUE);
// attributeValuesMap.put(path, value);
// }
// return attributeValuesMap;
// }

}
Original file line number Diff line number Diff line change
Expand Up @@ -235,9 +235,6 @@ private int initNewAuthenticationToken(AuthenticationWrapper authWrapper, HttpSe
}

private boolean needCreateNewAuthenticationToken(MidpointAuthentication mpAuthentication, int indexOfActualProcessingModule, HttpServletRequest httpRequest) {
if (mpAuthentication != null && mpAuthentication.getPrincipal() instanceof MidPointPrincipal && ((MidPointPrincipal) mpAuthentication.getPrincipal()).getFocus() != null) {
return false;
}
return AuthSequenceUtil.isClusterSequence(httpRequest)
|| needRestartAuthFlow(indexOfActualProcessingModule, mpAuthentication);
}
Expand Down Expand Up @@ -366,7 +363,20 @@ private boolean isPermitAllPage(HttpServletRequest request) {

private boolean needRestartAuthFlow(int indexOfProcessingModule, MidpointAuthentication mpAuthentication) {
// if index == -1 indicate restart authentication flow
return mpAuthentication == null || !mpAuthentication.isMerged() || indexOfProcessingModule == MidpointAuthentication.NO_MODULE_FOUND_INDEX;
return !isIdentifiedFocus(mpAuthentication) || indexOfProcessingModule == MidpointAuthentication.NO_MODULE_FOUND_INDEX; // || mpAuthentication == null || !mpAuthentication.isMerged();
}

private boolean isIdentifiedFocus(MidpointAuthentication mpAuthentication) {
if (mpAuthentication == null) {
return false;
}

Object principal = mpAuthentication.getPrincipal();
if (!(principal instanceof MidPointPrincipal)) {
return false;
}

return ((MidPointPrincipal) principal).getFocus() != null;
}

private int restartAuthFlow(HttpServletRequest httpRequest, AuthenticationWrapper authWrapper) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
package com.evolveum.midpoint.authentication.impl.filter;

import com.evolveum.midpoint.authentication.api.util.AuthConstants;
import com.evolveum.midpoint.authentication.api.util.AuthUtil;
import com.evolveum.midpoint.authentication.impl.module.authentication.token.FocusVerificationToken;
import com.evolveum.midpoint.prism.PrismContext;
import com.evolveum.midpoint.prism.path.ItemPath;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,16 +28,12 @@ public AttributeVerificationToken(MidPointPrincipal principal, Map<ItemPath, Str

@Override
public Object getCredentials() {
return null;
return attributeValues;
}

@Override
public Object getPrincipal() {
return principal;
}

@Override
public Object getDetails() {
return attributeValues;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/*
* Copyright (C) 2023 Evolveum and contributors
*
* This work is dual-licensed under the Apache License 2.0
* and European Union Public License. See LICENSE file for details.
*/

package com.evolveum.midpoint.authentication.impl.module.authentication.token;

import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.GrantedAuthority;

import java.util.Collection;

public class HintAuthenticationToken extends UsernamePasswordAuthenticationToken {
public HintAuthenticationToken(Object principal, Object credentials) {
super(principal, credentials);
}

public HintAuthenticationToken(Object principal, Object credentials, Collection<? extends GrantedAuthority> authorities) {
super(principal, credentials, authorities);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,15 @@
import com.evolveum.midpoint.authentication.impl.entry.point.WicketLoginUrlAuthenticationEntryPoint;
import com.evolveum.midpoint.authentication.impl.filter.AttributeVerificationAuthenticationFilter;
import com.evolveum.midpoint.authentication.impl.filter.HintAuthenticationFilter;
import com.evolveum.midpoint.authentication.impl.filter.configurers.MidpointAttributeConfigurer;
import com.evolveum.midpoint.authentication.impl.filter.configurers.MidpointExceptionHandlingConfigurer;
import com.evolveum.midpoint.authentication.impl.filter.configurers.MidpointFormLoginConfigurer;
import com.evolveum.midpoint.authentication.impl.handler.MidPointAuthenticationSuccessHandler;
import com.evolveum.midpoint.authentication.impl.handler.MidpointAuthenticationFailureHandler;
import com.evolveum.midpoint.authentication.impl.module.configuration.LoginFormModuleWebSecurityConfiguration;

import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

public class HintModuleWebSecurityConfigurer<C extends LoginFormModuleWebSecurityConfiguration> extends ModuleWebSecurityConfigurer<C> {

Expand All @@ -27,8 +29,9 @@ public HintModuleWebSecurityConfigurer(C configuration) {
@Override
protected void configure(HttpSecurity http) throws Exception {
super.configure(http);
HintAuthenticationFilter hintFilter = new HintAuthenticationFilter();
http.antMatcher(AuthUtil.stripEndingSlashes(getPrefix()) + "/**");
getOrApply(http, new MidpointFormLoginConfigurer<>(new HintAuthenticationFilter()))
getOrApply(http, new MidpointAttributeConfigurer<>(hintFilter))
.loginPage("/hint")
.loginProcessingUrl(AuthUtil.stripEndingSlashes(getPrefix()) + "/spring_security_login")
.failureHandler(new MidpointAuthenticationFailureHandler())
Expand All @@ -42,5 +45,6 @@ protected void configure(HttpSecurity http) throws Exception {
.invalidateHttpSession(true)
.deleteCookies("JSESSIONID")
.logoutSuccessHandler(createLogoutHandler());
http.addFilterBefore(hintFilter, UsernamePasswordAuthenticationFilter.class);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ protected Authentication internalAuthentication(Authentication authentication, L
try {
Authentication token;
if (authentication instanceof AttributeVerificationToken) {
Map<ItemPath, String> attrValuesMap = (Map<ItemPath, String>) authentication.getDetails();
Map<ItemPath, String> attrValuesMap = (Map<ItemPath, String>) authentication.getCredentials();
AttributeVerificationAuthenticationContext authContext = new AttributeVerificationAuthenticationContext(enteredUsername,
focusType, attrValuesMap, requireAssignment);
if (channel != null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,15 +53,8 @@ protected Authentication internalAuthentication(Authentication authentication, L
if (authentication.isAuthenticated() && authentication.getPrincipal() instanceof GuiProfiledPrincipal) {
return authentication;
}
// if (!(authentication.getPrincipal() instanceof MidPointPrincipal)) {
// return authentication;
// }
// authentication.getPrincipal()
// String enteredUsername = ((MidPointPrincipal) authentication.getPrincipal()).getUsername();
// LOGGER.trace("Authenticating username '{}'", enteredUsername);

ConnectionEnvironment connEnv = createEnvironment(channel);
// return new UsernamePasswordAuthenticationToken("administrator", "5ecr3t");

try {
Authentication token;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

import com.evolveum.midpoint.authentication.api.AuthenticationChannel;
import com.evolveum.midpoint.authentication.api.config.AuthenticationEvaluator;
import com.evolveum.midpoint.authentication.impl.module.authentication.token.HintAuthenticationToken;
import com.evolveum.midpoint.model.api.authentication.GuiProfiledPrincipal;
import com.evolveum.midpoint.model.api.context.PasswordAuthenticationContext;
import com.evolveum.midpoint.security.api.ConnectionEnvironment;
Expand Down Expand Up @@ -66,7 +67,7 @@ protected Authentication createNewAuthenticationToken(Authentication actualAuthe

@Override
public boolean supports(Class<?> authentication) {
return UsernamePasswordAuthenticationToken.class.equals(authentication);
return HintAuthenticationToken.class.equals(authentication);
}

// @Override
Expand Down

0 comments on commit 5f5aabf

Please sign in to comment.