use of org.keycloak.authentication.RequiredActionProvider in project keycloak by keycloak.
the class AuthenticationManager method evaluateRequiredAction.
private static void evaluateRequiredAction(final KeycloakSession session, final AuthenticationSessionModel authSession, final HttpRequest request, final EventBuilder event, final RealmModel realm, final UserModel user, RequiredActionFactory factory) {
RequiredActionProvider provider = factory.create(session);
RequiredActionContextResult result = new RequiredActionContextResult(authSession, realm, event, session, request, user, factory) {
@Override
public void challenge(Response response) {
throw new RuntimeException("Not allowed to call challenge() within evaluateTriggers()");
}
@Override
public void failure() {
throw new RuntimeException("Not allowed to call failure() within evaluateTriggers()");
}
@Override
public void success() {
throw new RuntimeException("Not allowed to call success() within evaluateTriggers()");
}
@Override
public void ignore() {
throw new RuntimeException("Not allowed to call ignore() within evaluateTriggers()");
}
};
provider.evaluateTriggers(result);
}
use of org.keycloak.authentication.RequiredActionProvider in project keycloak by keycloak.
the class AuthenticationManager method executeAction.
private static Response executeAction(KeycloakSession session, AuthenticationSessionModel authSession, RequiredActionProviderModel model, HttpRequest request, EventBuilder event, RealmModel realm, UserModel user, boolean kcActionExecution) {
RequiredActionFactory factory = (RequiredActionFactory) session.getKeycloakSessionFactory().getProviderFactory(RequiredActionProvider.class, model.getProviderId());
if (factory == null) {
throw new RuntimeException("Unable to find factory for Required Action: " + model.getProviderId() + " did you forget to declare it in a META-INF/services file?");
}
RequiredActionContextResult context = new RequiredActionContextResult(authSession, realm, event, session, request, user, factory);
RequiredActionProvider actionProvider = null;
try {
actionProvider = createRequiredAction(context);
} catch (AuthenticationFlowException e) {
if (e.getResponse() != null) {
return e.getResponse();
}
throw e;
}
if (kcActionExecution) {
if (actionProvider.initiatedActionSupport() == InitiatedActionSupport.NOT_SUPPORTED) {
logger.debugv("Requested action {0} does not support being invoked with kc_action", factory.getId());
setKcActionStatus(factory.getId(), RequiredActionContext.KcActionStatus.ERROR, authSession);
return null;
} else if (!model.isEnabled()) {
logger.debugv("Requested action {0} is disabled and can't be invoked with kc_action", factory.getId());
setKcActionStatus(factory.getId(), RequiredActionContext.KcActionStatus.ERROR, authSession);
return null;
} else {
authSession.setClientNote(Constants.KC_ACTION_EXECUTING, factory.getId());
}
}
actionProvider.requiredActionChallenge(context);
if (context.getStatus() == RequiredActionContext.Status.FAILURE) {
LoginProtocol protocol = context.getSession().getProvider(LoginProtocol.class, context.getAuthenticationSession().getProtocol());
protocol.setRealm(context.getRealm()).setHttpHeaders(context.getHttpRequest().getHttpHeaders()).setUriInfo(context.getUriInfo()).setEventBuilder(event);
Response response = protocol.sendError(context.getAuthenticationSession(), Error.CONSENT_DENIED);
event.error(Errors.REJECTED_BY_USER);
return response;
} else if (context.getStatus() == RequiredActionContext.Status.CHALLENGE) {
authSession.setAuthNote(AuthenticationProcessor.CURRENT_AUTHENTICATION_EXECUTION, model.getProviderId());
return context.getChallenge();
} else if (context.getStatus() == RequiredActionContext.Status.SUCCESS) {
event.clone().event(EventType.CUSTOM_REQUIRED_ACTION).detail(Details.CUSTOM_REQUIRED_ACTION, factory.getId()).success();
// don't have to perform the same action twice, so remove it from both the user and session required actions
authSession.getAuthenticatedUser().removeRequiredAction(factory.getId());
authSession.removeRequiredAction(factory.getId());
setKcActionStatus(factory.getId(), RequiredActionContext.KcActionStatus.SUCCESS, authSession);
}
return null;
}
use of org.keycloak.authentication.RequiredActionProvider in project keycloak by keycloak.
the class OIDCLoginProtocol method isReAuthRequiredForKcAction.
protected boolean isReAuthRequiredForKcAction(UserSessionModel userSession, AuthenticationSessionModel authSession) {
if (authSession.getClientNote(Constants.KC_ACTION) != null) {
String providerId = authSession.getClientNote(Constants.KC_ACTION);
RequiredActionProvider requiredActionProvider = this.session.getProvider(RequiredActionProvider.class, providerId);
String authTime = userSession.getNote(AuthenticationManager.AUTH_TIME);
int authTimeInt = authTime == null ? 0 : Integer.parseInt(authTime);
int maxAgeInt = requiredActionProvider.getMaxAuthAge();
return authTimeInt + maxAgeInt < Time.currentTime();
} else {
return false;
}
}
use of org.keycloak.authentication.RequiredActionProvider in project keycloak by keycloak.
the class LoginActionsService method processRequireAction.
private Response processRequireAction(final String authSessionId, final String code, String action, String clientId, String tabId) {
event.event(EventType.CUSTOM_REQUIRED_ACTION);
SessionCodeChecks checks = checksForCode(authSessionId, code, action, clientId, tabId, REQUIRED_ACTION);
if (!checks.verifyRequiredAction(action)) {
return checks.getResponse();
}
AuthenticationSessionModel authSession = checks.getAuthenticationSession();
processLocaleParam(authSession);
if (!checks.isActionRequest()) {
initLoginEvent(authSession);
event.event(EventType.CUSTOM_REQUIRED_ACTION);
return AuthenticationManager.nextActionAfterAuthentication(session, authSession, clientConnection, request, session.getContext().getUri(), event);
}
initLoginEvent(authSession);
event.event(EventType.CUSTOM_REQUIRED_ACTION);
event.detail(Details.CUSTOM_REQUIRED_ACTION, action);
RequiredActionFactory factory = (RequiredActionFactory) session.getKeycloakSessionFactory().getProviderFactory(RequiredActionProvider.class, action);
if (factory == null) {
ServicesLogger.LOGGER.actionProviderNull();
event.error(Errors.INVALID_CODE);
throw new WebApplicationException(ErrorPage.error(session, authSession, Response.Status.BAD_REQUEST, Messages.INVALID_CODE));
}
RequiredActionContextResult context = new RequiredActionContextResult(authSession, realm, event, session, request, authSession.getAuthenticatedUser(), factory) {
@Override
public void ignore() {
throw new RuntimeException("Cannot call ignore within processAction()");
}
};
RequiredActionProvider provider = null;
try {
provider = AuthenticationManager.createRequiredAction(context);
} catch (AuthenticationFlowException e) {
if (e.getResponse() != null) {
return e.getResponse();
}
throw new WebApplicationException(ErrorPage.error(session, authSession, Response.Status.BAD_REQUEST, Messages.DISPLAY_UNSUPPORTED));
}
Response response;
if (isCancelAppInitiatedAction(factory.getId(), authSession, context)) {
provider.initiatedActionCanceled(session, authSession);
AuthenticationManager.setKcActionStatus(factory.getId(), RequiredActionContext.KcActionStatus.CANCELLED, authSession);
context.success();
} else {
provider.processAction(context);
}
if (action != null) {
authSession.setAuthNote(AuthenticationProcessor.LAST_PROCESSED_EXECUTION, action);
}
if (context.getStatus() == RequiredActionContext.Status.SUCCESS) {
event.clone().success();
initLoginEvent(authSession);
event.event(EventType.LOGIN);
authSession.removeRequiredAction(factory.getId());
authSession.getAuthenticatedUser().removeRequiredAction(factory.getId());
authSession.removeAuthNote(AuthenticationProcessor.CURRENT_AUTHENTICATION_EXECUTION);
AuthenticationManager.setKcActionStatus(factory.getId(), RequiredActionContext.KcActionStatus.SUCCESS, authSession);
response = AuthenticationManager.nextActionAfterAuthentication(session, authSession, clientConnection, request, session.getContext().getUri(), event);
} else if (context.getStatus() == RequiredActionContext.Status.CHALLENGE) {
response = context.getChallenge();
} else if (context.getStatus() == RequiredActionContext.Status.FAILURE) {
response = interruptionResponse(context, authSession, action, Error.CONSENT_DENIED);
} else {
throw new RuntimeException("Unreachable");
}
return BrowserHistoryHelper.getInstance().saveResponseAndRedirect(session, authSession, response, true, request);
}
Aggregations