Merge pull request #2096 from patriot1burke/master

redirect after post in flow
This commit is contained in:
Bill Burke 2016-01-22 18:40:45 -05:00
commit 1cc359d1d8
4 changed files with 48 additions and 12 deletions

View file

@ -57,6 +57,7 @@ public class AuthenticationProcessor {
protected String flowPath; protected String flowPath;
protected boolean browserFlow; protected boolean browserFlow;
protected BruteForceProtector protector; protected BruteForceProtector protector;
protected boolean oneActionWasSuccessful;
/** /**
* This could be an error message forwarded from another authenticator * This could be an error message forwarded from another authenticator
*/ */
@ -761,6 +762,28 @@ public class AuthenticationProcessor {
return challenge; return challenge;
} }
/**
* Marks that at least one action was successful
*
*/
public void setActionSuccessful() {
oneActionWasSuccessful = true;
}
public Response checkWasSuccessfulBrowserAction() {
if (oneActionWasSuccessful && isBrowserFlow()) {
// redirect to non-action url so browser refresh button works without reposting past data
String code = generateCode();
URI redirect = LoginActionsService.loginActionsBaseUrl(getUriInfo())
.path(flowPath)
.queryParam(OAuth2Constants.CODE, code).build(getRealm().getName());
return Response.status(302).location(redirect).build();
} else {
return null;
}
}
public void attachSession() { public void attachSession() {
String username = clientSession.getAuthenticatedUser().getUsername(); String username = clientSession.getAuthenticatedUser().getUsername();
String attemptedUsername = clientSession.getNote(AbstractUsernameFormAuthenticator.ATTEMPTED_USERNAME); String attemptedUsername = clientSession.getNote(AbstractUsernameFormAuthenticator.ATTEMPTED_USERNAME);

View file

@ -68,6 +68,10 @@ public class DefaultAuthenticationFlow implements AuthenticationFlow {
Response response = processResult(result); Response response = processResult(result);
if (response == null) { if (response == null) {
processor.getClientSession().removeNote(AuthenticationProcessor.CURRENT_AUTHENTICATION_EXECUTION); processor.getClientSession().removeNote(AuthenticationProcessor.CURRENT_AUTHENTICATION_EXECUTION);
if (result.status == FlowStatus.SUCCESS) {
// we do this so that flow can redirect to a non-action URL
processor.setActionSuccessful();
}
return processFlow(); return processFlow();
} else return response; } else return response;
} }
@ -153,6 +157,10 @@ public class DefaultAuthenticationFlow implements AuthenticationFlow {
} }
} }
} }
// skip if action as successful already
Response redirect = processor.checkWasSuccessfulBrowserAction();
if (redirect != null) return redirect;
AuthenticationProcessor.Result context = processor.createAuthenticatorContext(model, authenticator, executions); AuthenticationProcessor.Result context = processor.createAuthenticatorContext(model, authenticator, executions);
logger.debug("invoke authenticator.authenticate"); logger.debug("invoke authenticator.authenticate");
authenticator.authenticate(context); authenticator.authenticate(context);

View file

@ -221,6 +221,7 @@ public class FormAuthenticationFlow implements AuthenticationFlow {
} }
processor.getClientSession().setExecutionStatus(actionExecution, ClientSessionModel.ExecutionStatus.SUCCESS); processor.getClientSession().setExecutionStatus(actionExecution, ClientSessionModel.ExecutionStatus.SUCCESS);
processor.getClientSession().removeNote(AuthenticationProcessor.CURRENT_AUTHENTICATION_EXECUTION); processor.getClientSession().removeNote(AuthenticationProcessor.CURRENT_AUTHENTICATION_EXECUTION);
processor.setActionSuccessful();
return null; return null;
} }

View file

