Search in sources :

Example 6 with ProceedContext

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");
}
Also used : VerifyAuthenticatorOptions(com.okta.idx.sdk.api.model.VerifyAuthenticatorOptions) TokenResponse(com.okta.idx.sdk.api.response.TokenResponse) ModelAndView(org.springframework.web.servlet.ModelAndView) AuthenticationResponse(com.okta.idx.sdk.api.response.AuthenticationResponse) ProceedContext(com.okta.idx.sdk.api.client.ProceedContext) RequestMapping(org.springframework.web.bind.annotation.RequestMapping)

Example 7 with ProceedContext

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);
}
Also used : AuthenticationResponse(com.okta.idx.sdk.api.response.AuthenticationResponse) ProceedContext(com.okta.idx.sdk.api.client.ProceedContext) GetMapping(org.springframework.web.bind.annotation.GetMapping)

Example 8 with ProceedContext

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;
}
Also used : TokenResponse(com.okta.idx.sdk.api.response.TokenResponse) ModelAndView(org.springframework.web.servlet.ModelAndView) List(java.util.List) LinkedList(java.util.LinkedList) Authenticator(com.okta.idx.sdk.api.client.Authenticator) ProceedContext(com.okta.idx.sdk.api.client.ProceedContext) GetMapping(org.springframework.web.bind.annotation.GetMapping)

Example 9 with ProceedContext

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);
    }
}
Also used : RequestParam(org.springframework.web.bind.annotation.RequestParam) Arrays(java.util.Arrays) Qrcode(com.okta.idx.sdk.api.model.Qrcode) ContextualData(com.okta.idx.sdk.api.model.ContextualData) Util(com.okta.spring.example.helpers.Util) AuthenticationResponse(com.okta.idx.sdk.api.response.AuthenticationResponse) LoggerFactory(org.slf4j.LoggerFactory) Autowired(org.springframework.beans.factory.annotation.Autowired) Controller(org.springframework.stereotype.Controller) Authenticator(com.okta.idx.sdk.api.client.Authenticator) UserProfile(com.okta.idx.sdk.api.model.UserProfile) ResponseHandler(com.okta.spring.example.helpers.ResponseHandler) RequestBody(org.springframework.web.bind.annotation.RequestBody) ProceedContext(com.okta.idx.sdk.api.client.ProceedContext) IDXAuthenticationWrapper(com.okta.idx.sdk.api.client.IDXAuthenticationWrapper) VerifyChannelDataOptions(com.okta.idx.sdk.api.model.VerifyChannelDataOptions) PollResults(com.okta.spring.example.helpers.PollResults) GetMapping(org.springframework.web.bind.annotation.GetMapping) VerifyAuthenticatorOptions(com.okta.idx.sdk.api.model.VerifyAuthenticatorOptions) HttpSession(javax.servlet.http.HttpSession) PostMapping(org.springframework.web.bind.annotation.PostMapping) Strings(com.okta.commons.lang.Strings) VerifyAuthenticatorAnswer(com.okta.idx.sdk.api.model.VerifyAuthenticatorAnswer) Assert(com.okta.commons.lang.Assert) Logger(org.slf4j.Logger) FormValue(com.okta.idx.sdk.api.model.FormValue) AuthenticationOptions(com.okta.idx.sdk.api.model.AuthenticationOptions) AuthenticationStatus(com.okta.idx.sdk.api.model.AuthenticationStatus) ResponseBody(org.springframework.web.bind.annotation.ResponseBody) Collectors(java.util.stream.Collectors) WebAuthnRequest(com.okta.idx.sdk.api.request.WebAuthnRequest) ModelAndView(org.springframework.web.servlet.ModelAndView) List(java.util.List) Optional(java.util.Optional) ModelAndView(org.springframework.web.servlet.ModelAndView) List(java.util.List) AuthenticationResponse(com.okta.idx.sdk.api.response.AuthenticationResponse) Authenticator(com.okta.idx.sdk.api.client.Authenticator) ProceedContext(com.okta.idx.sdk.api.client.ProceedContext) PostMapping(org.springframework.web.bind.annotation.PostMapping)

Example 10 with ProceedContext

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);
}
Also used : ModelAndView(org.springframework.web.servlet.ModelAndView) AuthenticationResponse(com.okta.idx.sdk.api.response.AuthenticationResponse) ProceedContext(com.okta.idx.sdk.api.client.ProceedContext) PostMapping(org.springframework.web.bind.annotation.PostMapping)

Aggregations

ProceedContext (com.okta.idx.sdk.api.client.ProceedContext)16 AuthenticationResponse (com.okta.idx.sdk.api.response.AuthenticationResponse)15 ModelAndView (org.springframework.web.servlet.ModelAndView)13 PostMapping (org.springframework.web.bind.annotation.PostMapping)12 VerifyAuthenticatorOptions (com.okta.idx.sdk.api.model.VerifyAuthenticatorOptions)6 GetMapping (org.springframework.web.bind.annotation.GetMapping)6 Authenticator (com.okta.idx.sdk.api.client.Authenticator)5 VerifyChannelDataOptions (com.okta.idx.sdk.api.model.VerifyChannelDataOptions)5 List (java.util.List)5 ContextualData (com.okta.idx.sdk.api.model.ContextualData)4 VerifyAuthenticatorAnswer (com.okta.idx.sdk.api.model.VerifyAuthenticatorAnswer)4 PollResults (com.okta.spring.example.helpers.PollResults)4 ResponseBody (org.springframework.web.bind.annotation.ResponseBody)4 Assert (com.okta.commons.lang.Assert)3 Strings (com.okta.commons.lang.Strings)3 IDXAuthenticationWrapper (com.okta.idx.sdk.api.client.IDXAuthenticationWrapper)3 AuthenticationOptions (com.okta.idx.sdk.api.model.AuthenticationOptions)3 AuthenticationStatus (com.okta.idx.sdk.api.model.AuthenticationStatus)3 FormValue (com.okta.idx.sdk.api.model.FormValue)3 Qrcode (com.okta.idx.sdk.api.model.Qrcode)3