private ClientSessionCode parseClientSessionCode(String code) { ClientSessionCode clientCode = ClientSessionCode.parse(code, this.session, this.realm); if (clientCode != null && clientCode.isValid(AUTHENTICATE.name(), ClientSessionCode.ActionType.LOGIN)) { ClientSessionModel clientSession = clientCode.getClientSession(); if (clientSession != null) { ClientModel client = clientSession.getClient(); if (client == null) { throw new IdentityBrokerException("Invalid client"); } logger.debugf("Got authorization code from client [%s].", client.getClientId()); } logger.debugf("Authorization code is valid."); return clientCode; } throw new IdentityBrokerException( "Invalid code, please login again through your application."); }
@Path("email-verification") @GET public Response emailVerification( @QueryParam("code") String code, @QueryParam("key") String key) { event.event(EventType.VERIFY_EMAIL); if (key != null) { Checks checks = new Checks(); if (!checks.verifyCode(key, ClientSessionModel.Action.VERIFY_EMAIL.name())) { return checks.response; } ClientSessionCode accessCode = checks.clientCode; ClientSessionModel clientSession = accessCode.getClientSession(); UserSessionModel userSession = clientSession.getUserSession(); UserModel user = userSession.getUser(); initEvent(clientSession); user.setEmailVerified(true); user.removeRequiredAction(RequiredAction.VERIFY_EMAIL); event.event(EventType.VERIFY_EMAIL).detail(Details.EMAIL, user.getEmail()).success(); String actionCookieValue = getActionCookie(); if (actionCookieValue == null || !actionCookieValue.equals(userSession.getId())) { session.sessions().removeClientSession(realm, clientSession); return session .getProvider(LoginFormsProvider.class) .setSuccess(Messages.EMAIL_VERIFIED) .createInfoPage(); } event = event.clone().removeDetail(Details.EMAIL).event(EventType.LOGIN); return AuthenticationManager.nextActionAfterAuthentication( session, userSession, clientSession, clientConnection, request, uriInfo, event); } else { Checks checks = new Checks(); if (!checks.verifyCode(code, ClientSessionModel.Action.VERIFY_EMAIL.name())) { return checks.response; } ClientSessionCode accessCode = checks.clientCode; ClientSessionModel clientSession = accessCode.getClientSession(); UserSessionModel userSession = clientSession.getUserSession(); initEvent(clientSession); createActionCookie(realm, uriInfo, clientConnection, userSession.getId()); return session .getProvider(LoginFormsProvider.class) .setClientSessionCode(accessCode.getCode()) .setUser(userSession.getUser()) .createResponse(RequiredAction.VERIFY_EMAIL); } }
/** * Send a update account email to the user * * <p>An email contains a link the user can click to perform a set of required actions. The * redirectUri and clientId parameters are optional. The default for the redirect is the account * client. * * @param id User is * @param redirectUri Redirect uri * @param clientId Client id * @param actions required actions the user needs to complete * @return */ @Path("{id}/execute-actions-email") @PUT @Consumes(MediaType.APPLICATION_JSON) public Response executeActionsEmail( @PathParam("id") String id, @QueryParam(OIDCLoginProtocol.REDIRECT_URI_PARAM) String redirectUri, @QueryParam(OIDCLoginProtocol.CLIENT_ID_PARAM) String clientId, List<String> actions) { auth.requireManage(); UserModel user = session.users().getUserById(id, realm); if (user == null) { return ErrorResponse.error("User not found", Response.Status.NOT_FOUND); } if (user.getEmail() == null) { return ErrorResponse.error("User email missing", Response.Status.BAD_REQUEST); } ClientSessionModel clientSession = createClientSession(user, redirectUri, clientId); for (String action : actions) { clientSession.addRequiredAction(action); } ClientSessionCode accessCode = new ClientSessionCode(realm, clientSession); accessCode.setAction(ClientSessionModel.Action.EXECUTE_ACTIONS.name()); try { UriBuilder builder = Urls.executeActionsBuilder(uriInfo.getBaseUri()); builder.queryParam("key", accessCode.getCode()); String link = builder.build(realm.getName()).toString(); long expiration = TimeUnit.SECONDS.toMinutes(realm.getAccessCodeLifespanUserAction()); this.session .getProvider(EmailTemplateProvider.class) .setRealm(realm) .setUser(user) .sendExecuteActions(link, expiration); // audit.user(user).detail(Details.EMAIL, user.getEmail()).detail(Details.CODE_ID, // accessCode.getCodeId()).success(); adminEvent.operation(OperationType.ACTION).resourcePath(uriInfo).success(); return Response.ok().build(); } catch (EmailException e) { logger.failedToSendActionsEmail(e); return ErrorResponse.error( "Failed to send execute actions email", Response.Status.INTERNAL_SERVER_ERROR); } }
/** * URL called after login page. YOU SHOULD NEVER INVOKE THIS DIRECTLY! * * @param code * @return */ @Path(AUTHENTICATE_PATH) @POST public Response authenticateForm( @QueryParam("code") String code, @QueryParam("execution") String execution) { event.event(EventType.LOGIN); Checks checks = new Checks(); if (!checks.verifyCode(code, ClientSessionModel.Action.AUTHENTICATE.name())) { return checks.response; } final ClientSessionCode clientCode = checks.clientCode; final ClientSessionModel clientSession = clientCode.getClientSession(); return processAuthentication(execution, clientSession, null); }
protected Response resetCredentials(String code, String execution) { event.event(EventType.RESET_PASSWORD); Checks checks = new Checks(); if (!checks.verifyCode(code, ClientSessionModel.Action.AUTHENTICATE.name())) { return checks.response; } final ClientSessionCode clientCode = checks.clientCode; final ClientSessionModel clientSession = clientCode.getClientSession(); if (!realm.isResetPasswordAllowed()) { event.client(clientCode.getClientSession().getClient()); event.error(Errors.NOT_ALLOWED); return ErrorPage.error(session, Messages.RESET_CREDENTIAL_NOT_ALLOWED); } return processResetCredentials(execution, clientSession, null); }
boolean verifyCode(String code, String requiredAction) { if (!verifyCode(code)) { return false; } else if (!clientCode.isValidAction(requiredAction)) { event.client(clientCode.getClientSession().getClient()); event.error(Errors.INVALID_CODE); response = ErrorPage.error(session, Messages.INVALID_CODE); return false; } else if (!clientCode.isActionActive(requiredAction)) { event.client(clientCode.getClientSession().getClient()); event.clone().error(Errors.EXPIRED_CODE); if (clientCode .getClientSession() .getAction() .equals(ClientSessionModel.Action.AUTHENTICATE.name())) { AuthenticationProcessor.resetFlow(clientCode.getClientSession()); response = processAuthentication(null, clientCode.getClientSession(), Messages.LOGIN_TIMEOUT); return false; } response = ErrorPage.error(session, Messages.EXPIRED_CODE); return false; } else { return true; } }
@Override public Response authenticated(UserSessionModel userSession, ClientSessionCode accessCode) { ClientSessionModel clientSession = accessCode.getClientSession(); setupResponseTypeAndMode(clientSession); String redirect = clientSession.getRedirectUri(); OIDCRedirectUriBuilder redirectUri = OIDCRedirectUriBuilder.fromUri(redirect, responseMode); String state = clientSession.getNote(OIDCLoginProtocol.STATE_PARAM); logger.debugv("redirectAccessCode: state: {0}", state); if (state != null) redirectUri.addParam(OAuth2Constants.STATE, state); // Standard or hybrid flow if (responseType.hasResponseType(OIDCResponseType.CODE)) { accessCode.setAction(ClientSessionModel.Action.CODE_TO_TOKEN.name()); redirectUri.addParam(OAuth2Constants.CODE, accessCode.getCode()); } // Implicit or hybrid flow if (responseType.isImplicitOrHybridFlow()) { TokenManager tokenManager = new TokenManager(); AccessTokenResponse res = tokenManager .responseBuilder( realm, clientSession.getClient(), event, session, userSession, clientSession) .generateAccessToken() .generateIDToken() .build(); if (responseType.hasResponseType(OIDCResponseType.ID_TOKEN)) { redirectUri.addParam("id_token", res.getIdToken()); } if (responseType.hasResponseType(OIDCResponseType.TOKEN)) { redirectUri.addParam("access_token", res.getToken()); redirectUri.addParam("token_type", res.getTokenType()); redirectUri.addParam("session-state", res.getSessionState()); redirectUri.addParam("expires_in", String.valueOf(res.getExpiresIn())); } redirectUri.addParam("not-before-policy", String.valueOf(res.getNotBeforePolicy())); } return redirectUri.build(); }
/** * Registration * * @param code * @return */ @Path(REGISTRATION_PATH) @POST public Response processRegister( @QueryParam("code") String code, @QueryParam("execution") String execution) { event.event(EventType.REGISTER); if (!realm.isRegistrationAllowed()) { event.error(Errors.REGISTRATION_DISABLED); return ErrorPage.error(session, Messages.REGISTRATION_NOT_ALLOWED); } Checks checks = new Checks(); if (!checks.verifyCode(code, ClientSessionModel.Action.AUTHENTICATE.name())) { return checks.response; } ClientSessionCode clientCode = checks.clientCode; ClientSessionModel clientSession = clientCode.getClientSession(); return processRegistration(execution, clientSession, null); }
/** * protocol independent registration page entry point * * @param code * @return */ @Path(REGISTRATION_PATH) @GET public Response registerPage( @QueryParam("code") String code, @QueryParam("execution") String execution) { event.event(EventType.REGISTER); if (!realm.isRegistrationAllowed()) { event.error(Errors.REGISTRATION_DISABLED); return ErrorPage.error(session, Messages.REGISTRATION_NOT_ALLOWED); } Checks checks = new Checks(); if (!checks.verifyCode(code, ClientSessionModel.Action.AUTHENTICATE.name())) { return checks.response; } event.detail(Details.CODE_ID, code); ClientSessionCode clientSessionCode = checks.clientCode; ClientSessionModel clientSession = clientSessionCode.getClientSession(); authManager.expireIdentityCookie(realm, uriInfo, clientConnection); return processRegistration(execution, clientSession, null); }
@Path("federated-identity-update") @GET public Response processFederatedIdentityUpdate( @QueryParam("action") String action, @QueryParam("provider_id") String providerId, @QueryParam("stateChecker") String stateChecker) { if (auth == null) { return login("identity"); } require(AccountRoles.MANAGE_ACCOUNT); csrfCheck(stateChecker); UserModel user = auth.getUser(); if (Validation.isEmpty(providerId)) { setReferrerOnPage(); return account .setError(Messages.MISSING_IDENTITY_PROVIDER) .createResponse(AccountPages.FEDERATED_IDENTITY); } AccountSocialAction accountSocialAction = AccountSocialAction.getAction(action); if (accountSocialAction == null) { setReferrerOnPage(); return account .setError(Messages.INVALID_FEDERATED_IDENTITY_ACTION) .createResponse(AccountPages.FEDERATED_IDENTITY); } boolean hasProvider = false; for (IdentityProviderModel model : realm.getIdentityProviders()) { if (model.getAlias().equals(providerId)) { hasProvider = true; } } if (!hasProvider) { setReferrerOnPage(); return account .setError(Messages.IDENTITY_PROVIDER_NOT_FOUND) .createResponse(AccountPages.FEDERATED_IDENTITY); } if (!user.isEnabled()) { setReferrerOnPage(); return account .setError(Messages.ACCOUNT_DISABLED) .createResponse(AccountPages.FEDERATED_IDENTITY); } switch (accountSocialAction) { case ADD: String redirectUri = UriBuilder.fromUri( Urls.accountFederatedIdentityPage(uriInfo.getBaseUri(), realm.getName())) .build() .toString(); try { ClientSessionModel clientSession = auth.getClientSession(); ClientSessionCode clientSessionCode = new ClientSessionCode(realm, clientSession); clientSessionCode.setAction(ClientSessionModel.Action.AUTHENTICATE.name()); clientSession.setRedirectUri(redirectUri); clientSession.setNote(OIDCLoginProtocol.STATE_PARAM, UUID.randomUUID().toString()); return Response.temporaryRedirect( Urls.identityProviderAuthnRequest( this.uriInfo.getBaseUri(), providerId, realm.getName(), clientSessionCode.getCode())) .build(); } catch (Exception spe) { setReferrerOnPage(); return account .setError(Messages.IDENTITY_PROVIDER_REDIRECT_ERROR) .createResponse(AccountPages.FEDERATED_IDENTITY); } case REMOVE: FederatedIdentityModel link = session.users().getFederatedIdentity(user, providerId, realm); if (link != null) { // Removing last social provider is not possible if you don't have other possibility to // authenticate if (session.users().getFederatedIdentities(user, realm).size() > 1 || user.getFederationLink() != null || isPasswordSet(user)) { session.users().removeFederatedIdentity(realm, user, providerId); logger.debugv( "Social provider {0} removed successfully from user {1}", providerId, user.getUsername()); event .event(EventType.REMOVE_FEDERATED_IDENTITY) .client(auth.getClient()) .user(auth.getUser()) .detail(Details.USERNAME, link.getUserId() + "@" + link.getIdentityProvider()) .success(); setReferrerOnPage(); return account .setSuccess(Messages.IDENTITY_PROVIDER_REMOVED) .createResponse(AccountPages.FEDERATED_IDENTITY); } else { setReferrerOnPage(); return account .setError(Messages.FEDERATED_IDENTITY_REMOVING_LAST_PROVIDER) .createResponse(AccountPages.FEDERATED_IDENTITY); } } else { setReferrerOnPage(); return account .setError(Messages.FEDERATED_IDENTITY_NOT_ACTIVE) .createResponse(AccountPages.FEDERATED_IDENTITY); } default: throw new IllegalArgumentException(); } }
@Override public Response authenticated(UserSessionModel userSession, ClientSessionCode accessCode) { ClientSessionModel clientSession = accessCode.getClientSession(); ClientModel client = clientSession.getClient(); SamlClient samlClient = new SamlClient(client); String requestID = clientSession.getNote(SAML_REQUEST_ID); String relayState = clientSession.getNote(GeneralConstants.RELAY_STATE); String redirectUri = clientSession.getRedirectUri(); String responseIssuer = getResponseIssuer(realm); String nameIdFormat = getNameIdFormat(samlClient, clientSession); String nameId = getNameId(nameIdFormat, clientSession, userSession); // save NAME_ID and format in clientSession as they may be persistent or transient or email and // not username // we'll need to send this back on a logout clientSession.setNote(SAML_NAME_ID, nameId); clientSession.setNote(SAML_NAME_ID_FORMAT, nameIdFormat); SAML2LoginResponseBuilder builder = new SAML2LoginResponseBuilder(); builder .requestID(requestID) .destination(redirectUri) .issuer(responseIssuer) .assertionExpiration(realm.getAccessCodeLifespan()) .subjectExpiration(realm.getAccessTokenLifespan()) .sessionIndex(clientSession.getId()) .requestIssuer(clientSession.getClient().getClientId()) .nameIdentifier(nameIdFormat, nameId) .authMethod(JBossSAMLURIConstants.AC_UNSPECIFIED.get()); if (!samlClient.includeAuthnStatement()) { builder.disableAuthnStatement(true); } List<ProtocolMapperProcessor<SAMLAttributeStatementMapper>> attributeStatementMappers = new LinkedList<>(); List<ProtocolMapperProcessor<SAMLLoginResponseMapper>> loginResponseMappers = new LinkedList<>(); ProtocolMapperProcessor<SAMLRoleListMapper> roleListMapper = null; Set<ProtocolMapperModel> mappings = accessCode.getRequestedProtocolMappers(); for (ProtocolMapperModel mapping : mappings) { ProtocolMapper mapper = (ProtocolMapper) session .getKeycloakSessionFactory() .getProviderFactory(ProtocolMapper.class, mapping.getProtocolMapper()); if (mapper == null) continue; if (mapper instanceof SAMLAttributeStatementMapper) { attributeStatementMappers.add( new ProtocolMapperProcessor<SAMLAttributeStatementMapper>( (SAMLAttributeStatementMapper) mapper, mapping)); } if (mapper instanceof SAMLLoginResponseMapper) { loginResponseMappers.add( new ProtocolMapperProcessor<SAMLLoginResponseMapper>( (SAMLLoginResponseMapper) mapper, mapping)); } if (mapper instanceof SAMLRoleListMapper) { roleListMapper = new ProtocolMapperProcessor<SAMLRoleListMapper>((SAMLRoleListMapper) mapper, mapping); } } Document samlDocument = null; try { ResponseType samlModel = builder.buildModel(); final AttributeStatementType attributeStatement = populateAttributeStatements( attributeStatementMappers, session, userSession, clientSession); populateRoles(roleListMapper, session, userSession, clientSession, attributeStatement); // SAML Spec 2.7.3 AttributeStatement must contain one or more Attribute or EncryptedAttribute if (attributeStatement.getAttributes().size() > 0) { AssertionType assertion = samlModel.getAssertions().get(0).getAssertion(); assertion.addStatement(attributeStatement); } samlModel = transformLoginResponse( loginResponseMappers, samlModel, session, userSession, clientSession); samlDocument = builder.buildDocument(samlModel); } catch (Exception e) { logger.error("failed", e); return ErrorPage.error(session, Messages.FAILED_TO_PROCESS_RESPONSE); } JaxrsSAML2BindingBuilder bindingBuilder = new JaxrsSAML2BindingBuilder(); bindingBuilder.relayState(relayState); KeyManager keyManager = session.keys(); KeyManager.ActiveKey keys = keyManager.getActiveKey(realm); if (samlClient.requiresRealmSignature()) { String canonicalization = samlClient.getCanonicalizationMethod(); if (canonicalization != null) { bindingBuilder.canonicalizationMethod(canonicalization); } bindingBuilder .signatureAlgorithm(samlClient.getSignatureAlgorithm()) .signWith(keys.getPrivateKey(), keys.getPublicKey(), keys.getCertificate()) .signDocument(); } if (samlClient.requiresAssertionSignature()) { String canonicalization = samlClient.getCanonicalizationMethod(); if (canonicalization != null) { bindingBuilder.canonicalizationMethod(canonicalization); } bindingBuilder .signatureAlgorithm(samlClient.getSignatureAlgorithm()) .signWith(keys.getPrivateKey(), keys.getPublicKey(), keys.getCertificate()) .signAssertions(); } if (samlClient.requiresEncryption()) { PublicKey publicKey = null; try { publicKey = SamlProtocolUtils.getEncryptionValidationKey(client); } catch (Exception e) { logger.error("failed", e); return ErrorPage.error(session, Messages.FAILED_TO_PROCESS_RESPONSE); } bindingBuilder.encrypt(publicKey); } try { return buildAuthenticatedResponse(clientSession, redirectUri, samlDocument, bindingBuilder); } catch (Exception e) { logger.error("failed", e); return ErrorPage.error(session, Messages.FAILED_TO_PROCESS_RESPONSE); } }
public Response processRequireAction(final String code, String action) { event.event(EventType.CUSTOM_REQUIRED_ACTION); event.detail(Details.CUSTOM_REQUIRED_ACTION, action); if (action == null) { logger.error("required action query param was null"); event.error(Errors.INVALID_CODE); throw new WebApplicationException(ErrorPage.error(session, Messages.INVALID_CODE)); } RequiredActionFactory factory = (RequiredActionFactory) session .getKeycloakSessionFactory() .getProviderFactory(RequiredActionProvider.class, action); if (factory == null) { logger.error("required action provider was null"); event.error(Errors.INVALID_CODE); throw new WebApplicationException(ErrorPage.error(session, Messages.INVALID_CODE)); } RequiredActionProvider provider = factory.create(session); Checks checks = new Checks(); if (!checks.verifyCode(code, action)) { return checks.response; } final ClientSessionCode clientCode = checks.clientCode; final ClientSessionModel clientSession = clientCode.getClientSession(); if (clientSession.getUserSession() == null) { logger.error("user session was null"); event.error(Errors.USER_SESSION_NOT_FOUND); throw new WebApplicationException(ErrorPage.error(session, Messages.SESSION_NOT_ACTIVE)); } initEvent(clientSession); event.event(EventType.CUSTOM_REQUIRED_ACTION); RequiredActionContextResult context = new RequiredActionContextResult( clientSession.getUserSession(), clientSession, realm, event, session, request, clientSession.getUserSession().getUser(), factory) { @Override public String generateAccessCode(String action) { String clientSessionAction = clientSession.getAction(); if (action.equals(clientSessionAction)) { clientSession.setTimestamp(Time.currentTime()); return code; } ClientSessionCode code = new ClientSessionCode(getRealm(), getClientSession()); code.setAction(action); return code.getCode(); } @Override public void ignore() { throw new RuntimeException("Cannot call ignore within processAction()"); } }; provider.processAction(context); if (context.getStatus() == RequiredActionContext.Status.SUCCESS) { event.clone().success(); // do both clientSession.removeRequiredAction(factory.getId()); clientSession.getUserSession().getUser().removeRequiredAction(factory.getId()); event.event(EventType.LOGIN); return AuthenticationManager.nextActionAfterAuthentication( session, clientSession.getUserSession(), clientSession, clientConnection, request, uriInfo, event); } if (context.getStatus() == RequiredActionContext.Status.CHALLENGE) { return context.getChallenge(); } if (context.getStatus() == RequiredActionContext.Status.FAILURE) { LoginProtocol protocol = context .getSession() .getProvider(LoginProtocol.class, context.getClientSession().getAuthMethod()); protocol .setRealm(context.getRealm()) .setHttpHeaders(context.getHttpRequest().getHttpHeaders()) .setUriInfo(context.getUriInfo()); event.detail(Details.CUSTOM_REQUIRED_ACTION, action).error(Errors.REJECTED_BY_USER); return protocol.consentDenied(context.getClientSession()); } throw new RuntimeException("Unreachable"); }
/** * OAuth grant page. You should not invoked this directly! * * @param formData * @return */ @Path("consent") @POST @Consumes(MediaType.APPLICATION_FORM_URLENCODED) public Response processConsent(final MultivaluedMap<String, String> formData) { event.event(EventType.LOGIN).detail(Details.RESPONSE_TYPE, "code"); if (!checkSsl()) { return ErrorPage.error(session, Messages.HTTPS_REQUIRED); } String code = formData.getFirst("code"); ClientSessionCode accessCode = ClientSessionCode.parse(code, session, realm); if (accessCode == null || !accessCode.isValid(ClientSessionModel.Action.OAUTH_GRANT.name())) { event.error(Errors.INVALID_CODE); return ErrorPage.error(session, Messages.INVALID_ACCESS_CODE); } ClientSessionModel clientSession = accessCode.getClientSession(); event.detail(Details.CODE_ID, clientSession.getId()); String redirect = clientSession.getRedirectUri(); UserSessionModel userSession = clientSession.getUserSession(); UserModel user = userSession.getUser(); ClientModel client = clientSession.getClient(); event .client(client) .user(user) .detail(Details.RESPONSE_TYPE, "code") .detail(Details.REDIRECT_URI, redirect); event.detail(Details.AUTH_METHOD, userSession.getAuthMethod()); event.detail(Details.USERNAME, userSession.getLoginUsername()); if (userSession.isRememberMe()) { event.detail(Details.REMEMBER_ME, "true"); } if (!AuthenticationManager.isSessionValid(realm, userSession)) { AuthenticationManager.backchannelLogout( session, realm, userSession, uriInfo, clientConnection, headers, true); event.error(Errors.INVALID_CODE); return ErrorPage.error(session, Messages.SESSION_NOT_ACTIVE); } event.session(userSession); if (formData.containsKey("cancel")) { LoginProtocol protocol = session.getProvider(LoginProtocol.class, clientSession.getAuthMethod()); protocol.setRealm(realm).setHttpHeaders(headers).setUriInfo(uriInfo); event.error(Errors.REJECTED_BY_USER); return protocol.consentDenied(clientSession); } UserConsentModel grantedConsent = user.getConsentByClient(client.getId()); if (grantedConsent == null) { grantedConsent = new UserConsentModel(client); user.addConsent(grantedConsent); } for (RoleModel role : accessCode.getRequestedRoles()) { grantedConsent.addGrantedRole(role); } for (ProtocolMapperModel protocolMapper : accessCode.getRequestedProtocolMappers()) { if (protocolMapper.isConsentRequired() && protocolMapper.getConsentText() != null) { grantedConsent.addGrantedProtocolMapper(protocolMapper); } } user.updateConsent(grantedConsent); event.detail(Details.CONSENT, Details.CONSENT_VALUE_CONSENT_GRANTED); event.success(); return authManager.redirectAfterSuccessfulFlow( session, realm, userSession, clientSession, request, uriInfo, clientConnection); }
public boolean verifyCode(String code) { if (!checkSsl()) { event.error(Errors.SSL_REQUIRED); response = ErrorPage.error(session, Messages.HTTPS_REQUIRED); return false; } if (!realm.isEnabled()) { event.error(Errors.REALM_DISABLED); response = ErrorPage.error(session, Messages.REALM_NOT_ENABLED); return false; } ClientSessionCode.ParseResult result = ClientSessionCode.parseResult(code, session, realm); clientCode = result.getCode(); if (clientCode == null) { if (result.isClientSessionNotFound()) { // timeout try { ClientSessionModel clientSession = RestartLoginCookie.restartSession(session, realm, code); if (clientSession != null) { event .clone() .detail(Details.RESTART_AFTER_TIMEOUT, "true") .error(Errors.EXPIRED_CODE); response = processFlow( null, clientSession, AUTHENTICATE_PATH, realm.getBrowserFlow(), Messages.LOGIN_TIMEOUT); return false; } } catch (Exception e) { logger.error("failed to parse RestartLoginCookie", e); } } event.error(Errors.INVALID_CODE); response = ErrorPage.error(session, Messages.INVALID_CODE); return false; } ClientSessionModel clientSession = clientCode.getClientSession(); if (clientSession == null) { event.error(Errors.INVALID_CODE); response = ErrorPage.error(session, Messages.INVALID_CODE); return false; } event.detail(Details.CODE_ID, clientSession.getId()); ClientModel client = clientSession.getClient(); if (client == null) { event.error(Errors.CLIENT_NOT_FOUND); response = ErrorPage.error(session, Messages.UNKNOWN_LOGIN_REQUESTER); session.sessions().removeClientSession(realm, clientSession); return false; } if (!client.isEnabled()) { event.error(Errors.CLIENT_NOT_FOUND); response = ErrorPage.error(session, Messages.LOGIN_REQUESTER_NOT_ENABLED); session.sessions().removeClientSession(realm, clientSession); return false; } session.getContext().setClient(client); return true; }