use of org.keycloak.authentication.authenticators.broker.util.SerializedBrokeredIdentityContext in project keycloak by keycloak.
the class AbstractIdpAuthenticator method action.
@Override
public void action(AuthenticationFlowContext context) {
AuthenticationSessionModel clientSession = context.getAuthenticationSession();
SerializedBrokeredIdentityContext serializedCtx = SerializedBrokeredIdentityContext.readFromAuthenticationSession(clientSession, BROKERED_CONTEXT_NOTE);
if (serializedCtx == null) {
throw new AuthenticationFlowException("Not found serialized context in clientSession", AuthenticationFlowError.IDENTITY_PROVIDER_ERROR);
}
BrokeredIdentityContext brokerContext = serializedCtx.deserialize(context.getSession(), clientSession);
if (!brokerContext.getIdpConfig().isEnabled()) {
sendFailureChallenge(context, Response.Status.BAD_REQUEST, Errors.IDENTITY_PROVIDER_ERROR, Messages.IDENTITY_PROVIDER_UNEXPECTED_ERROR, AuthenticationFlowError.IDENTITY_PROVIDER_ERROR);
}
actionImpl(context, serializedCtx, brokerContext);
}
use of org.keycloak.authentication.authenticators.broker.util.SerializedBrokeredIdentityContext in project keycloak by keycloak.
the class LoginFormsUtil method filterIdentityProviders.
public static List<IdentityProviderModel> filterIdentityProviders(Stream<IdentityProviderModel> providers, KeycloakSession session, AuthenticationFlowContext context) {
if (context != null) {
AuthenticationSessionModel authSession = context.getAuthenticationSession();
SerializedBrokeredIdentityContext serializedCtx = SerializedBrokeredIdentityContext.readFromAuthenticationSession(authSession, AbstractIdpAuthenticator.BROKERED_CONTEXT_NOTE);
final IdentityProviderModel existingIdp = (serializedCtx == null) ? null : serializedCtx.deserialize(session, authSession).getIdpConfig();
final Set<String> federatedIdentities;
if (context.getUser() != null) {
federatedIdentities = session.users().getFederatedIdentitiesStream(session.getContext().getRealm(), context.getUser()).map(federatedIdentityModel -> federatedIdentityModel.getIdentityProvider()).collect(Collectors.toSet());
} else {
federatedIdentities = null;
}
return providers.filter(p -> {
// Filter current IDP during first-broker-login flow. Re-authentication with the "linked" broker should not be possible
if (existingIdp == null)
return true;
return !Objects.equals(p.getAlias(), existingIdp.getAlias());
}).filter(idp -> {
// In case that we already have user established in authentication session, we show just providers already linked to this user
if (federatedIdentities == null)
return true;
return federatedIdentities.contains(idp.getAlias());
}).collect(Collectors.toList());
}
return providers.collect(Collectors.toList());
}
use of org.keycloak.authentication.authenticators.broker.util.SerializedBrokeredIdentityContext in project keycloak by keycloak.
the class LoginActionsService method brokerLoginFlow.
protected Response brokerLoginFlow(String authSessionId, String code, String execution, String clientId, String tabId, String flowPath) {
boolean firstBrokerLogin = flowPath.equals(FIRST_BROKER_LOGIN_PATH);
EventType eventType = firstBrokerLogin ? EventType.IDENTITY_PROVIDER_FIRST_LOGIN : EventType.IDENTITY_PROVIDER_POST_LOGIN;
event.event(eventType);
SessionCodeChecks checks = checksForCode(authSessionId, code, execution, clientId, tabId, flowPath);
if (!checks.verifyActiveAndValidAction(AuthenticationSessionModel.Action.AUTHENTICATE.name(), ClientSessionCode.ActionType.LOGIN)) {
return checks.getResponse();
}
event.detail(Details.CODE_ID, code);
final AuthenticationSessionModel authSession = checks.getAuthenticationSession();
processLocaleParam(authSession);
String noteKey = firstBrokerLogin ? AbstractIdpAuthenticator.BROKERED_CONTEXT_NOTE : PostBrokerLoginConstants.PBL_BROKERED_IDENTITY_CONTEXT;
SerializedBrokeredIdentityContext serializedCtx = SerializedBrokeredIdentityContext.readFromAuthenticationSession(authSession, noteKey);
if (serializedCtx == null) {
ServicesLogger.LOGGER.notFoundSerializedCtxInClientSession(noteKey);
throw new WebApplicationException(ErrorPage.error(session, authSession, Response.Status.BAD_REQUEST, "Not found serialized context in authenticationSession."));
}
BrokeredIdentityContext brokerContext = serializedCtx.deserialize(session, authSession);
final String identityProviderAlias = brokerContext.getIdpConfig().getAlias();
String flowId = firstBrokerLogin ? brokerContext.getIdpConfig().getFirstBrokerLoginFlowId() : brokerContext.getIdpConfig().getPostBrokerLoginFlowId();
if (flowId == null) {
ServicesLogger.LOGGER.flowNotConfigForIDP(identityProviderAlias);
throw new WebApplicationException(ErrorPage.error(session, authSession, Response.Status.BAD_REQUEST, "Flow not configured for identity provider"));
}
AuthenticationFlowModel brokerLoginFlow = realm.getAuthenticationFlowById(flowId);
if (brokerLoginFlow == null) {
ServicesLogger.LOGGER.flowNotFoundForIDP(flowId, identityProviderAlias);
throw new WebApplicationException(ErrorPage.error(session, authSession, Response.Status.BAD_REQUEST, "Flow not found for identity provider"));
}
event.detail(Details.IDENTITY_PROVIDER, identityProviderAlias).detail(Details.IDENTITY_PROVIDER_USERNAME, brokerContext.getUsername());
AuthenticationProcessor processor = new AuthenticationProcessor() {
@Override
public Response authenticateOnly() throws AuthenticationFlowException {
Response challenge = super.authenticateOnly();
if (challenge != null) {
if ("true".equals(authenticationSession.getAuthNote(FORWARDED_PASSIVE_LOGIN))) {
// forwarded passive login is incompatible with challenges created by the broker flows.
logger.errorf("Challenge encountered when executing %s flow. Auth requests with prompt=none are incompatible with challenges", flowPath);
LoginProtocol protocol = session.getProvider(LoginProtocol.class, authSession.getProtocol());
protocol.setRealm(realm).setHttpHeaders(headers).setUriInfo(session.getContext().getUri()).setEventBuilder(event);
return protocol.sendError(authSession, Error.PASSIVE_INTERACTION_REQUIRED);
}
}
return challenge;
}
@Override
protected Response authenticationComplete() {
if (firstBrokerLogin) {
authSession.setAuthNote(AbstractIdpAuthenticator.FIRST_BROKER_LOGIN_SUCCESS, identityProviderAlias);
} else {
String authStateNoteKey = PostBrokerLoginConstants.PBL_AUTH_STATE_PREFIX + identityProviderAlias;
authSession.setAuthNote(authStateNoteKey, "true");
}
return redirectToAfterBrokerLoginEndpoint(authSession, firstBrokerLogin);
}
};
return processFlow(checks.isActionRequest(), execution, authSession, flowPath, brokerLoginFlow, null, processor);
}
use of org.keycloak.authentication.authenticators.broker.util.SerializedBrokeredIdentityContext in project keycloak by keycloak.
the class IdentityBrokerService method finishOrRedirectToPostBrokerLogin.
private Response finishOrRedirectToPostBrokerLogin(AuthenticationSessionModel authSession, BrokeredIdentityContext context, boolean wasFirstBrokerLogin) {
String postBrokerLoginFlowId = context.getIdpConfig().getPostBrokerLoginFlowId();
if (postBrokerLoginFlowId == null) {
logger.debugf("Skip redirect to postBrokerLogin flow. PostBrokerLogin flow not set for identityProvider '%s'.", context.getIdpConfig().getAlias());
return afterPostBrokerLoginFlowSuccess(authSession, context, wasFirstBrokerLogin);
} else {
logger.debugf("Redirect to postBrokerLogin flow after authentication with identityProvider '%s'.", context.getIdpConfig().getAlias());
authSession.getParentSession().setTimestamp(Time.currentTime());
SerializedBrokeredIdentityContext ctx = SerializedBrokeredIdentityContext.serialize(context);
ctx.saveToAuthenticationSession(authSession, PostBrokerLoginConstants.PBL_BROKERED_IDENTITY_CONTEXT);
authSession.setAuthNote(PostBrokerLoginConstants.PBL_AFTER_FIRST_BROKER_LOGIN, String.valueOf(wasFirstBrokerLogin));
URI redirect = LoginActionsService.postBrokerLoginProcessor(session.getContext().getUri()).queryParam(Constants.CLIENT_ID, authSession.getClient().getClientId()).queryParam(Constants.TAB_ID, authSession.getTabId()).build(realmModel.getName());
return Response.status(302).location(redirect).build();
}
}
use of org.keycloak.authentication.authenticators.broker.util.SerializedBrokeredIdentityContext in project keycloak by keycloak.
the class IdentityBrokerService method afterPostBrokerLoginFlowSuccess.
private Response afterPostBrokerLoginFlowSuccess(AuthenticationSessionModel authSession, BrokeredIdentityContext context, boolean wasFirstBrokerLogin) {
String providerId = context.getIdpConfig().getAlias();
UserModel federatedUser = authSession.getAuthenticatedUser();
if (wasFirstBrokerLogin) {
return finishBrokerAuthentication(context, federatedUser, authSession, providerId);
} else {
boolean firstBrokerLoginInProgress = (authSession.getAuthNote(AbstractIdpAuthenticator.BROKERED_CONTEXT_NOTE) != null);
if (firstBrokerLoginInProgress) {
logger.debugf("Reauthenticated with broker '%s' when linking user '%s' with other broker", context.getIdpConfig().getAlias(), federatedUser.getUsername());
SerializedBrokeredIdentityContext serializedCtx = SerializedBrokeredIdentityContext.readFromAuthenticationSession(authSession, AbstractIdpAuthenticator.BROKERED_CONTEXT_NOTE);
authSession.setAuthNote(AbstractIdpAuthenticator.FIRST_BROKER_LOGIN_SUCCESS, serializedCtx.getIdentityProviderId());
return afterFirstBrokerLogin(authSession);
} else {
return finishBrokerAuthentication(context, federatedUser, authSession, providerId);
}
}
}
Aggregations