Search in sources :

Example 11 with FederatedIdentityModel

use of org.keycloak.models.FederatedIdentityModel in project keycloak by keycloak.

the class LinkedAccountsResource method removeLinkedAccount.

@DELETE
@Path("/{providerId}")
@Produces(MediaType.APPLICATION_JSON)
public Response removeLinkedAccount(@PathParam("providerId") String providerId) {
    auth.require(AccountRoles.MANAGE_ACCOUNT);
    String errorMessage = checkCommonPreconditions(providerId);
    if (errorMessage != null) {
        return ErrorResponse.error(errorMessage, Response.Status.BAD_REQUEST);
    }
    FederatedIdentityModel link = session.users().getFederatedIdentity(realm, user, providerId);
    if (link == null) {
        return ErrorResponse.error(Messages.FEDERATED_IDENTITY_NOT_ACTIVE, Response.Status.BAD_REQUEST);
    }
    // Removing last social provider is not possible if you don't have other possibility to authenticate
    if (!(session.users().getFederatedIdentitiesStream(realm, user).count() > 1 || user.getFederationLink() != null || isPasswordSet())) {
        return ErrorResponse.error(Messages.FEDERATED_IDENTITY_REMOVING_LAST_PROVIDER, Response.Status.BAD_REQUEST);
    }
    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, auth.getUser().getUsername()).detail(Details.IDENTITY_PROVIDER, link.getIdentityProvider()).detail(Details.IDENTITY_PROVIDER_USERNAME, link.getUserName()).success();
    return Cors.add(request, Response.noContent()).auth().allowedOrigins(auth.getToken()).build();
}
Also used : FederatedIdentityModel(org.keycloak.models.FederatedIdentityModel) Path(javax.ws.rs.Path) DELETE(javax.ws.rs.DELETE) Produces(javax.ws.rs.Produces)

Example 12 with FederatedIdentityModel

use of org.keycloak.models.FederatedIdentityModel in project keycloak by keycloak.

the class LinkedAccountsResource method toLinkedAccountRepresentation.

private LinkedAccountRepresentation toLinkedAccountRepresentation(IdentityProviderModel provider, Set<String> socialIds, Stream<FederatedIdentityModel> identities) {
    String providerId = provider.getAlias();
    FederatedIdentityModel identity = getIdentity(identities, providerId);
    String displayName = KeycloakModelUtils.getIdentityProviderDisplayName(session, provider);
    String guiOrder = provider.getConfig() != null ? provider.getConfig().get("guiOrder") : null;
    LinkedAccountRepresentation rep = new LinkedAccountRepresentation();
    rep.setConnected(identity != null);
    rep.setSocial(socialIds.contains(provider.getProviderId()));
    rep.setProviderAlias(providerId);
    rep.setDisplayName(displayName);
    rep.setGuiOrder(guiOrder);
    rep.setProviderName(provider.getAlias());
    if (identity != null) {
        rep.setLinkedUsername(identity.getUserName());
    }
    return rep;
}
Also used : FederatedIdentityModel(org.keycloak.models.FederatedIdentityModel) LinkedAccountRepresentation(org.keycloak.representations.account.LinkedAccountRepresentation)

Example 13 with FederatedIdentityModel

use of org.keycloak.models.FederatedIdentityModel in project keycloak by keycloak.

the class UserCacheSession method getFederatedIdentitiesStream.

@Override
public Stream<FederatedIdentityModel> getFederatedIdentitiesStream(RealmModel realm, UserModel user) {
    logger.tracev("getFederatedIdentities: {0}", user.getUsername());
    String cacheKey = getFederatedIdentityLinksCacheKey(user.getId());
    if (realmInvalidations.contains(realm.getId()) || invalidations.contains(user.getId()) || invalidations.contains(cacheKey)) {
        return getDelegate().getFederatedIdentitiesStream(realm, user);
    }
    CachedFederatedIdentityLinks cachedLinks = cache.get(cacheKey, CachedFederatedIdentityLinks.class);
    if (cachedLinks == null) {
        Long loaded = cache.getCurrentRevision(cacheKey);
        Set<FederatedIdentityModel> federatedIdentities = getDelegate().getFederatedIdentitiesStream(realm, user).collect(Collectors.toSet());
        cachedLinks = new CachedFederatedIdentityLinks(loaded, cacheKey, realm, federatedIdentities);
        cache.addRevisioned(cachedLinks, startupRevision);
        return federatedIdentities.stream();
    } else {
        return cachedLinks.getFederatedIdentities().stream();
    }
}
Also used : FederatedIdentityModel(org.keycloak.models.FederatedIdentityModel) CachedFederatedIdentityLinks(org.keycloak.models.cache.infinispan.entities.CachedFederatedIdentityLinks)

Example 14 with FederatedIdentityModel

use of org.keycloak.models.FederatedIdentityModel in project keycloak by keycloak.

