mirror of
https://github.com/keycloak/keycloak.git
synced 2026-01-09 15:02:05 -03:30
Allow identity provider configuration without defaults for user authentication (#43963)
Closes #43552 Signed-off-by: stianst <stianst@gmail.com>
This commit is contained in:
parent
a9a14bd346
commit
b278dbbb3d
@ -49,14 +49,14 @@ public class IdentityProviderRepresentation {
|
||||
* @see #UPFLM_OFF
|
||||
*/
|
||||
@Deprecated
|
||||
protected String updateProfileFirstLoginMode = UPFLM_ON;
|
||||
protected String updateProfileFirstLoginMode;
|
||||
|
||||
protected boolean trustEmail;
|
||||
protected boolean storeToken;
|
||||
protected boolean addReadTokenRoleOnCreate;
|
||||
protected boolean authenticateByDefault;
|
||||
protected boolean linkOnly;
|
||||
protected boolean hideOnLogin;
|
||||
protected Boolean trustEmail;
|
||||
protected Boolean storeToken;
|
||||
protected Boolean addReadTokenRoleOnCreate;
|
||||
protected Boolean authenticateByDefault;
|
||||
protected Boolean linkOnly;
|
||||
protected Boolean hideOnLogin;
|
||||
protected String firstBrokerLoginFlowAlias;
|
||||
protected String postBrokerLoginFlowAlias;
|
||||
protected String organizationId;
|
||||
@ -103,19 +103,19 @@ public class IdentityProviderRepresentation {
|
||||
this.enabled = enabled;
|
||||
}
|
||||
|
||||
public boolean isLinkOnly() {
|
||||
public Boolean isLinkOnly() {
|
||||
return linkOnly;
|
||||
}
|
||||
|
||||
public void setLinkOnly(boolean linkOnly) {
|
||||
public void setLinkOnly(Boolean linkOnly) {
|
||||
this.linkOnly = linkOnly;
|
||||
}
|
||||
|
||||
public boolean isHideOnLogin() {
|
||||
public Boolean isHideOnLogin() {
|
||||
return this.hideOnLogin;
|
||||
}
|
||||
|
||||
public void setHideOnLogin(boolean hideOnLogin) {
|
||||
public void setHideOnLogin(Boolean hideOnLogin) {
|
||||
this.hideOnLogin = hideOnLogin;
|
||||
}
|
||||
|
||||
@ -126,8 +126,8 @@ public class IdentityProviderRepresentation {
|
||||
* @deprecated {@link #setUpdateProfileFirstLoginMode(String)}
|
||||
*/
|
||||
@Deprecated
|
||||
public void setUpdateProfileFirstLogin(boolean updateProfileFirstLogin) {
|
||||
this.updateProfileFirstLoginMode = updateProfileFirstLogin ? UPFLM_ON : UPFLM_OFF;
|
||||
public void setUpdateProfileFirstLogin(Boolean updateProfileFirstLogin) {
|
||||
this.updateProfileFirstLoginMode = updateProfileFirstLogin == null ? null : (updateProfileFirstLogin ? UPFLM_ON : UPFLM_OFF);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -150,12 +150,12 @@ public class IdentityProviderRepresentation {
|
||||
* @deprecated Replaced by configuration option in identity provider authenticator
|
||||
*/
|
||||
@Deprecated
|
||||
public boolean isAuthenticateByDefault() {
|
||||
public Boolean isAuthenticateByDefault() {
|
||||
return authenticateByDefault;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public void setAuthenticateByDefault(boolean authenticateByDefault) {
|
||||
public void setAuthenticateByDefault(Boolean authenticateByDefault) {
|
||||
this.authenticateByDefault = authenticateByDefault;
|
||||
}
|
||||
|
||||
@ -175,27 +175,27 @@ public class IdentityProviderRepresentation {
|
||||
this.postBrokerLoginFlowAlias = postBrokerLoginFlowAlias;
|
||||
}
|
||||
|
||||
public boolean isStoreToken() {
|
||||
public Boolean isStoreToken() {
|
||||
return this.storeToken;
|
||||
}
|
||||
|
||||
public void setStoreToken(boolean storeToken) {
|
||||
public void setStoreToken(Boolean storeToken) {
|
||||
this.storeToken = storeToken;
|
||||
}
|
||||
|
||||
public boolean isAddReadTokenRoleOnCreate() {
|
||||
public Boolean isAddReadTokenRoleOnCreate() {
|
||||
return addReadTokenRoleOnCreate;
|
||||
}
|
||||
|
||||
public void setAddReadTokenRoleOnCreate(boolean addReadTokenRoleOnCreate) {
|
||||
public void setAddReadTokenRoleOnCreate(Boolean addReadTokenRoleOnCreate) {
|
||||
this.addReadTokenRoleOnCreate = addReadTokenRoleOnCreate;
|
||||
}
|
||||
|
||||
public boolean isTrustEmail() {
|
||||
public Boolean isTrustEmail() {
|
||||
return trustEmail;
|
||||
}
|
||||
|
||||
public void setTrustEmail(boolean trustEmail) {
|
||||
public void setTrustEmail(Boolean trustEmail) {
|
||||
this.trustEmail = trustEmail;
|
||||
}
|
||||
|
||||
|
||||
38
core/src/main/java/org/keycloak/util/Booleans.java
Normal file
38
core/src/main/java/org/keycloak/util/Booleans.java
Normal file
@ -0,0 +1,38 @@
|
||||
package org.keycloak.util;
|
||||
|
||||
public class Booleans {
|
||||
|
||||
/**
|
||||
* Checks if a boolean is true, including support for null values where null is considered false
|
||||
*
|
||||
* @param b the boolean to check
|
||||
* @return true if non-null and true
|
||||
*/
|
||||
public static Boolean isTrue(Boolean b) {
|
||||
return b != null && b;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a boolean is false, including support for null values where null is considered false
|
||||
*
|
||||
* @param b the boolean to check
|
||||
* @return true if null and false
|
||||
*/
|
||||
public static Boolean isFalse(Boolean b) {
|
||||
return b == null || !b;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares two boolean, including support for null values where null is considered false
|
||||
*
|
||||
* @param a the first boolean to compare
|
||||
* @param b the second boolean to compare
|
||||
* @return true if both values have resolves to the same value
|
||||
*/
|
||||
public static Boolean equals(Boolean a, Boolean b) {
|
||||
a = a != null && a;
|
||||
b = b != null && b;
|
||||
return a.equals(b);
|
||||
}
|
||||
|
||||
}
|
||||
@ -30,6 +30,10 @@ For anyone implementing a custom federated user authentication identity provider
|
||||
by Keycloak or `AbstractIdentityProvider` you need to update your implementation to implement
|
||||
the new `UserAuthenticationIdentityProvider` interface (all methods remain the same, they have just been moved).
|
||||
|
||||
Additionally, both `IdentityProviderModel` and `IdentityProviderRepresentation` are now using Boolean values to allow
|
||||
configuration like `isHideOnLogin` to be null in order to not include these in Identity Provider types that do
|
||||
not need these configurations.
|
||||
|
||||
=== Accepting only normalized paths in requests
|
||||
|
||||
Previously {project_name} accepted HTTP requests with paths containing double dots (`..`) or double slashes (`//`). When processing them, it normalized the path by collapsing double slashes and normalized the path according to RFC3986.
|
||||
|
||||
@ -31,6 +31,7 @@ import jakarta.persistence.criteria.CriteriaBuilder;
|
||||
import jakarta.persistence.criteria.CriteriaDelete;
|
||||
import jakarta.persistence.criteria.CriteriaQuery;
|
||||
import jakarta.persistence.criteria.MapJoin;
|
||||
import jakarta.persistence.criteria.Path;
|
||||
import jakarta.persistence.criteria.Predicate;
|
||||
import jakarta.persistence.criteria.Root;
|
||||
import org.hibernate.Session;
|
||||
@ -252,10 +253,11 @@ public class JpaIdentityProviderStorageProvider implements IdentityProviderStora
|
||||
case ENABLED:
|
||||
case HIDE_ON_LOGIN:
|
||||
case LINK_ONLY: {
|
||||
Path<Boolean> path = idp.get(key);
|
||||
if (Boolean.parseBoolean(value)) {
|
||||
predicates.add(builder.isTrue(idp.get(key)));
|
||||
predicates.add(builder.isTrue(path));
|
||||
} else {
|
||||
predicates.add(builder.isFalse(idp.get(key)));
|
||||
predicates.add(builder.or(builder.isNull(path), builder.equal(path, Boolean.FALSE)));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
@ -57,22 +57,22 @@ public class IdentityProviderEntity {
|
||||
private boolean enabled;
|
||||
|
||||
@Column(name = "TRUST_EMAIL")
|
||||
private boolean trustEmail;
|
||||
private Boolean trustEmail;
|
||||
|
||||
@Column(name="STORE_TOKEN")
|
||||
private boolean storeToken;
|
||||
private Boolean storeToken;
|
||||
|
||||
@Column(name="LINK_ONLY")
|
||||
private boolean linkOnly;
|
||||
private Boolean linkOnly;
|
||||
|
||||
@Column(name="HIDE_ON_LOGIN")
|
||||
private boolean hideOnLogin;
|
||||
private Boolean hideOnLogin;
|
||||
|
||||
@Column(name="ADD_TOKEN_ROLE")
|
||||
protected boolean addReadTokenRoleOnCreate;
|
||||
protected Boolean addReadTokenRoleOnCreate;
|
||||
|
||||
@Column(name="AUTHENTICATE_BY_DEFAULT")
|
||||
private boolean authenticateByDefault;
|
||||
private Boolean authenticateByDefault;
|
||||
|
||||
@Column(name="FIRST_BROKER_LOGIN_FLOW_ID")
|
||||
private String firstBrokerLoginFlowId;
|
||||
@ -129,27 +129,27 @@ public class IdentityProviderEntity {
|
||||
this.enabled = enabled;
|
||||
}
|
||||
|
||||
public boolean isStoreToken() {
|
||||
public Boolean isStoreToken() {
|
||||
return this.storeToken;
|
||||
}
|
||||
|
||||
public void setStoreToken(boolean storeToken) {
|
||||
public void setStoreToken(Boolean storeToken) {
|
||||
this.storeToken = storeToken;
|
||||
}
|
||||
|
||||
public boolean isAuthenticateByDefault() {
|
||||
public Boolean isAuthenticateByDefault() {
|
||||
return authenticateByDefault;
|
||||
}
|
||||
|
||||
public void setAuthenticateByDefault(boolean authenticateByDefault) {
|
||||
public void setAuthenticateByDefault(Boolean authenticateByDefault) {
|
||||
this.authenticateByDefault = authenticateByDefault;
|
||||
}
|
||||
|
||||
public boolean isLinkOnly() {
|
||||
public Boolean isLinkOnly() {
|
||||
return linkOnly;
|
||||
}
|
||||
|
||||
public void setLinkOnly(boolean linkOnly) {
|
||||
public void setLinkOnly(Boolean linkOnly) {
|
||||
this.linkOnly = linkOnly;
|
||||
}
|
||||
|
||||
@ -177,11 +177,11 @@ public class IdentityProviderEntity {
|
||||
this.organizationId = organizationId;
|
||||
}
|
||||
|
||||
public boolean isHideOnLogin() {
|
||||
public Boolean isHideOnLogin() {
|
||||
return this.hideOnLogin;
|
||||
}
|
||||
|
||||
public void setHideOnLogin(boolean hideOnLogin) {
|
||||
public void setHideOnLogin(Boolean hideOnLogin) {
|
||||
this.hideOnLogin = hideOnLogin;
|
||||
}
|
||||
|
||||
@ -193,19 +193,19 @@ public class IdentityProviderEntity {
|
||||
this.config = config;
|
||||
}
|
||||
|
||||
public boolean isAddReadTokenRoleOnCreate() {
|
||||
public Boolean isAddReadTokenRoleOnCreate() {
|
||||
return addReadTokenRoleOnCreate;
|
||||
}
|
||||
|
||||
public void setAddReadTokenRoleOnCreate(boolean addReadTokenRoleOnCreate) {
|
||||
public void setAddReadTokenRoleOnCreate(Boolean addReadTokenRoleOnCreate) {
|
||||
this.addReadTokenRoleOnCreate = addReadTokenRoleOnCreate;
|
||||
}
|
||||
|
||||
public boolean isTrustEmail() {
|
||||
public Boolean isTrustEmail() {
|
||||
return trustEmail;
|
||||
}
|
||||
|
||||
public void setTrustEmail(boolean trustEmail) {
|
||||
public void setTrustEmail(Boolean trustEmail) {
|
||||
this.trustEmail = trustEmail;
|
||||
}
|
||||
|
||||
|
||||
@ -58,4 +58,19 @@
|
||||
</modifySql>
|
||||
</changeSet>
|
||||
|
||||
<changeSet author="keycloak" id="26.5.0-idp-config-allow-null">
|
||||
<dropDefaultValue tableName="IDENTITY_PROVIDER" columnName="TRUST_EMAIL"/>
|
||||
<dropNotNullConstraint tableName="IDENTITY_PROVIDER" columnName="TRUST_EMAIL" columnDataType="BOOLEAN"/>
|
||||
<dropNotNullConstraint tableName="IDENTITY_PROVIDER" columnName="STORE_TOKEN" columnDataType="BOOLEAN"/>
|
||||
<dropDefaultValue tableName="IDENTITY_PROVIDER" columnName="STORE_TOKEN"/>
|
||||
<dropDefaultValue tableName="IDENTITY_PROVIDER" columnName="ADD_TOKEN_ROLE"/>
|
||||
<dropNotNullConstraint tableName="IDENTITY_PROVIDER" columnName="ADD_TOKEN_ROLE" columnDataType="BOOLEAN"/>
|
||||
<dropDefaultValue tableName="IDENTITY_PROVIDER" columnName="AUTHENTICATE_BY_DEFAULT"/>
|
||||
<dropNotNullConstraint tableName="IDENTITY_PROVIDER" columnName="AUTHENTICATE_BY_DEFAULT" columnDataType="BOOLEAN"/>
|
||||
<dropDefaultValue tableName="IDENTITY_PROVIDER" columnName="LINK_ONLY"/>
|
||||
<dropNotNullConstraint tableName="IDENTITY_PROVIDER" columnName="LINK_ONLY" columnDataType="BOOLEAN"/>
|
||||
<!-- HIDE_ON_LOGIN did not have a non-null constraint -->
|
||||
<dropDefaultValue tableName="IDENTITY_PROVIDER" columnName="HIDE_ON_LOGIN"/>
|
||||
</changeSet>
|
||||
|
||||
</databaseChangeLog>
|
||||
|
||||
@ -110,6 +110,7 @@ import org.keycloak.storage.UserStorageProvider;
|
||||
import org.keycloak.storage.UserStorageProviderModel;
|
||||
import org.keycloak.storage.UserStorageUtil;
|
||||
import org.keycloak.storage.federated.UserFederatedStorageProvider;
|
||||
import org.keycloak.util.Booleans;
|
||||
import org.keycloak.util.JsonSerialization;
|
||||
import org.keycloak.utils.StringUtil;
|
||||
import org.keycloak.validation.ValidationUtil;
|
||||
@ -1514,7 +1515,7 @@ public class DefaultExportImportManager implements ExportImportManager {
|
||||
String defaultProvider = null;
|
||||
if (rep.getIdentityProviders() != null) {
|
||||
for (IdentityProviderRepresentation i : rep.getIdentityProviders()) {
|
||||
if (i.isEnabled() && i.isAuthenticateByDefault()) {
|
||||
if (i.isEnabled() && Booleans.isTrue(i.isAuthenticateByDefault())) {
|
||||
defaultProvider = i.getProviderId();
|
||||
break;
|
||||
}
|
||||
|
||||
@ -28,6 +28,7 @@ import org.keycloak.models.RealmModel;
|
||||
import org.keycloak.models.UserModel;
|
||||
import org.keycloak.models.UserSessionModel;
|
||||
import org.keycloak.sessions.AuthenticationSessionModel;
|
||||
import org.keycloak.util.Booleans;
|
||||
|
||||
import jakarta.ws.rs.core.MediaType;
|
||||
import jakarta.ws.rs.core.Response;
|
||||
@ -206,7 +207,7 @@ public abstract class AbstractIdentityProvider<C extends IdentityProviderModel>
|
||||
|
||||
if (isNewUser || federatedEmail != null && !federatedEmail.equalsIgnoreCase(localEmail)) {
|
||||
IdentityProviderModel config = context.getIdpConfig();
|
||||
boolean trustEmail = config.isTrustEmail();
|
||||
boolean trustEmail = Booleans.isTrue(config.isTrustEmail());
|
||||
|
||||
if (logger.isTraceEnabled()) {
|
||||
logger.tracef("Email %s verified automatically after updating user '%s' through Identity provider '%s' ", trustEmail ? "" : "not", user.getUsername(), config.getAlias());
|
||||
|
||||
@ -13,7 +13,11 @@ public final class IdentityProviderMapperSyncModeDelegate {
|
||||
protected static final Logger logger = Logger.getLogger(IdentityProviderMapperSyncModeDelegate.class);
|
||||
|
||||
public static void delegateUpdateBrokeredUser(KeycloakSession session, RealmModel realm, UserModel user, IdentityProviderMapperModel mapperModel, BrokeredIdentityContext context, IdentityProviderMapper mapper) {
|
||||
IdentityProviderSyncMode effectiveSyncMode = combineIdpAndMapperSyncMode(context.getIdpConfig().getSyncMode(), mapperModel.getSyncMode());
|
||||
IdentityProviderSyncMode idpSyncMode = context.getIdpConfig().getSyncMode();
|
||||
if (idpSyncMode == null) {
|
||||
idpSyncMode = IdentityProviderSyncMode.LEGACY;
|
||||
}
|
||||
IdentityProviderSyncMode effectiveSyncMode = combineIdpAndMapperSyncMode(idpSyncMode, mapperModel.getSyncMode());
|
||||
|
||||
if (!mapper.supportsSyncMode(effectiveSyncMode)) {
|
||||
logger.warnf("The mapper %s does not explicitly support sync mode %s. Please ensure that the SPI supports the sync mode correctly and update it to reflect this.", mapper.getDisplayType(), effectiveSyncMode);
|
||||
|
||||
@ -890,11 +890,6 @@ public class ModelToRepresentation {
|
||||
providerRep.setConfig(config);
|
||||
providerRep.setAddReadTokenRoleOnCreate(identityProviderModel.isAddReadTokenRoleOnCreate());
|
||||
|
||||
String syncMode = config.get(IdentityProviderModel.SYNC_MODE);
|
||||
if (syncMode == null) {
|
||||
config.put(IdentityProviderModel.SYNC_MODE, "LEGACY");
|
||||
}
|
||||
|
||||
String firstBrokerLoginFlowId = identityProviderModel.getFirstBrokerLoginFlowId();
|
||||
if (firstBrokerLoginFlowId != null) {
|
||||
AuthenticationFlowModel flow = realm.getAuthenticationFlowById(firstBrokerLoginFlowId);
|
||||
|
||||
@ -75,18 +75,18 @@ public class IdentityProviderModel implements Serializable {
|
||||
|
||||
private boolean enabled;
|
||||
|
||||
private boolean trustEmail;
|
||||
private Boolean trustEmail;
|
||||
|
||||
private boolean storeToken;
|
||||
private Boolean storeToken;
|
||||
|
||||
protected boolean addReadTokenRoleOnCreate;
|
||||
protected Boolean addReadTokenRoleOnCreate;
|
||||
|
||||
protected boolean linkOnly;
|
||||
protected Boolean linkOnly;
|
||||
|
||||
/**
|
||||
* Specifies if particular provider should be used by default for authentication even before displaying login screen
|
||||
*/
|
||||
private boolean authenticateByDefault;
|
||||
private Boolean authenticateByDefault;
|
||||
|
||||
private String firstBrokerLoginFlowId;
|
||||
|
||||
@ -98,7 +98,7 @@ public class IdentityProviderModel implements Serializable {
|
||||
|
||||
private String displayIconClasses;
|
||||
|
||||
private boolean hideOnLogin;
|
||||
private Boolean hideOnLogin;
|
||||
|
||||
/**
|
||||
* <p>A map containing the configuration and properties for a specific identity provider instance and implementation. The items
|
||||
@ -162,29 +162,29 @@ public class IdentityProviderModel implements Serializable {
|
||||
this.enabled = enabled;
|
||||
}
|
||||
|
||||
public boolean isStoreToken() {
|
||||
public Boolean isStoreToken() {
|
||||
return this.storeToken;
|
||||
}
|
||||
|
||||
public void setStoreToken(boolean storeToken) {
|
||||
public void setStoreToken(Boolean storeToken) {
|
||||
this.storeToken = storeToken;
|
||||
}
|
||||
|
||||
public boolean isLinkOnly() {
|
||||
public Boolean isLinkOnly() {
|
||||
return linkOnly;
|
||||
}
|
||||
|
||||
public void setLinkOnly(boolean linkOnly) {
|
||||
public void setLinkOnly(Boolean linkOnly) {
|
||||
this.linkOnly = linkOnly;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public boolean isAuthenticateByDefault() {
|
||||
public Boolean isAuthenticateByDefault() {
|
||||
return authenticateByDefault;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public void setAuthenticateByDefault(boolean authenticateByDefault) {
|
||||
public void setAuthenticateByDefault(Boolean authenticateByDefault) {
|
||||
this.authenticateByDefault = authenticateByDefault;
|
||||
}
|
||||
|
||||
@ -212,19 +212,19 @@ public class IdentityProviderModel implements Serializable {
|
||||
this.config = config;
|
||||
}
|
||||
|
||||
public boolean isAddReadTokenRoleOnCreate() {
|
||||
public Boolean isAddReadTokenRoleOnCreate() {
|
||||
return addReadTokenRoleOnCreate;
|
||||
}
|
||||
|
||||
public void setAddReadTokenRoleOnCreate(boolean addReadTokenRoleOnCreate) {
|
||||
public void setAddReadTokenRoleOnCreate(Boolean addReadTokenRoleOnCreate) {
|
||||
this.addReadTokenRoleOnCreate = addReadTokenRoleOnCreate;
|
||||
}
|
||||
|
||||
public boolean isTrustEmail() {
|
||||
public Boolean isTrustEmail() {
|
||||
return trustEmail;
|
||||
}
|
||||
|
||||
public void setTrustEmail(boolean trustEmail) {
|
||||
public void setTrustEmail(Boolean trustEmail) {
|
||||
this.trustEmail = trustEmail;
|
||||
}
|
||||
|
||||
@ -259,35 +259,35 @@ public class IdentityProviderModel implements Serializable {
|
||||
}
|
||||
|
||||
public IdentityProviderSyncMode getSyncMode() {
|
||||
return IdentityProviderSyncMode.valueOf(getConfig().getOrDefault(SYNC_MODE, "LEGACY"));
|
||||
String syncMode = getConfig().get(SYNC_MODE);
|
||||
return syncMode != null ? IdentityProviderSyncMode.valueOf(syncMode) : null;
|
||||
}
|
||||
|
||||
public void setSyncMode(IdentityProviderSyncMode syncMode) {
|
||||
getConfig().put(SYNC_MODE, syncMode.toString());
|
||||
getConfig().put(SYNC_MODE, syncMode != null ? syncMode.toString() : null);
|
||||
}
|
||||
|
||||
public boolean isLoginHint() {
|
||||
return Boolean.valueOf(getConfig().get(LOGIN_HINT));
|
||||
return getBooleanConfig(LOGIN_HINT);
|
||||
}
|
||||
|
||||
public void setLoginHint(boolean loginHint) {
|
||||
getConfig().put(LOGIN_HINT, String.valueOf(loginHint));
|
||||
public void setLoginHint(Boolean loginHint) {
|
||||
setBooleanConfig(LOGIN_HINT, loginHint);
|
||||
}
|
||||
|
||||
public boolean isPassMaxAge() {
|
||||
return Boolean.valueOf(getConfig().get(PASS_MAX_AGE));
|
||||
return getBooleanConfig(PASS_MAX_AGE);
|
||||
}
|
||||
|
||||
public void setPassMaxAge(boolean passMaxAge) {
|
||||
getConfig().put(PASS_MAX_AGE, String.valueOf(passMaxAge));
|
||||
public void setPassMaxAge(Boolean passMaxAge) {
|
||||
setBooleanConfig(PASS_MAX_AGE, passMaxAge);
|
||||
}
|
||||
|
||||
|
||||
public boolean isHideOnLogin() {
|
||||
public Boolean isHideOnLogin() {
|
||||
return this.hideOnLogin;
|
||||
}
|
||||
|
||||
public void setHideOnLogin(boolean hideOnLogin) {
|
||||
public void setHideOnLogin(Boolean hideOnLogin) {
|
||||
this.hideOnLogin = hideOnLogin;
|
||||
}
|
||||
|
||||
@ -297,23 +297,23 @@ public class IdentityProviderModel implements Serializable {
|
||||
* @return
|
||||
*/
|
||||
public boolean isTransientUsers() {
|
||||
return Profile.isFeatureEnabled(Feature.TRANSIENT_USERS) && Boolean.valueOf(getConfig().get(DO_NOT_STORE_USERS));
|
||||
return Profile.isFeatureEnabled(Feature.TRANSIENT_USERS) && getBooleanConfig(DO_NOT_STORE_USERS);
|
||||
}
|
||||
|
||||
/**
|
||||
* Configures the IdP to not store users in Keycloak database. Default value: {@code false}.
|
||||
* @return
|
||||
*/
|
||||
public void setTransientUsers(boolean transientUsers) {
|
||||
getConfig().put(DO_NOT_STORE_USERS, String.valueOf(transientUsers));
|
||||
public void setTransientUsers(Boolean transientUsers) {
|
||||
setBooleanConfig(DO_NOT_STORE_USERS, transientUsers);
|
||||
}
|
||||
|
||||
public boolean isFilteredByClaims() {
|
||||
return Boolean.valueOf(getConfig().getOrDefault(FILTERED_BY_CLAIMS, Boolean.toString(false)));
|
||||
return getBooleanConfig(FILTERED_BY_CLAIMS);
|
||||
}
|
||||
|
||||
public void setFilteredByClaims(boolean filteredByClaims) {
|
||||
getConfig().put(FILTERED_BY_CLAIMS, String.valueOf(filteredByClaims));
|
||||
public void setFilteredByClaims(Boolean filteredByClaims) {
|
||||
setBooleanConfig(FILTERED_BY_CLAIMS, filteredByClaims);
|
||||
}
|
||||
|
||||
public String getClaimFilterName() {
|
||||
@ -341,11 +341,11 @@ public class IdentityProviderModel implements Serializable {
|
||||
}
|
||||
|
||||
public boolean isCaseSensitiveOriginalUsername() {
|
||||
return Boolean.parseBoolean(getConfig().getOrDefault(CASE_SENSITIVE_ORIGINAL_USERNAME, Boolean.FALSE.toString()));
|
||||
return getBooleanConfig(CASE_SENSITIVE_ORIGINAL_USERNAME);
|
||||
}
|
||||
|
||||
public void setCaseSensitiveOriginalUsername(boolean caseSensitive) {
|
||||
getConfig().put(CASE_SENSITIVE_ORIGINAL_USERNAME, Boolean.valueOf(caseSensitive).toString());
|
||||
public void setCaseSensitiveOriginalUsername(Boolean caseSensitive) {
|
||||
setBooleanConfig(CASE_SENSITIVE_ORIGINAL_USERNAME, caseSensitive);
|
||||
}
|
||||
|
||||
public void setMinValidityToken(int minValidityToken) {
|
||||
@ -386,4 +386,14 @@ public class IdentityProviderModel implements Serializable {
|
||||
return Objects.equals(getInternalId(), ((IdentityProviderModel) obj).getInternalId()) &&
|
||||
Objects.equals(getAlias(), ((IdentityProviderModel) obj).getAlias());
|
||||
}
|
||||
|
||||
private boolean getBooleanConfig(String key) {
|
||||
String value = getConfig().get(key);
|
||||
return value != null ? Boolean.parseBoolean(value) : Boolean.FALSE;
|
||||
}
|
||||
|
||||
private void setBooleanConfig(String key, Boolean value) {
|
||||
getConfig().put(key, value != null ? String.valueOf(value) : null);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -23,6 +23,7 @@ import java.util.function.Predicate;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.keycloak.util.Booleans;
|
||||
import org.keycloak.provider.Provider;
|
||||
|
||||
/**
|
||||
@ -236,9 +237,9 @@ public interface IdentityProviderStorageProvider extends Provider {
|
||||
|
||||
ENABLED(IdentityProviderModel.ENABLED, Boolean.TRUE.toString(), IdentityProviderModel::isEnabled),
|
||||
|
||||
LINK_ONLY(IdentityProviderModel.LINK_ONLY, Boolean.FALSE.toString(), Predicate.not(IdentityProviderModel::isLinkOnly)),
|
||||
LINK_ONLY(IdentityProviderModel.LINK_ONLY, Boolean.FALSE.toString(), m -> Booleans.isFalse(m.isLinkOnly())),
|
||||
|
||||
HIDE_ON_LOGIN(IdentityProviderModel.HIDE_ON_LOGIN, Boolean.FALSE.toString(), Predicate.not(IdentityProviderModel::isHideOnLogin));
|
||||
HIDE_ON_LOGIN(IdentityProviderModel.HIDE_ON_LOGIN, Boolean.FALSE.toString(), m -> Booleans.isFalse(m.isHideOnLogin()));
|
||||
|
||||
private final String key;
|
||||
private final String value;
|
||||
|
||||
@ -17,7 +17,7 @@ public class KubernetesIdentityProviderConfig extends OIDCIdentityProviderConfig
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isHideOnLogin() {
|
||||
public Boolean isHideOnLogin() {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@ -90,6 +90,7 @@ import org.keycloak.services.messages.Messages;
|
||||
import org.keycloak.services.resources.RealmsResource;
|
||||
import org.keycloak.sessions.AuthenticationSessionModel;
|
||||
import org.keycloak.urls.UrlType;
|
||||
import org.keycloak.util.Booleans;
|
||||
import org.keycloak.util.JsonSerialization;
|
||||
import org.keycloak.utils.StringUtil;
|
||||
import org.keycloak.vault.VaultStringSecret;
|
||||
@ -357,7 +358,7 @@ public abstract class AbstractOAuth2IdentityProvider<C extends OAuth2IdentityPro
|
||||
event.error(Errors.INVALID_REQUEST);
|
||||
return exchangeUnsupportedRequiredType();
|
||||
}
|
||||
if (!getConfig().isStoreToken()) {
|
||||
if (Booleans.isFalse(getConfig().isStoreToken())) {
|
||||
// if token isn't stored, we need to see if this session has been linked
|
||||
String brokerId = tokenUserSession.getNote(Details.IDENTITY_PROVIDER);
|
||||
brokerId = brokerId == null ? tokenUserSession.getNote(UserAuthenticationIdentityProvider.EXTERNAL_IDENTITY_PROVIDER) : brokerId;
|
||||
@ -474,7 +475,7 @@ public abstract class AbstractOAuth2IdentityProvider<C extends OAuth2IdentityPro
|
||||
|
||||
BrokeredIdentityContext context = doGetFederatedIdentity(accessToken);
|
||||
|
||||
if (getConfig().isStoreToken() && response.startsWith("{")) {
|
||||
if (Booleans.isTrue(getConfig().isStoreToken()) && response.startsWith("{")) {
|
||||
try {
|
||||
OAuthResponse tokenResponse = JsonSerialization.readValue(response, OAuthResponse.class);
|
||||
if (tokenResponse.getExpiresIn() != null && tokenResponse.getExpiresIn() > 0) {
|
||||
@ -512,7 +513,7 @@ public abstract class AbstractOAuth2IdentityProvider<C extends OAuth2IdentityPro
|
||||
AuthenticationSessionModel authenticationSession = request.getAuthenticationSession();
|
||||
String loginHint = authenticationSession.getClientNote(OIDCLoginProtocol.LOGIN_HINT_PARAM);
|
||||
|
||||
if (getConfig().isLoginHint() && loginHint != null) {
|
||||
if (Booleans.isTrue(getConfig().isLoginHint()) && loginHint != null) {
|
||||
uriBuilder.queryParam(OIDCLoginProtocol.LOGIN_HINT_PARAM, loginHint);
|
||||
}
|
||||
|
||||
@ -745,7 +746,7 @@ public abstract class AbstractOAuth2IdentityProvider<C extends OAuth2IdentityPro
|
||||
|
||||
BrokeredIdentityContext federatedIdentity = provider.getFederatedIdentity(response);
|
||||
|
||||
if (providerConfig.isStoreToken()) {
|
||||
if (Booleans.isTrue(providerConfig.isStoreToken())) {
|
||||
// make sure that token wasn't already set by getFederatedIdentity();
|
||||
// want to be able to allow provider to set the token itself.
|
||||
if (federatedIdentity.getToken() == null)federatedIdentity.setToken(response);
|
||||
|
||||
@ -80,6 +80,7 @@ import org.keycloak.services.messages.Messages;
|
||||
import org.keycloak.services.resources.IdentityBrokerService;
|
||||
import org.keycloak.services.resources.RealmsResource;
|
||||
import org.keycloak.sessions.AuthenticationSessionModel;
|
||||
import org.keycloak.util.Booleans;
|
||||
import org.keycloak.util.JsonSerialization;
|
||||
import org.keycloak.util.TokenUtil;
|
||||
import org.keycloak.vault.VaultStringSecret;
|
||||
@ -413,7 +414,7 @@ public class OIDCIdentityProvider extends AbstractOAuth2IdentityProvider<OIDCIde
|
||||
|
||||
JsonWebToken idToken = validateToken(encodedIdToken);
|
||||
|
||||
if (getConfig().isPassMaxAge()) {
|
||||
if (Booleans.isTrue(getConfig().isPassMaxAge())) {
|
||||
AuthenticationSessionModel authSession = session.getContext().getAuthenticationSession();
|
||||
|
||||
if (isAuthTimeExpired(idToken, authSession)) {
|
||||
@ -464,7 +465,7 @@ public class OIDCIdentityProvider extends AbstractOAuth2IdentityProvider<OIDCIde
|
||||
identity.getContextData().put(BROKER_NONCE_PARAM, idToken.getOtherClaims().get(OIDCLoginProtocol.NONCE_PARAM));
|
||||
}
|
||||
|
||||
if (getConfig().isStoreToken()) {
|
||||
if (Booleans.isTrue(getConfig().isStoreToken())) {
|
||||
if (tokenResponse.getExpiresIn() > 0) {
|
||||
long accessTokenExpiration = Time.currentTime() + tokenResponse.getExpiresIn();
|
||||
tokenResponse.getOtherClaims().put(ACCESS_TOKEN_EXPIRATION, accessTokenExpiration);
|
||||
@ -976,7 +977,7 @@ public class OIDCIdentityProvider extends AbstractOAuth2IdentityProvider<OIDCIde
|
||||
|
||||
String maxAge = request.getAuthenticationSession().getClientNote(OIDCLoginProtocol.MAX_AGE_PARAM);
|
||||
|
||||
if (getConfig().isPassMaxAge() && maxAge != null) {
|
||||
if (Booleans.isTrue(getConfig().isPassMaxAge()) && maxAge != null) {
|
||||
uriBuilder.queryParam(OIDCLoginProtocol.MAX_AGE_PARAM, maxAge);
|
||||
}
|
||||
|
||||
@ -1023,7 +1024,7 @@ public class OIDCIdentityProvider extends AbstractOAuth2IdentityProvider<OIDCIde
|
||||
.orElseGet(() -> contextData.get(VALIDATED_ACCESS_TOKEN));
|
||||
Boolean emailVerified = getEmailVerifiedClaim(token);
|
||||
|
||||
if (!config.isTrustEmail() || emailVerified == null) {
|
||||
if (Booleans.isFalse(config.isTrustEmail()) || emailVerified == null) {
|
||||
// fallback to the default behavior if trust is disabled or there is no email_verified claim
|
||||
super.setEmailVerified(user, context);
|
||||
return;
|
||||
|
||||
@ -119,6 +119,7 @@ import org.keycloak.saml.validators.ConditionsValidator;
|
||||
import org.keycloak.saml.validators.DestinationValidator;
|
||||
import org.keycloak.services.util.CacheControlUtil;
|
||||
import org.keycloak.sessions.AuthenticationSessionModel;
|
||||
import org.keycloak.util.Booleans;
|
||||
import org.keycloak.utils.StringUtil;
|
||||
import org.w3c.dom.Element;
|
||||
import org.w3c.dom.NodeList;
|
||||
@ -658,7 +659,7 @@ public class SAMLEndpoint {
|
||||
identity.setEmail(subjectNameID.getValue());
|
||||
}
|
||||
|
||||
if (config.isStoreToken()) {
|
||||
if (Booleans.isTrue(config.isStoreToken())) {
|
||||
identity.setToken(samlResponse);
|
||||
}
|
||||
|
||||
|
||||
@ -84,6 +84,7 @@ import org.keycloak.saml.processing.core.saml.v2.util.SAMLMetadataUtil;
|
||||
import org.keycloak.saml.processing.core.util.KeycloakKeySamlExtensionGenerator;
|
||||
import org.keycloak.saml.validators.DestinationValidator;
|
||||
import org.keycloak.sessions.AuthenticationSessionModel;
|
||||
import org.keycloak.util.Booleans;
|
||||
import org.keycloak.util.JsonSerialization;
|
||||
|
||||
import org.w3c.dom.Document;
|
||||
@ -159,7 +160,7 @@ public class SAMLIdentityProvider extends AbstractIdentityProvider<SAMLIdentityP
|
||||
|
||||
Integer attributeConsumingServiceIndex = getConfig().getAttributeConsumingServiceIndex();
|
||||
|
||||
String loginHint = getConfig().isLoginHint() ? request.getAuthenticationSession().getClientNote(OIDCLoginProtocol.LOGIN_HINT_PARAM) : null;
|
||||
String loginHint = Booleans.isTrue(getConfig().isLoginHint()) ? request.getAuthenticationSession().getClientNote(OIDCLoginProtocol.LOGIN_HINT_PARAM) : null;
|
||||
Boolean allowCreate = null;
|
||||
if (getConfig().getConfig().get(SAMLIdentityProviderConfig.ALLOW_CREATE) == null || getConfig().isAllowCreate())
|
||||
allowCreate = Boolean.TRUE;
|
||||
|
||||
@ -29,7 +29,6 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import jakarta.ws.rs.core.MultivaluedHashMap;
|
||||
@ -66,6 +65,7 @@ import org.keycloak.organization.utils.Organizations;
|
||||
import org.keycloak.protocol.oidc.OIDCLoginProtocol;
|
||||
import org.keycloak.services.messages.Messages;
|
||||
import org.keycloak.sessions.AuthenticationSessionModel;
|
||||
import org.keycloak.util.Booleans;
|
||||
|
||||
public class OrganizationAuthenticator extends IdentityProviderAuthenticator {
|
||||
|
||||
@ -429,7 +429,7 @@ public class OrganizationAuthenticator extends IdentityProviderAuthenticator {
|
||||
}
|
||||
|
||||
private boolean hasPublicBrokers(OrganizationModel organization) {
|
||||
return organization.getIdentityProviders().anyMatch(Predicate.not(IdentityProviderModel::isHideOnLogin));
|
||||
return organization.getIdentityProviders().anyMatch(i -> Booleans.isFalse(i.isHideOnLogin()));
|
||||
}
|
||||
|
||||
private OrganizationProvider getOrganizationProvider() {
|
||||
|
||||
@ -25,6 +25,7 @@ import org.keycloak.forms.login.freemarker.model.IdentityProviderBean;
|
||||
import org.keycloak.models.IdentityProviderModel;
|
||||
import org.keycloak.models.OrganizationModel;
|
||||
import org.keycloak.organization.utils.Organizations;
|
||||
import org.keycloak.util.Booleans;
|
||||
|
||||
import static org.keycloak.models.IdentityProviderStorageProvider.FetchMode.ALL;
|
||||
import static org.keycloak.models.IdentityProviderStorageProvider.FetchMode.ORG_ONLY;
|
||||
@ -64,7 +65,7 @@ public class OrganizationAwareIdentityProviderBean extends IdentityProviderBean
|
||||
// we already have the organization, just fetch the organization's public enabled IDPs.
|
||||
if (this.organization != null) {
|
||||
return organization.getIdentityProviders()
|
||||
.filter(idp -> idp.isEnabled() && !idp.isLinkOnly() && !idp.isHideOnLogin())
|
||||
.filter(idp -> idp.isEnabled() && Booleans.isFalse(idp.isLinkOnly()) && Booleans.isFalse(idp.isHideOnLogin()))
|
||||
.filter(idp -> !Objects.equals(existingIDP, idp.getAlias()))
|
||||
.map(idp -> createIdentityProvider(super.realm, super.baseURI, idp))
|
||||
.sorted(IDP_COMPARATOR_INSTANCE).toList();
|
||||
@ -103,6 +104,6 @@ public class OrganizationAwareIdentityProviderBean extends IdentityProviderBean
|
||||
if (organization != null && !Objects.equals(organization.getId(),idp.getOrganizationId())) {
|
||||
return false;
|
||||
}
|
||||
return !idp.isHideOnLogin();
|
||||
return Booleans.isFalse(idp.isHideOnLogin());
|
||||
}
|
||||
}
|
||||
|
||||
@ -63,6 +63,7 @@ import org.keycloak.services.resources.admin.fgap.AdminPermissions;
|
||||
import org.keycloak.services.validation.Validation;
|
||||
import org.keycloak.sessions.AuthenticationSessionModel;
|
||||
import org.keycloak.sessions.RootAuthenticationSessionModel;
|
||||
import org.keycloak.util.Booleans;
|
||||
|
||||
import static org.keycloak.authentication.authenticators.util.AuthenticatorUtils.getDisabledByBruteForceEventError;
|
||||
import static org.keycloak.models.IdentityProviderType.EXCHANGE_EXTERNAL_TOKEN;
|
||||
@ -389,7 +390,7 @@ public abstract class AbstractTokenExchangeProvider implements TokenExchangeProv
|
||||
target.importNewUser(session, realm, user, mapper, context);
|
||||
}
|
||||
|
||||
if (context.getIdpConfig().isTrustEmail() && !Validation.isBlank(user.getEmail())) {
|
||||
if (Booleans.isTrue(context.getIdpConfig().isTrustEmail()) && !Validation.isBlank(user.getEmail())) {
|
||||
logger.debugf("Email verified automatically after registration of user '%s' through Identity provider '%s' ", user.getUsername(), context.getIdpConfig().getAlias());
|
||||
user.setEmailVerified(true);
|
||||
}
|
||||
|
||||
@ -96,6 +96,7 @@ import org.keycloak.services.util.DefaultClientSessionContext;
|
||||
import org.keycloak.services.validation.Validation;
|
||||
import org.keycloak.sessions.AuthenticationSessionModel;
|
||||
import org.keycloak.sessions.RootAuthenticationSessionModel;
|
||||
import org.keycloak.util.Booleans;
|
||||
import org.keycloak.util.JsonSerialization;
|
||||
|
||||
import jakarta.ws.rs.GET;
|
||||
@ -395,7 +396,7 @@ public class IdentityBrokerService implements UserAuthenticationIdentityProvider
|
||||
if (identityProviderModel == null) {
|
||||
throw new IdentityBrokerException("Identity Provider [" + providerAlias + "] not found.");
|
||||
}
|
||||
if (identityProviderModel.isLinkOnly()) {
|
||||
if (Booleans.isTrue(identityProviderModel.isLinkOnly())) {
|
||||
throw new IdentityBrokerException("Identity Provider [" + providerAlias + "] is not allowed to perform a login.");
|
||||
}
|
||||
if (clientSessionCode.getClientSession() != null && loginHint != null) {
|
||||
@ -504,7 +505,7 @@ public class IdentityBrokerService implements UserAuthenticationIdentityProvider
|
||||
UserAuthenticationIdentityProvider<?> identityProvider = getIdentityProvider(session, providerAlias);
|
||||
IdentityProviderModel identityProviderConfig = getIdentityProviderConfig(providerAlias);
|
||||
|
||||
if (identityProviderConfig.isStoreToken()) {
|
||||
if (Booleans.isTrue(identityProviderConfig.isStoreToken())) {
|
||||
FederatedIdentityModel identity = this.session.users().getFederatedIdentity(this.realmModel, authResult.user(), providerAlias);
|
||||
|
||||
if (identity == null) {
|
||||
@ -553,7 +554,7 @@ public class IdentityBrokerService implements UserAuthenticationIdentityProvider
|
||||
AuthenticationSessionModel authenticationSession = context.getAuthenticationSession();
|
||||
|
||||
String providerAlias = identityProviderConfig.getAlias();
|
||||
if (!identityProviderConfig.isStoreToken()) {
|
||||
if (Booleans.isFalse(identityProviderConfig.isStoreToken())) {
|
||||
if (isDebugEnabled()) {
|
||||
logger.debugf("Token will not be stored for identity provider [%s].", providerAlias);
|
||||
}
|
||||
@ -731,7 +732,7 @@ public class IdentityBrokerService implements UserAuthenticationIdentityProvider
|
||||
event.user(federatedUser);
|
||||
event.detail(Details.USERNAME, federatedUser.getUsername());
|
||||
|
||||
if (context.getIdpConfig().isAddReadTokenRoleOnCreate()) {
|
||||
if (Booleans.isTrue(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");
|
||||
@ -1014,7 +1015,7 @@ public class IdentityBrokerService implements UserAuthenticationIdentityProvider
|
||||
|
||||
|
||||
if (federatedUser != null) {
|
||||
if (context.getIdpConfig().isStoreToken()) {
|
||||
if (Booleans.isTrue(context.getIdpConfig().isStoreToken())) {
|
||||
FederatedIdentityModel oldModel = this.session.users().getFederatedIdentity(this.realmModel, federatedUser, context.getIdpConfig().getAlias());
|
||||
if (!ObjectUtil.isEqualOrBothNull(context.getToken(), oldModel.getToken())) {
|
||||
this.session.users().updateFederatedIdentity(this.realmModel, federatedUser, newModel);
|
||||
@ -1155,7 +1156,7 @@ public class IdentityBrokerService implements UserAuthenticationIdentityProvider
|
||||
}
|
||||
|
||||
private void updateToken(BrokeredIdentityContext context, UserModel federatedUser, FederatedIdentityModel federatedIdentityModel) {
|
||||
if (context.getIdpConfig().isStoreToken() && !ObjectUtil.isEqualOrBothNull(context.getToken(), federatedIdentityModel.getToken())) {
|
||||
if (Booleans.isTrue(context.getIdpConfig().isStoreToken()) && !ObjectUtil.isEqualOrBothNull(context.getToken(), federatedIdentityModel.getToken())) {
|
||||
// like in OIDCIdentityProvider.exchangeStoredToken()
|
||||
// we shouldn't override the refresh token if it is null in the context and not null in the DB
|
||||
// as for google IDP it will be lost forever
|
||||
|
||||
@ -129,12 +129,7 @@ public class IdentityProvidersResource {
|
||||
String providerId = formDataMap.getFirst("providerId").asString();
|
||||
String config = StreamUtil.readString(formDataMap.getFirst("file").asInputStream());
|
||||
IdentityProviderFactory<?> providerFactory = getProviderFactoryById(providerId);
|
||||
final Map<String, String> parsedConfig = providerFactory.parseConfig(session, config);
|
||||
String syncMode = parsedConfig.get(IdentityProviderModel.SYNC_MODE);
|
||||
if (syncMode == null) {
|
||||
parsedConfig.put(IdentityProviderModel.SYNC_MODE, "LEGACY");
|
||||
}
|
||||
return parsedConfig;
|
||||
return providerFactory.parseConfig(session, config);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -42,6 +42,7 @@ import org.keycloak.services.ErrorPage;
|
||||
import org.keycloak.services.managers.ClientSessionCode;
|
||||
import org.keycloak.services.messages.Messages;
|
||||
import org.keycloak.sessions.AuthenticationSessionModel;
|
||||
import org.keycloak.util.Booleans;
|
||||
import org.keycloak.vault.VaultStringSecret;
|
||||
import twitter4j.AccessToken;
|
||||
import twitter4j.OAuthAuthorization;
|
||||
@ -132,7 +133,7 @@ public class TwitterIdentityProvider extends AbstractIdentityProvider<OAuth2Iden
|
||||
if (requestedType != null && !requestedType.equals(TWITTER_TOKEN_TYPE)) {
|
||||
return exchangeUnsupportedRequiredType();
|
||||
}
|
||||
if (!getConfig().isStoreToken()) {
|
||||
if (Booleans.isFalse(getConfig().isStoreToken())) {
|
||||
String brokerId = tokenUserSession.getNote(Details.IDENTITY_PROVIDER);
|
||||
if (brokerId == null || !brokerId.equals(getConfig().getAlias())) {
|
||||
return exchangeNotLinkedNoStore(uriInfo, authorizedClient, tokenUserSession, tokenSubject);
|
||||
@ -255,7 +256,7 @@ public class TwitterIdentityProvider extends AbstractIdentityProvider<OAuth2Iden
|
||||
tokenBuilder.append("\"user_id\":").append("\"").append(oAuthAccessToken.getUserId()).append("\"");
|
||||
tokenBuilder.append("}");
|
||||
String token = tokenBuilder.toString();
|
||||
if (providerConfig.isStoreToken()) {
|
||||
if (Booleans.isTrue(providerConfig.isStoreToken())) {
|
||||
identity.setToken(token);
|
||||
}
|
||||
identity.getContextData().put(UserAuthenticationIdentityProvider.FEDERATED_ACCESS_TOKEN, token);
|
||||
|
||||
@ -35,8 +35,11 @@ public class AbstractIdentityProviderTest {
|
||||
|
||||
String secret = idpRep.getConfig() != null ? idpRep.getConfig().get("clientSecret") : null;
|
||||
idpRep = StripSecretsUtils.stripSecrets(null, idpRep);
|
||||
// if legacy hide on login page attribute was used, the attr will be removed when converted to model
|
||||
idpRep.setHideOnLogin(Boolean.parseBoolean(idpRep.getConfig().remove(IdentityProviderModel.LEGACY_HIDE_ON_LOGIN_ATTR)));
|
||||
|
||||
if ("true".equals(idpRep.getConfig().get(IdentityProviderModel.LEGACY_HIDE_ON_LOGIN_ATTR))) {
|
||||
idpRep.setHideOnLogin(true);
|
||||
idpRep.getConfig().remove(IdentityProviderModel.LEGACY_HIDE_ON_LOGIN_ATTR);
|
||||
}
|
||||
|
||||
AdminEventAssertion.assertEvent(adminEvents.poll(), OperationType.CREATE, AdminEventPaths.identityProviderPath(idpRep.getAlias()), idpRep, ResourceType.IDENTITY_PROVIDER);
|
||||
|
||||
|
||||
@ -93,8 +93,8 @@ public class IdentityProviderOidcTest extends AbstractIdentityProviderTest {
|
||||
assertEquals("clientId", representation.getConfig().get("clientId"));
|
||||
assertEquals(ComponentRepresentation.SECRET_VALUE, representation.getConfig().get("clientSecret"));
|
||||
assertTrue(representation.isEnabled());
|
||||
assertFalse(representation.isStoreToken());
|
||||
assertFalse(representation.isTrustEmail());
|
||||
assertNull(representation.isStoreToken());
|
||||
assertNull(representation.isTrustEmail());
|
||||
assertNull(representation.getFirstBrokerLoginFlowAlias());
|
||||
|
||||
assertEquals("some secret value", runOnServer.fetch(s -> s.identityProviders().getByAlias("new-identity-provider").getConfig().get("clientSecret"), String.class));
|
||||
@ -211,8 +211,8 @@ public class IdentityProviderOidcTest extends AbstractIdentityProviderTest {
|
||||
assertEquals(OIDCLoginProtocol.CLIENT_SECRET_BASIC, representation.getConfig().get("clientAuthMethod"));
|
||||
|
||||
assertTrue(representation.isEnabled());
|
||||
assertFalse(representation.isStoreToken());
|
||||
assertFalse(representation.isTrustEmail());
|
||||
assertNull(representation.isStoreToken());
|
||||
assertNull(representation.isTrustEmail());
|
||||
|
||||
assertEquals("some secret value", runOnServer.fetch(s -> s.identityProviders().getByAlias("new-identity-provider").getConfig().get("clientSecret"), String.class));
|
||||
|
||||
@ -249,8 +249,8 @@ public class IdentityProviderOidcTest extends AbstractIdentityProviderTest {
|
||||
assertEquals(OIDCLoginProtocol.PRIVATE_KEY_JWT, representation.getConfig().get("clientAuthMethod"));
|
||||
assertNull(representation.getConfig().get("jwtX509HeadersEnabled"));
|
||||
assertTrue(representation.isEnabled());
|
||||
assertFalse(representation.isStoreToken());
|
||||
assertFalse(representation.isTrustEmail());
|
||||
assertNull(representation.isStoreToken());
|
||||
assertNull(representation.isTrustEmail());
|
||||
|
||||
managedRealm.cleanup().add(r -> r.identityProviders().get(id).remove());
|
||||
}
|
||||
@ -283,8 +283,8 @@ public class IdentityProviderOidcTest extends AbstractIdentityProviderTest {
|
||||
assertEquals(OIDCLoginProtocol.PRIVATE_KEY_JWT, representation.getConfig().get("clientAuthMethod"));
|
||||
assertEquals("true", representation.getConfig().get("jwtX509HeadersEnabled"));
|
||||
assertTrue(representation.isEnabled());
|
||||
assertFalse(representation.isStoreToken());
|
||||
assertFalse(representation.isTrustEmail());
|
||||
assertNull(representation.isStoreToken());
|
||||
assertNull(representation.isTrustEmail());
|
||||
|
||||
managedRealm.cleanup().add(r -> r.identityProviders().get(id).remove());
|
||||
}
|
||||
|
||||
@ -417,7 +417,7 @@ public class IdentityProviderSamlTest extends AbstractIdentityProviderTest {
|
||||
// import endpoint simply converts IDPSSODescriptor into key value pairs.
|
||||
// check that saml-idp-metadata.xml was properly converted into key value pairs
|
||||
//System.out.println(config);
|
||||
List<String> keys = new ArrayList<>(List.of("syncMode",
|
||||
List<String> keys = new ArrayList<>(List.of(
|
||||
"validateSignature",
|
||||
"singleLogoutServiceUrl",
|
||||
"postBindingLogout",
|
||||
|
||||
@ -2,6 +2,9 @@ package org.keycloak.tests.client.authentication.external;
|
||||
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import jakarta.ws.rs.core.Response;
|
||||
|
||||
import org.hamcrest.MatcherAssert;
|
||||
import org.hamcrest.Matchers;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.MethodOrderer;
|
||||
import org.junit.jupiter.api.Test;
|
||||
@ -29,6 +32,7 @@ import org.keycloak.testsuite.util.IdentityProviderBuilder;
|
||||
import org.openqa.selenium.NoSuchElementException;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Map;
|
||||
|
||||
@KeycloakIntegrationTest(config = SpiffeClientAuthTest.SpiffeServerConfig.class)
|
||||
@TestMethodOrder(MethodOrderer.MethodName.class)
|
||||
@ -58,6 +62,22 @@ public class SpiffeConfigTest {
|
||||
IdentityProviderRepresentation rep = createConfig("testConfig", "spiffe://test", "https://localhost");
|
||||
Assertions.assertEquals(201, idps.create(rep).getStatus());
|
||||
|
||||
IdentityProviderRepresentation createdRep = realm.admin().identityProviders().get(rep.getAlias()).toRepresentation();
|
||||
|
||||
Assertions.assertTrue(createdRep.isEnabled());
|
||||
MatcherAssert.assertThat(createdRep.getConfig(), Matchers.equalTo(Map.of("bundleEndpoint", "https://localhost", "issuer", "spiffe://test")));
|
||||
|
||||
Assertions.assertNull(createdRep.getUpdateProfileFirstLoginMode());
|
||||
Assertions.assertNull(createdRep.getFirstBrokerLoginFlowAlias());
|
||||
Assertions.assertNull(createdRep.getPostBrokerLoginFlowAlias());
|
||||
Assertions.assertNull(createdRep.getOrganizationId());
|
||||
Assertions.assertNull(createdRep.isAddReadTokenRoleOnCreate());
|
||||
Assertions.assertNull(createdRep.isAuthenticateByDefault());
|
||||
Assertions.assertNull(createdRep.isHideOnLogin());
|
||||
Assertions.assertNull(createdRep.isLinkOnly());
|
||||
Assertions.assertNull(createdRep.isTrustEmail());
|
||||
Assertions.assertNull(createdRep.isStoreToken());
|
||||
|
||||
checkNotDisplayOnLoginPages("testConfig");
|
||||
checkNoIdpsInAccountConsole();
|
||||
}
|
||||
|
||||
@ -857,13 +857,13 @@ public final class KcOidcBrokerTest extends AbstractAdvancedBrokerTest {
|
||||
}
|
||||
|
||||
private void updateIdPSyncMode(IdentityProviderRepresentation idProvider, IdentityProviderResource idProviderResource,
|
||||
IdentityProviderSyncMode syncMode, boolean trustEmail) {
|
||||
IdentityProviderSyncMode syncMode, Boolean trustEmail) {
|
||||
assertThat(idProvider, Matchers.notNullValue());
|
||||
assertThat(idProviderResource, Matchers.notNullValue());
|
||||
assertThat(syncMode, Matchers.notNullValue());
|
||||
|
||||
if (idProvider.getConfig().get(IdentityProviderModel.SYNC_MODE).equals(syncMode.name())
|
||||
&& idProvider.isTrustEmail() == trustEmail) {
|
||||
&& trustEmail.equals(idProvider.isTrustEmail())) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@ -55,7 +55,7 @@ public class KcAdmCreateTest extends AbstractAdmCliTest {
|
||||
}
|
||||
|
||||
// If the sync mode is not present on creating the idp, it will never be stored automatically. However, the model will always report behaviour as "LEGACY", so no errors should occur.
|
||||
Assert.assertEquals("LEGACY", realmResource.identityProviders().get("idpAlias").toRepresentation().getConfig().get(IdentityProviderModel.SYNC_MODE));
|
||||
Assert.assertNull(realmResource.identityProviders().get("idpAlias").toRepresentation().getConfig().get(IdentityProviderModel.SYNC_MODE));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user