use of com.okta.idx.sdk.api.client.ProceedContext in project okta-idx-java by okta.
the class HomeController method displayIndexOrHomePage.
/**
* Display one of:
* <p>
* a) index page - if the user is not authenticated yet (does not have token response in session).
* b) home page - if the user is authenticated (or) we have obtained a token for the user from the interaction code or otp in callback.
* c) info page - if the user is unauthenticated yet and has received an otp in callback. the info page will ask the user to input
* otp in the original browser to continue with the flow.
* d) error page - if the received state does not correlate with the state in client context or if the callback
* contains error parameters.
* <p>
* where index page refers to the root view with table of contents,
* and home page refers to the view that shows the user profile information along with token information.
*
* @param interactionCode the interaction code from callback (optional)
* @param state the state value from callback (optional)
* @param otp the one time password or verification code (optional)
* @param error the error from callback when interaction_code could not be sent (optional)
* @param errDesc the error_description from callback (optional)
* @param session the http session
* @return the index page view with table of contents or the home page view if we have a token or the info page.
*/
@RequestMapping(value = { "/", "**/callback" }, method = RequestMethod.GET)
public ModelAndView displayIndexOrHomePage(@RequestParam(name = "interaction_code", required = false) final String interactionCode, @RequestParam(name = "state", required = false) final String state, @RequestParam(name = "otp", required = false) final String otp, @RequestParam(name = "error", required = false) final String error, @RequestParam(name = "error_description", required = false) final String errDesc, final HttpSession session) {
ProceedContext proceedContext = Util.getProceedContextFromSession(session);
TokenResponse tokenResponse = (TokenResponse) session.getAttribute("tokenResponse");
// render home page if token is already present in session
if (tokenResponse != null) {
return homeHelper.proceedToHome(tokenResponse, session);
}
// correlate received state with the client context
if ((Strings.hasText(interactionCode) || Strings.hasText(otp)) && proceedContext != null && (Strings.isEmpty(state) || !state.equals(proceedContext.getClientContext().getState()))) {
ModelAndView mav = new ModelAndView("error");
mav.addObject("errors", "Could not correlate client context with the received state value " + state + " in callback");
return mav;
}
AuthenticationResponse authenticationResponse;
// if interaction code is present, exchange it for a token
if (Strings.hasText(interactionCode)) {
authenticationResponse = authenticationWrapper.fetchTokenWithInteractionCode(proceedContext, interactionCode);
return responseHandler.handleKnownTransitions(authenticationResponse, session);
}
// if otp is present, proceed with introspect to finish the flow
if (Strings.hasText(otp)) {
if (proceedContext == null) {
// different browser case
ModelAndView mav = new ModelAndView("info");
mav.addObject("message", "Please enter OTP " + otp + " in the original browser tab to finish the flow.");
return mav;
}
VerifyAuthenticatorOptions verifyAuthenticatorOptions = new VerifyAuthenticatorOptions(otp);
authenticationResponse = authenticationWrapper.verifyAuthenticator(proceedContext, verifyAuthenticatorOptions);
return responseHandler.handleKnownTransitions(authenticationResponse, session);
}
// if error params are present, show error page
if (Strings.hasText(error) || Strings.hasText(errDesc)) {
ModelAndView mav = new ModelAndView("error");
mav.addObject("errors", error + ":" + errDesc);
return mav;
}
// return the root view
return new ModelAndView("index");
}
use of com.okta.idx.sdk.api.client.ProceedContext in project okta-idx-java by okta.
the class HomeController method displayUserActivationPage.
/**
* Activate user with activation token.
*
* @param activationToken the activation token (from email link)
* @param session the http session
* @return the authenticator selection or home page view
*/
@GetMapping(value = "/activate")
public ModelAndView displayUserActivationPage(@RequestParam(name = "token") final String activationToken, final HttpSession session) {
beginUserActivation(session, activationToken);
ProceedContext proceedContext = Util.getProceedContextFromSession(session);
AuthenticationResponse authenticationResponse = authenticationWrapper.introspect(proceedContext.getClientContext());
return responseHandler.handleKnownTransitions(authenticationResponse, session);
}
use of com.okta.idx.sdk.api.client.ProceedContext in project okta-idx-java by okta.
the class HomeController method displaySelectAuthenticatorPage.
/**
* Display the select authenticator page.
*
* @param session the http session
* @param completedAuthenticatorType the last enrolled/verified authenticator type
* @return the select authenticators view.
*/
@GetMapping("/select-authenticator")
public ModelAndView displaySelectAuthenticatorPage(final HttpSession session, @RequestParam(value = "completed", required = false) final String completedAuthenticatorType) {
List<Authenticator> authenticators = (List<Authenticator>) session.getAttribute("authenticators");
if (completedAuthenticatorType != null) {
authenticators.removeIf(authenticator -> authenticator.getLabel().equals(completedAuthenticatorType));
}
TokenResponse tokenResponse = (TokenResponse) session.getAttribute("tokenResponse");
if (tokenResponse != null) {
return homeHelper.proceedToHome(tokenResponse, session);
}
ProceedContext proceedContext = Util.getProceedContextFromSession(session);
boolean canSkip = authenticationWrapper.isSkipAuthenticatorPresent(proceedContext);
ModelAndView modelAndView = new ModelAndView("select-authenticator");
modelAndView.addObject("title", "Select Authenticator");
modelAndView.addObject("canSkip", canSkip);
modelAndView.addObject("authenticators", authenticators);
return modelAndView;
}
use of com.okta.idx.sdk.api.client.ProceedContext in project okta-idx-java by okta.
the class LoginController method selectAuthenticator.
/**
* Handle authenticator selection during authentication.
*
* @param authenticatorType the authenticatorType
* @param session the session
* @param action the submit or cancel action from form post
* @return select authenticator view or select factor view or error view
*/
@PostMapping(value = "/select-authenticator")
public ModelAndView selectAuthenticator(@RequestParam("authenticator-type") final String authenticatorType, @RequestParam(value = "action") final String action, final HttpSession session) {
AuthenticationResponse authenticationResponse = null;
Authenticator foundAuthenticator = null;
ProceedContext proceedContext = Util.getProceedContextFromSession(session);
if ("skip".equals(action)) {
logger.info("Skipping {} authenticator", authenticatorType);
authenticationResponse = idxAuthenticationWrapper.skipAuthenticatorEnrollment(proceedContext);
return responseHandler.handleKnownTransitions(authenticationResponse, session);
}
List<Authenticator> authenticators = (List<Authenticator>) session.getAttribute("authenticators");
if ("webauthn".equals(authenticatorType)) {
ModelAndView modelAndView;
Optional<Authenticator> authenticatorOptional = authenticators.stream().filter(auth -> auth.getType().equals(authenticatorType)).findFirst();
String authId = authenticatorOptional.get().getId();
AuthenticationResponse enrollResponse = idxAuthenticationWrapper.enrollAuthenticator(proceedContext, authId);
Util.updateSession(session, enrollResponse.getProceedContext());
String webauthnCredentialId = enrollResponse.getWebAuthnParams().getWebauthnCredentialId();
if (webauthnCredentialId != null) {
modelAndView = new ModelAndView("select-webauthn-authenticator");
modelAndView.addObject("title", "Select Webauthn Authenticator");
modelAndView.addObject("webauthnCredentialId", webauthnCredentialId);
modelAndView.addObject("challengeData", enrollResponse.getWebAuthnParams().getCurrentAuthenticator().getValue().getContextualData().getChallengeData());
} else {
modelAndView = new ModelAndView("enroll-webauthn-authenticator");
modelAndView.addObject("title", "Enroll Webauthn Authenticator");
modelAndView.addObject("currentAuthenticator", enrollResponse.getWebAuthnParams().getCurrentAuthenticator());
}
return modelAndView;
}
if ("okta_verify".equals(authenticatorType)) {
ModelAndView modelAndView;
Optional<Authenticator> authenticatorOptional = authenticators.stream().filter(auth -> auth.getType().equals(authenticatorType)).findFirst();
Assert.isTrue(authenticatorOptional.isPresent(), "Authenticator not found");
// Looking for QRCODE factor
Optional<Authenticator.Factor> factorOptional = authenticatorOptional.get().getFactors().stream().filter(x -> "QRCODE".equals(x.getLabel())).findFirst();
Assert.isTrue(factorOptional.isPresent(), "Authenticator not found");
authenticationResponse = idxAuthenticationWrapper.selectFactor(proceedContext, factorOptional.get());
Util.setProceedContextForPoll(session, authenticationResponse.getProceedContext());
List<Authenticator.Factor> factors = authenticatorOptional.get().getFactors().stream().filter(x -> !"QRCODE".equals(x.getLabel())).collect(Collectors.toList());
modelAndView = new ModelAndView("setup-okta-verify");
modelAndView.addObject("qrCode", authenticationResponse.getContextualData().getQrcode().getHref());
modelAndView.addObject("channelName", "qrcode");
modelAndView.addObject("factors", factors);
modelAndView.addObject("authenticatorId", authenticatorOptional.get().getId());
modelAndView.addObject("pollTimeout", authenticationResponse.getProceedContext().getRefresh());
return modelAndView;
}
for (Authenticator authenticator : authenticators) {
if (authenticatorType.equals(authenticator.getType())) {
foundAuthenticator = authenticator;
if (foundAuthenticator.getFactors().size() == 1) {
authenticationResponse = idxAuthenticationWrapper.selectAuthenticator(proceedContext, authenticator);
if (authenticationResponse.getContextualData() != null) {
session.setAttribute("totp", authenticationResponse.getContextualData());
} else {
session.removeAttribute("totp");
}
} else {
// user should select the factor in a separate view
ModelAndView modelAndView = new ModelAndView("select-factor");
modelAndView.addObject("title", "Select Factor");
modelAndView.addObject("authenticatorId", foundAuthenticator.getId());
modelAndView.addObject("factors", foundAuthenticator.getFactors());
return modelAndView;
}
}
}
if (responseHandler.needsToShowErrors(authenticationResponse)) {
ModelAndView modelAndView = new ModelAndView("select-authenticator");
modelAndView.addObject("errors", authenticationResponse.getErrors());
return modelAndView;
}
ModelAndView terminalTransition = responseHandler.handleTerminalTransitions(authenticationResponse, session);
if (terminalTransition != null) {
return terminalTransition;
}
switch(authenticationResponse.getAuthenticationStatus()) {
case AWAITING_AUTHENTICATOR_VERIFICATION_DATA:
return responseHandler.verifyForm();
case AWAITING_AUTHENTICATOR_ENROLLMENT:
case AWAITING_AUTHENTICATOR_ENROLLMENT_DATA:
return responseHandler.registerVerifyForm(foundAuthenticator);
case AWAITING_POLL_ENROLLMENT:
return responseHandler.setupOktaVerifyForm(session);
default:
return responseHandler.handleKnownTransitions(authenticationResponse, session);
}
}
use of com.okta.idx.sdk.api.client.ProceedContext in project okta-idx-java by okta.
the class LoginController method poll.
/**
* Handle Okta verify functionality.
*
* @param session the session
* @return the view associated with authentication response.
*/
@PostMapping("/poll")
public ModelAndView poll(final HttpSession session) {
ProceedContext proceedContext = Util.getProceedContextForPoll(session);
if (proceedContext == null) {
proceedContext = Util.getProceedContextFromSession(session);
}
AuthenticationResponse authenticationResponse = idxAuthenticationWrapper.poll(proceedContext);
if (responseHandler.needsToShowErrors(authenticationResponse)) {
ModelAndView modelAndView = new ModelAndView("error");
modelAndView.addObject("errors", authenticationResponse.getErrors());
return modelAndView;
}
return responseHandler.handleKnownTransitions(authenticationResponse, session);
}
Aggregations