Search in sources :

Example 36 with BrokeredIdentityContext

use of org.keycloak.broker.provider.BrokeredIdentityContext in project keycloak by keycloak.

the class IdentityBrokerService method afterFirstBrokerLogin.

private Response afterFirstBrokerLogin(AuthenticationSessionModel authSession) {
    try {
        this.event.detail(Details.CODE_ID, authSession.getParentSession().getId()).removeDetail("auth_method");
        SerializedBrokeredIdentityContext serializedCtx = SerializedBrokeredIdentityContext.readFromAuthenticationSession(authSession, AbstractIdpAuthenticator.BROKERED_CONTEXT_NOTE);
        if (serializedCtx == null) {
            throw new IdentityBrokerException("Not found serialized context in clientSession");
        }
        BrokeredIdentityContext context = serializedCtx.deserialize(session, authSession);
        String providerId = context.getIdpConfig().getAlias();
        event.detail(Details.IDENTITY_PROVIDER, providerId);
        event.detail(Details.IDENTITY_PROVIDER_USERNAME, context.getUsername());
        // Ensure the first-broker-login flow was successfully finished
        String authProvider = authSession.getAuthNote(AbstractIdpAuthenticator.FIRST_BROKER_LOGIN_SUCCESS);
        if (authProvider == null || !authProvider.equals(providerId)) {
            throw new IdentityBrokerException("Invalid request. Not found the flag that first-broker-login flow was finished");
        }
        // firstBrokerLogin workflow finished. Removing note now
        authSession.removeAuthNote(AbstractIdpAuthenticator.BROKERED_CONTEXT_NOTE);
        UserModel federatedUser = authSession.getAuthenticatedUser();
        if (federatedUser == null) {
            throw new IdentityBrokerException("Couldn't found authenticated federatedUser in authentication session");
        }
        event.user(federatedUser);
        event.detail(Details.USERNAME, federatedUser.getUsername());
        if (context.getIdpConfig().isAddReadTokenRoleOnCreate()) {
            ClientModel brokerClient = realmModel.getClientByClientId(Constants.BROKER_SERVICE_CLIENT_ID);
            if (brokerClient == null) {
                throw new IdentityBrokerException("Client 'broker' not available. Maybe realm has not migrated to support the broker token exchange service");
            }
            RoleModel readTokenRole = brokerClient.getRole(Constants.READ_TOKEN_ROLE);
            federatedUser.grantRole(readTokenRole);
        }
        // Add federated identity link here
        FederatedIdentityModel federatedIdentityModel = new FederatedIdentityModel(context.getIdpConfig().getAlias(), context.getId(), context.getUsername(), context.getToken());
        session.users().addFederatedIdentity(realmModel, federatedUser, federatedIdentityModel);
        String isRegisteredNewUser = authSession.getAuthNote(AbstractIdpAuthenticator.BROKER_REGISTERED_NEW_USER);
        if (Boolean.parseBoolean(isRegisteredNewUser)) {
            logger.debugf("Registered new user '%s' after first login with identity provider '%s'. Identity provider username is '%s' . ", federatedUser.getUsername(), providerId, context.getUsername());
            context.getIdp().importNewUser(session, realmModel, federatedUser, context);
            KeycloakSessionFactory sessionFactory = session.getKeycloakSessionFactory();
            realmModel.getIdentityProviderMappersByAliasStream(providerId).forEach(mapper -> {
                IdentityProviderMapper target = (IdentityProviderMapper) sessionFactory.getProviderFactory(IdentityProviderMapper.class, mapper.getIdentityProviderMapper());
                target.importNewUser(session, realmModel, federatedUser, mapper, context);
            });
            if (context.getIdpConfig().isTrustEmail() && !Validation.isBlank(federatedUser.getEmail()) && !Boolean.parseBoolean(authSession.getAuthNote(AbstractIdpAuthenticator.UPDATE_PROFILE_EMAIL_CHANGED))) {
                logger.debugf("Email verified automatically after registration of user '%s' through Identity provider '%s' ", federatedUser.getUsername(), context.getIdpConfig().getAlias());
                federatedUser.setEmailVerified(true);
            }
            event.event(EventType.REGISTER).detail(Details.REGISTER_METHOD, "broker").detail(Details.EMAIL, federatedUser.getEmail()).success();
        } else {
            logger.debugf("Linked existing keycloak user '%s' with identity provider '%s' . Identity provider username is '%s' .", federatedUser.getUsername(), providerId, context.getUsername());
            event.event(EventType.FEDERATED_IDENTITY_LINK).success();
            updateFederatedIdentity(context, federatedUser);
        }
        return finishOrRedirectToPostBrokerLogin(authSession, context, true);
    } catch (Exception e) {
        return redirectToErrorPage(authSession, Response.Status.INTERNAL_SERVER_ERROR, Messages.IDENTITY_PROVIDER_UNEXPECTED_ERROR, e);
    }
}
Also used : UserModel(org.keycloak.models.UserModel) ClientModel(org.keycloak.models.ClientModel) IdentityBrokerException(org.keycloak.broker.provider.IdentityBrokerException) FederatedIdentityModel(org.keycloak.models.FederatedIdentityModel) IdentityProviderMapper(org.keycloak.broker.provider.IdentityProviderMapper) RoleModel(org.keycloak.models.RoleModel) SerializedBrokeredIdentityContext(org.keycloak.authentication.authenticators.broker.util.SerializedBrokeredIdentityContext) KeycloakSessionFactory(org.keycloak.models.KeycloakSessionFactory) BrokeredIdentityContext(org.keycloak.broker.provider.BrokeredIdentityContext) SerializedBrokeredIdentityContext(org.keycloak.authentication.authenticators.broker.util.SerializedBrokeredIdentityContext) NoSuchAlgorithmException(java.security.NoSuchAlgorithmException) WebApplicationException(javax.ws.rs.WebApplicationException) IOException(java.io.IOException) IdentityBrokerException(org.keycloak.broker.provider.IdentityBrokerException) OAuthErrorException(org.keycloak.OAuthErrorException) NotFoundException(javax.ws.rs.NotFoundException) ErrorPageException(org.keycloak.services.ErrorPageException)

