Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,8 @@ Although each type of identity provider has its configuration options, all share
|Trust Email
|When *ON*, {project_name} trusts email addresses from the identity provider. If the realm requires email validation, users that log in from this identity provider do not need to perform the email verification process.
If the target identity provider supports email verification and advertises this information when returning the user profile information, the email of the federated user will be (un)marked as verified.
For instance, an OpenID Connect Provider returning a `email_verified` claim in their ID Tokens.
For an OpenID Connect provider, this applies to the `email_verified` claim accompanying the email address in its ID token or UserInfo response.
If the claim is absent, the *Trust Email* setting provides the default verification status.
Note that this setting will set the email as verified when the user is federated for the first time and on subsequent logins
through the broker if the sync mode is set to `FORCE`.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -597,7 +597,8 @@ protected BrokeredIdentityContext extractIdentity(AccessTokenResponse tokenRespo
familyName = getJsonProperty(userInfo, IDToken.FAMILY_NAME);
preferredUsername = getUsernameFromUserInfo(userInfo);
String userInfoEmail = getJsonProperty(userInfo, "email");
Boolean userInfoEmailVerified = Boolean.parseBoolean(getJsonProperty(userInfo, IDToken.EMAIL_VERIFIED));
String userInfoEmailVerifiedClaim = getJsonProperty(userInfo, IDToken.EMAIL_VERIFIED);
Boolean userInfoEmailVerified = userInfoEmailVerifiedClaim == null ? null : Boolean.valueOf(userInfoEmailVerifiedClaim);

if (userInfoEmail != null) {
email = userInfoEmail;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,55 @@
package org.keycloak.tests.broker.oidc;

import org.keycloak.admin.client.resource.ClientResource;
import org.keycloak.admin.client.resource.ClientScopeResource;
import org.keycloak.protocol.oidc.mappers.OIDCAttributeMapperHelper;
import org.keycloak.representations.IDToken;
import org.keycloak.representations.idm.IdentityProviderRepresentation;
import org.keycloak.representations.idm.UserRepresentation;
import org.keycloak.testframework.annotations.KeycloakIntegrationTest;
import org.keycloak.tests.broker.AbstractKcOidcBrokerTest;
import org.keycloak.tests.utils.admin.AdminApiUtil;
import org.keycloak.testsuite.util.AccountHelper;

import org.junit.jupiter.api.Test;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;

@KeycloakIntegrationTest
public class KcOidcBrokerTest extends AbstractKcOidcBrokerTest {

@Test
public void testTrustEmailWhenEmailVerifiedClaimIsMissingFromUserInfo() {
IdentityProviderRepresentation idp = consumerRealm.admin().identityProviders().get(getIdpAlias()).toRepresentation();
idp.setTrustEmail(true);
idp.getConfig().put("disableUserInfo", "false");
consumerRealm.admin().identityProviders().get(getIdpAlias()).update(idp);

// Send the email only through UserInfo and omit email_verified.
ClientScopeResource emailScope = AdminApiUtil.findClientScopeByName(providerRealm.admin(), "email");
emailScope.getProtocolMappers().getMappers().forEach(mapper -> {
if (IDToken.EMAIL_VERIFIED.equals(mapper.getConfig().get(OIDCAttributeMapperHelper.TOKEN_CLAIM_NAME))) {
emailScope.getProtocolMappers().delete(mapper.getId());
} else if (IDToken.EMAIL.equals(mapper.getConfig().get(OIDCAttributeMapperHelper.TOKEN_CLAIM_NAME))) {
mapper.getConfig().put(OIDCAttributeMapperHelper.INCLUDE_IN_ID_TOKEN, "false");
emailScope.getProtocolMappers().update(mapper.getId(), mapper);
}
});
ClientResource providerClient = providerRealm.admin().clients().get(
providerRealm.admin().clients().findByClientId(CLIENT_ID).get(0).getId());
providerClient.getProtocolMappers().getMappers().forEach(mapper -> {
if (IDToken.EMAIL.equals(mapper.getConfig().get(OIDCAttributeMapperHelper.TOKEN_CLAIM_NAME))) {
mapper.getConfig().put(OIDCAttributeMapperHelper.INCLUDE_IN_ID_TOKEN, "false");
providerClient.getProtocolMappers().update(mapper.getId(), mapper);
}
});

disableUpdateProfileOnFirstLogin();
logInAsUserInIDP();
assertTrue(oauth.parseLoginResponse().isSuccess());
UserRepresentation consumerUser = AccountHelper.getUserRepresentation(consumerRealm.admin(), getUserLogin());
assertEquals(getUserEmail(), consumerUser.getEmail());
assertTrue(consumerUser.isEmailVerified());
}
}
Loading