@ -812,15 +812,16 @@ public class LoginActionsService {
final ClientSessionCode clientCode = checks.clientCode; final ClientSessionCode clientCode = checks.clientCode;
final ClientSessionModel clientSession = clientCode.getClientSession(); final ClientSessionModel clientSession = clientCode.getClientSession();
if (clientSession.getUserSession() == null) { final UserSessionModel userSession = clientSession.getUserSession();
if (userSession == null) {
logger.userSessionNull(); logger.userSessionNull();
event.error(Errors.USER_SESSION_NOT_FOUND); event.error(Errors.USER_SESSION_NOT_FOUND);
throw new WebApplicationException(ErrorPage.error(session, Messages.SESSION_NOT_ACTIVE)); throw new WebApplicationException(ErrorPage.error(session, Messages.SESSION_NOT_ACTIVE));
} }
if (action == null && clientSession.getUserSession() != null) { // do next required action only if user is already authenticated if (action == null && userSession != null) { // do next required action only if user is already authenticated
initEvent(clientSession); initEvent(clientSession);
event.event(EventType.LOGIN); event.event(EventType.LOGIN);
return AuthenticationManager.nextActionAfterAuthentication(session, clientSession.getUserSession(), clientSession, clientConnection, request, uriInfo, event); return AuthenticationManager.nextActionAfterAuthentication(session, userSession, clientSession, clientConnection, request, uriInfo, event);
} }
if (!action.equals(clientSession.getNote(AuthenticationManager.CURRENT_REQUIRED_ACTION))) { if (!action.equals(clientSession.getNote(AuthenticationManager.CURRENT_REQUIRED_ACTION))) {
@ -841,7 +842,7 @@ public class LoginActionsService {
event.event(EventType.CUSTOM_REQUIRED_ACTION); event.event(EventType.CUSTOM_REQUIRED_ACTION);
RequiredActionContextResult context = new RequiredActionContextResult(clientSession.getUserSession(), clientSession, realm, event, session, request, clientSession.getUserSession().getUser(), factory) { RequiredActionContextResult context = new RequiredActionContextResult(userSession, clientSession, realm, event, session, request, userSession.getUser(), factory) {
@Override @Override
public void ignore() { public void ignore() {
throw new RuntimeException("Cannot call ignore within processAction()"); throw new RuntimeException("Cannot call ignore within processAction()");
@ -850,16 +851,19 @@ public class LoginActionsService {
provider.processAction(context); provider.processAction(context);
if (context.getStatus() == RequiredActionContext.Status.SUCCESS) { if (context.getStatus() == RequiredActionContext.Status.SUCCESS) {
event.clone().success(); event.clone().success();
// do both
clientSession.removeRequiredAction(factory.getId());
clientSession.getUserSession().getUser().removeRequiredAction(factory.getId());
clientSession.removeNote(AuthenticationManager.CURRENT_REQUIRED_ACTION);
// redirect to a generic code URI so that browser refresh will work
//return redirectToRequiredActions(code);
event.removeDetail(Details.CUSTOM_REQUIRED_ACTION);
initEvent(clientSession); initEvent(clientSession);
event.event(EventType.LOGIN); event.event(EventType.LOGIN);
return AuthenticationManager.nextActionAfterAuthentication(session, clientSession.getUserSession(), clientSession, clientConnection, request, uriInfo, event); clientSession.removeRequiredAction(factory.getId());
userSession.getUser().removeRequiredAction(factory.getId());
clientSession.removeNote(AuthenticationManager.CURRENT_REQUIRED_ACTION);
if (AuthenticationManager.isActionRequired(session, userSession, clientSession, clientConnection, request, uriInfo, event)) {
// redirect to a generic code URI so that browser refresh will work
return redirectToRequiredActions(code);
} else {
return AuthenticationManager.finishedRequiredActions(session, userSession, clientSession, clientConnection, request, uriInfo, event);
}
} }
if (context.getStatus() == RequiredActionContext.Status.CHALLENGE) { if (context.getStatus() == RequiredActionContext.Status.CHALLENGE) {
return context.getChallenge(); return context.getChallenge();