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();
}
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;
}
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();
}
}
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);
}
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);
}
}
Aggregations