Example 37 with BrokeredIdentityContext

use of org.keycloak.broker.provider.BrokeredIdentityContext in project keycloak by keycloak.

the class AbstractIdpAuthenticator method authenticate.

@Override
public void authenticate(AuthenticationFlowContext context) {
    AuthenticationSessionModel authSession = context.getAuthenticationSession();
    SerializedBrokeredIdentityContext serializedCtx = SerializedBrokeredIdentityContext.readFromAuthenticationSession(authSession, 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(), authSession);
    if (!brokerContext.getIdpConfig().isEnabled()) {
        sendFailureChallenge(context, Response.Status.BAD_REQUEST, Errors.IDENTITY_PROVIDER_ERROR, Messages.IDENTITY_PROVIDER_UNEXPECTED_ERROR, AuthenticationFlowError.IDENTITY_PROVIDER_ERROR);
    }
    authenticateImpl(context, serializedCtx, brokerContext);
}
Also used : AuthenticationSessionModel(org.keycloak.sessions.AuthenticationSessionModel) AuthenticationFlowException(org.keycloak.authentication.AuthenticationFlowException) SerializedBrokeredIdentityContext(org.keycloak.authentication.authenticators.broker.util.SerializedBrokeredIdentityContext) BrokeredIdentityContext(org.keycloak.broker.provider.BrokeredIdentityContext) SerializedBrokeredIdentityContext(org.keycloak.authentication.authenticators.broker.util.SerializedBrokeredIdentityContext)

Example 38 with BrokeredIdentityContext

use of org.keycloak.broker.provider.BrokeredIdentityContext in project keycloak by keycloak.

the class AbstractOAuth2IdentityProviderTest method getFederatedIdentity_responseUrlLine.

@Test
public void getFederatedIdentity_responseUrlLine() {
    TestProvider tested = getTested();
    BrokeredIdentityContext fi = tested.getFederatedIdentity("cosi=sss&" + AbstractOAuth2IdentityProvider.OAUTH2_PARAMETER_ACCESS_TOKEN + "=458rtf&kdesi=ss}");
    Assert.assertNotNull(fi);
    Assert.assertEquals("458rtf", fi.getId());
}
Also used : BrokeredIdentityContext(org.keycloak.broker.provider.BrokeredIdentityContext) Test(org.junit.Test)

Example 39 with BrokeredIdentityContext

use of org.keycloak.broker.provider.BrokeredIdentityContext in project keycloak by keycloak.

the class IdpUsernamePasswordForm method setupForm.

protected LoginFormsProvider setupForm(AuthenticationFlowContext context, MultivaluedMap<String, String> formData, Optional<UserModel> existingUser) {
    SerializedBrokeredIdentityContext serializedCtx = SerializedBrokeredIdentityContext.readFromAuthenticationSession(context.getAuthenticationSession(), AbstractIdpAuthenticator.BROKERED_CONTEXT_NOTE);
    if (serializedCtx == null) {
        throw new AuthenticationFlowException("Not found serialized context in clientSession", AuthenticationFlowError.IDENTITY_PROVIDER_ERROR);
    }
    existingUser.ifPresent(u -> formData.putSingle(AuthenticationManager.FORM_USERNAME, u.getUsername()));
    LoginFormsProvider form = context.form().setFormData(formData).setAttribute(LoginFormsProvider.REGISTRATION_DISABLED, true).setInfo(Messages.FEDERATED_IDENTITY_CONFIRM_REAUTHENTICATE_MESSAGE, serializedCtx.getIdentityProviderId());
    SerializedBrokeredIdentityContext serializedCtx0 = SerializedBrokeredIdentityContext.readFromAuthenticationSession(context.getAuthenticationSession(), AbstractIdpAuthenticator.NESTED_FIRST_BROKER_CONTEXT);
    if (serializedCtx0 != null) {
        BrokeredIdentityContext ctx0 = serializedCtx0.deserialize(context.getSession(), context.getAuthenticationSession());
        form.setError(Messages.NESTED_FIRST_BROKER_FLOW_MESSAGE, ctx0.getIdpConfig().getAlias(), ctx0.getUsername());
        context.getAuthenticationSession().setAuthNote(AbstractIdpAuthenticator.NESTED_FIRST_BROKER_CONTEXT, null);
    }
    return form;
}
Also used : LoginFormsProvider(org.keycloak.forms.login.LoginFormsProvider) AuthenticationFlowException(org.keycloak.authentication.AuthenticationFlowException) SerializedBrokeredIdentityContext(org.keycloak.authentication.authenticators.broker.util.SerializedBrokeredIdentityContext) BrokeredIdentityContext(org.keycloak.broker.provider.BrokeredIdentityContext) SerializedBrokeredIdentityContext(org.keycloak.authentication.authenticators.broker.util.SerializedBrokeredIdentityContext)