the class UserCacheSession method removeFederatedIdentity.

@Override
public boolean removeFederatedIdentity(RealmModel realm, UserModel user, String socialProvider) {
    // Needs to invalidate both directions
    FederatedIdentityModel socialLink = getFederatedIdentity(realm, user, socialProvider);
    UserFederationLinkRemovedEvent event = UserFederationLinkRemovedEvent.create(user.getId(), realm.getId(), socialLink);
    cache.federatedIdentityLinkRemovedInvalidation(user.getId(), realm.getId(), event.getIdentityProviderId(), event.getSocialUserId(), invalidations);
    invalidationEvents.add(event);
    return getDelegate().removeFederatedIdentity(realm, user, socialProvider);
}
Also used : UserFederationLinkRemovedEvent(org.keycloak.models.cache.infinispan.events.UserFederationLinkRemovedEvent) FederatedIdentityModel(org.keycloak.models.FederatedIdentityModel)

Example 15 with FederatedIdentityModel

use of org.keycloak.models.FederatedIdentityModel in project keycloak by keycloak.

the class IdentityBrokerService method authenticated.

public Response authenticated(BrokeredIdentityContext context) {
    IdentityProviderModel identityProviderConfig = context.getIdpConfig();
    AuthenticationSessionModel authenticationSession = context.getAuthenticationSession();
    String providerId = identityProviderConfig.getAlias();
    if (!identityProviderConfig.isStoreToken()) {
        if (isDebugEnabled()) {
            logger.debugf("Token will not be stored for identity provider [%s].", providerId);
        }
        context.setToken(null);
    }
    StatusResponseType loginResponse = (StatusResponseType) context.getContextData().get(SAMLEndpoint.SAML_LOGIN_RESPONSE);
    if (loginResponse != null) {
        for (Iterator<SamlAuthenticationPreprocessor> it = SamlSessionUtils.getSamlAuthenticationPreprocessorIterator(session); it.hasNext(); ) {
            loginResponse = it.next().beforeProcessingLoginResponse(loginResponse, authenticationSession);
        }
    }
    session.getContext().setClient(authenticationSession.getClient());
    context.getIdp().preprocessFederatedIdentity(session, realmModel, context);
    KeycloakSessionFactory sessionFactory = session.getKeycloakSessionFactory();
    realmModel.getIdentityProviderMappersByAliasStream(context.getIdpConfig().getAlias()).forEach(mapper -> {
        IdentityProviderMapper target = (IdentityProviderMapper) sessionFactory.getProviderFactory(IdentityProviderMapper.class, mapper.getIdentityProviderMapper());
        target.preprocessFederatedIdentity(session, realmModel, mapper, context);
    });
    FederatedIdentityModel federatedIdentityModel = new FederatedIdentityModel(providerId, context.getId(), context.getUsername(), context.getToken());
    this.event.event(EventType.IDENTITY_PROVIDER_LOGIN).detail(Details.REDIRECT_URI, authenticationSession.getRedirectUri()).detail(Details.IDENTITY_PROVIDER, providerId).detail(Details.IDENTITY_PROVIDER_USERNAME, context.getUsername());
    UserModel federatedUser = this.session.users().getUserByFederatedIdentity(this.realmModel, federatedIdentityModel);
    boolean shouldMigrateId = false;
    // try to find the user using legacy ID
    if (federatedUser == null && context.getLegacyId() != null) {
        federatedIdentityModel = new FederatedIdentityModel(federatedIdentityModel, context.getLegacyId());
        federatedUser = this.session.users().getUserByFederatedIdentity(this.realmModel, federatedIdentityModel);
        shouldMigrateId = true;
    }
    // Check if federatedUser is already authenticated (this means linking social into existing federatedUser account)
    UserSessionModel userSession = new AuthenticationSessionManager(session).getUserSession(authenticationSession);
    if (shouldPerformAccountLinking(authenticationSession, userSession, providerId)) {
        return performAccountLinking(authenticationSession, userSession, context, federatedIdentityModel, federatedUser);
    }
    if (federatedUser == null) {
        logger.debugf("Federated user not found for provider '%s' and broker username '%s'", providerId, context.getUsername());
        String username = context.getModelUsername();
        if (username == null) {
            if (this.realmModel.isRegistrationEmailAsUsername() && !Validation.isBlank(context.getEmail())) {
                username = context.getEmail();
            } else if (context.getUsername() == null) {
                username = context.getIdpConfig().getAlias() + "." + context.getId();
            } else {
                username = context.getUsername();
            }
        }
        username = username.trim();
        context.setModelUsername(username);
        SerializedBrokeredIdentityContext ctx0 = SerializedBrokeredIdentityContext.readFromAuthenticationSession(authenticationSession, AbstractIdpAuthenticator.BROKERED_CONTEXT_NOTE);
        if (ctx0 != null) {
            SerializedBrokeredIdentityContext ctx1 = SerializedBrokeredIdentityContext.serialize(context);
            ctx1.saveToAuthenticationSession(authenticationSession, AbstractIdpAuthenticator.NESTED_FIRST_BROKER_CONTEXT);
            logger.warnv("Nested first broker flow detected: {0} -> {1}", ctx0.getIdentityProviderId(), ctx1.getIdentityProviderId());
            logger.debug("Resuming last execution");
            URI redirect = new AuthenticationFlowURLHelper(session, realmModel, session.getContext().getUri()).getLastExecutionUrl(authenticationSession);
            return Response.status(Status.FOUND).location(redirect).build();
        }
        logger.debug("Redirecting to flow for firstBrokerLogin");
        boolean forwardedPassiveLogin = "true".equals(authenticationSession.getAuthNote(AuthenticationProcessor.FORWARDED_PASSIVE_LOGIN));
        // Redirect to firstBrokerLogin after successful login and ensure that previous authentication state removed
        AuthenticationProcessor.resetFlow(authenticationSession, LoginActionsService.FIRST_BROKER_LOGIN_PATH);
        // Set the FORWARDED_PASSIVE_LOGIN note (if needed) after resetting the session so it is not lost.
        if (forwardedPassiveLogin) {
            authenticationSession.setAuthNote(AuthenticationProcessor.FORWARDED_PASSIVE_LOGIN, "true");
        }
        SerializedBrokeredIdentityContext ctx = SerializedBrokeredIdentityContext.serialize(context);
        ctx.saveToAuthenticationSession(authenticationSession, AbstractIdpAuthenticator.BROKERED_CONTEXT_NOTE);
        URI redirect = LoginActionsService.firstBrokerLoginProcessor(session.getContext().getUri()).queryParam(Constants.CLIENT_ID, authenticationSession.getClient().getClientId()).queryParam(Constants.TAB_ID, authenticationSession.getTabId()).build(realmModel.getName());
        return Response.status(302).location(redirect).build();
    } else {
        Response response = validateUser(authenticationSession, federatedUser, realmModel);
        if (response != null) {
            return response;
        }
        updateFederatedIdentity(context, federatedUser);
        if (shouldMigrateId) {
            migrateFederatedIdentityId(context, federatedUser);
        }
        authenticationSession.setAuthenticatedUser(federatedUser);
        return finishOrRedirectToPostBrokerLogin(authenticationSession, context, false);
    }
}
Also used : AuthenticationSessionModel(org.keycloak.sessions.AuthenticationSessionModel) RootAuthenticationSessionModel(org.keycloak.sessions.RootAuthenticationSessionModel) UserSessionModel(org.keycloak.models.UserSessionModel) FederatedIdentityModel(org.keycloak.models.FederatedIdentityModel) AuthenticationFlowURLHelper(org.keycloak.services.util.AuthenticationFlowURLHelper) IdentityProviderModel(org.keycloak.models.IdentityProviderModel) SerializedBrokeredIdentityContext(org.keycloak.authentication.authenticators.broker.util.SerializedBrokeredIdentityContext) KeycloakSessionFactory(org.keycloak.models.KeycloakSessionFactory) URI(java.net.URI) StatusResponseType(org.keycloak.dom.saml.v2.protocol.StatusResponseType) UserModel(org.keycloak.models.UserModel) AuthenticationSessionManager(org.keycloak.services.managers.AuthenticationSessionManager) Response(javax.ws.rs.core.Response) ErrorResponse(org.keycloak.services.ErrorResponse) IdentityProviderMapper(org.keycloak.broker.provider.IdentityProviderMapper) SamlAuthenticationPreprocessor(org.keycloak.protocol.saml.preprocessor.SamlAuthenticationPreprocessor)

Aggregations

FederatedIdentityModel (org.keycloak.models.FederatedIdentityModel)22 UserModel (org.keycloak.models.UserModel)6 IOException (java.io.IOException)4 Path (javax.ws.rs.Path)4 NotFoundException (javax.ws.rs.NotFoundException)3 Produces (javax.ws.rs.Produces)3 IdentityProviderMapper (org.keycloak.broker.provider.IdentityProviderMapper)3 ClientModel (org.keycloak.models.ClientModel)3 IdentityProviderModel (org.keycloak.models.IdentityProviderModel)3 KeycloakSessionFactory (org.keycloak.models.KeycloakSessionFactory)3 URI (java.net.URI)2 NoSuchAlgorithmException (java.security.NoSuchAlgorithmException)2 ArrayList (java.util.ArrayList)2 List (java.util.List)2 Map (java.util.Map)2 GET (javax.ws.rs.GET)2 POST (javax.ws.rs.POST)2 WebApplicationException (javax.ws.rs.WebApplicationException)2 Response (javax.ws.rs.core.Response)2 SerializedBrokeredIdentityContext (org.keycloak.authentication.authenticators.broker.util.SerializedBrokeredIdentityContext)2