Example 40 with BrokeredIdentityContext

use of org.keycloak.broker.provider.BrokeredIdentityContext in project keycloak by keycloak.

the class SerializedBrokeredIdentityContext method deserialize.

public BrokeredIdentityContext deserialize(KeycloakSession session, AuthenticationSessionModel authSession) {
    BrokeredIdentityContext ctx = new BrokeredIdentityContext(getId());
    ctx.setUsername(getBrokerUsername());
    ctx.setModelUsername(getModelUsername());
    ctx.setEmail(getEmail());
    ctx.setFirstName(getFirstName());
    ctx.setLastName(getLastName());
    ctx.setBrokerSessionId(getBrokerSessionId());
    ctx.setBrokerUserId(getBrokerUserId());
    ctx.setToken(getToken());
    RealmModel realm = authSession.getRealm();
    IdentityProviderModel idpConfig = realm.getIdentityProviderByAlias(getIdentityProviderId());
    if (idpConfig == null) {
        throw new ModelException("Can't find identity provider with ID " + getIdentityProviderId() + " in realm " + realm.getName());
    }
    IdentityProvider idp = IdentityBrokerService.getIdentityProvider(session, realm, idpConfig.getAlias());
    ctx.setIdpConfig(idpConfig);
    ctx.setIdp(idp);
    IdentityProviderDataMarshaller serializer = idp.getMarshaller();
    for (Map.Entry<String, ContextDataEntry> entry : getContextData().entrySet()) {
        try {
            ContextDataEntry value = entry.getValue();
            Class<?> clazz = Reflections.classForName(value.getClazz(), this.getClass().getClassLoader());
            Object deserialized = serializer.deserialize(value.getData(), clazz);
            ctx.getContextData().put(entry.getKey(), deserialized);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
    ctx.setAuthenticationSession(authSession);
    return ctx;
}
Also used : ModelException(org.keycloak.models.ModelException) IdentityProvider(org.keycloak.broker.provider.IdentityProvider) IdentityProviderModel(org.keycloak.models.IdentityProviderModel) BrokeredIdentityContext(org.keycloak.broker.provider.BrokeredIdentityContext) IOException(java.io.IOException) ModelException(org.keycloak.models.ModelException) RealmModel(org.keycloak.models.RealmModel) IdentityProviderDataMarshaller(org.keycloak.broker.provider.IdentityProviderDataMarshaller) HashMap(java.util.HashMap) Map(java.util.Map)

Aggregations

BrokeredIdentityContext (org.keycloak.broker.provider.BrokeredIdentityContext)40 IOException (java.io.IOException)12 IdentityBrokerException (org.keycloak.broker.provider.IdentityBrokerException)12 JsonNode (com.fasterxml.jackson.databind.JsonNode)11 SerializedBrokeredIdentityContext (org.keycloak.authentication.authenticators.broker.util.SerializedBrokeredIdentityContext)6 ErrorResponseException (org.keycloak.services.ErrorResponseException)6 OAuthErrorException (org.keycloak.OAuthErrorException)5 AuthenticationSessionModel (org.keycloak.sessions.AuthenticationSessionModel)5 Map (java.util.Map)3 AuthenticationFlowException (org.keycloak.authentication.AuthenticationFlowException)3 SimpleHttp (org.keycloak.broker.provider.util.SimpleHttp)3 HashMap (java.util.HashMap)2 Set (java.util.Set)2 Collectors (java.util.stream.Collectors)2 WebApplicationException (javax.ws.rs.WebApplicationException)2 MediaType (javax.ws.rs.core.MediaType)2 Response (javax.ws.rs.core.Response)2 Test (org.junit.Test)2 IdentityProvider (org.keycloak.broker.provider.IdentityProvider)2 JWSInput (org.keycloak.jose.jws.JWSInput)2