diff --git a/core/src/main/java/org/keycloak/representations/idm/RealmRepresentation.java b/core/src/main/java/org/keycloak/representations/idm/RealmRepresentation.java index d7e77d6dfc..47d62c7e1b 100755 --- a/core/src/main/java/org/keycloak/representations/idm/RealmRepresentation.java +++ b/core/src/main/java/org/keycloak/representations/idm/RealmRepresentation.java @@ -138,6 +138,7 @@ public class RealmRepresentation { protected Integer webAuthnPolicyCreateTimeout; protected Boolean webAuthnPolicyAvoidSameAuthenticatorRegister; protected List webAuthnPolicyAcceptableAaguids; + protected List webAuthnPolicyExtraOrigins; // WebAuthn passwordless properties below @@ -151,6 +152,7 @@ public class RealmRepresentation { protected Integer webAuthnPolicyPasswordlessCreateTimeout; protected Boolean webAuthnPolicyPasswordlessAvoidSameAuthenticatorRegister; protected List webAuthnPolicyPasswordlessAcceptableAaguids; + protected List webAuthnPolicyPasswordlessExtraOrigins; // Client Policies/Profiles @@ -1127,6 +1129,14 @@ public class RealmRepresentation { this.webAuthnPolicyAcceptableAaguids = webAuthnPolicyAcceptableAaguids; } + public List getWebAuthnPolicyExtraOrigins(){ + return webAuthnPolicyExtraOrigins; + } + + public void setWebAuthnPolicyExtraOrigins(List extraOrigins) { + this.webAuthnPolicyExtraOrigins = extraOrigins; + } + // WebAuthn passwordless properties below @@ -1210,6 +1220,14 @@ public class RealmRepresentation { this.webAuthnPolicyPasswordlessAcceptableAaguids = webAuthnPolicyPasswordlessAcceptableAaguids; } + public List getWebAuthnPolicyPasswordlessExtraOrigins(){ + return webAuthnPolicyPasswordlessExtraOrigins; + } + + public void setWebAuthnPolicyPasswordlessExtraOrigins(List extraOrigins) { + this.webAuthnPolicyPasswordlessExtraOrigins = extraOrigins; + } + // Client Policies/Profiles @JsonIgnore diff --git a/js/apps/admin-ui/public/locales/en/translation.json b/js/apps/admin-ui/public/locales/en/translation.json index ff9a3ccd1d..e67335ae0e 100644 --- a/js/apps/admin-ui/public/locales/en/translation.json +++ b/js/apps/admin-ui/public/locales/en/translation.json @@ -2386,7 +2386,9 @@ "webAuthnPolicyCreateTimeoutHint": "Timeout needs to be between 0 seconds and 8 hours", "webAuthnPolicyAvoidSameAuthenticatorRegister": "Avoid same authenticator registration", "webAuthnPolicyAcceptableAaguids": "Acceptable AAGUIDs", + "webAuthnPolicyExtraOrigins": "Extra Origins", "addAaguids": "Add AAGUID", + "addOrigins": "Add Origin", "webAuthnUpdateSuccess": "Updated webauthn policies successfully", "webAuthnUpdateError": "Could not update webauthn policies due to {{error}}", "flowName": "Flow name", @@ -2496,6 +2498,7 @@ "webAuthnPolicyCreateTimeoutHelp": "Timeout value for creating user's public key credential in seconds. if set to 0, this timeout option is not adapted.", "webAuthnPolicyAvoidSameAuthenticatorRegisterHelp": "Avoid registering the authenticator that has already been registered.", "webAuthnPolicyAcceptableAaguidsHelp": "The list of AAGUID of which an authenticator can be registered.", + "webAuthnPolicyExtraOriginsHelp": "The list of extra origin for non-web application.", "passwordPoliciesHelp": { "forceExpiredPasswordChange": "The number of days the password is valid before a new password is required.", "hashIterations": "The number of times a password is hashed before storage or verification. Default: 27,500.", diff --git a/js/apps/admin-ui/public/locales/ja/translation.json b/js/apps/admin-ui/public/locales/ja/translation.json index 1b3a802d7b..3757d93505 100644 --- a/js/apps/admin-ui/public/locales/ja/translation.json +++ b/js/apps/admin-ui/public/locales/ja/translation.json @@ -603,6 +603,8 @@ "webAuthnPolicyCreateTimeout": "タイムアウト", "webAuthnPolicyAvoidSameAuthenticatorRegister": "オーセンティケーターの重複登録回避", "webAuthnPolicyAcceptableAaguids": "許容可能なAAGUID", + "webAuthnPolicyExtraOrigins": "エクストラオリジンズ", + "addOrigins": "オリジンを追加", "default": "DEFAULT", "flow": { "browser": "ブラウザーフロー", @@ -640,6 +642,7 @@ "webAuthnPolicyCreateTimeoutHelp": "ユーザーの公開鍵クレデンシャルの作成に対するタイムアウト値(秒単位)。0に設定すると、このタイムアウト・オプションは適応されません。", "webAuthnPolicyAvoidSameAuthenticatorRegisterHelp": "すでに登録されているオーセンティケーターの登録を避けるかどうかを設定します。", "webAuthnPolicyAcceptableAaguidsHelp": "登録可能なオーセンティケーターのAAGUIDのリスト。", + "webAuthnPolicyExtraOriginsHelp": "非 Web アプリケーションの追加オリジンのリスト。", "unlinkUsers": "ユーザーのリンクを解除する", "removeImported": "インポートを削除", "vendor": "ベンダー", diff --git a/js/apps/admin-ui/public/locales/zh-CN/translation.json b/js/apps/admin-ui/public/locales/zh-CN/translation.json index e42a56d6b2..c3825e0f53 100644 --- a/js/apps/admin-ui/public/locales/zh-CN/translation.json +++ b/js/apps/admin-ui/public/locales/zh-CN/translation.json @@ -2342,7 +2342,9 @@ "webAuthnPolicyCreateTimeoutHint": "超时时间需要在 0 秒到 8 小时之间", "webAuthnPolicyAvoidSameAuthenticatorRegister": "避免相同的身份验证器注册", "webAuthnPolicyAcceptableAaguids": "可接受的 AAGUID", + "webAuthnPolicyExtraOrigins": "额外的 Origin", "addAaguids": "添加 AAGUID", + "addOrigins": "添加 Origin", "webAuthnUpdateSuccess": "已成功更新 webauthn 策略", "webAuthnUpdateError": "由于{{error}},无法更新 webauthn 策略", "flowName": "流程名称", @@ -2451,6 +2453,7 @@ "webAuthnPolicyCreateTimeoutHelp": "以秒为单位创建用户公钥凭证的超时值。如果设置为 0,则不适应此超时选项。", "webAuthnPolicyAvoidSameAuthenticatorRegisterHelp": "避免注册已经被注册过的验证器。", "webAuthnPolicyAcceptableAaguidsHelp": "AAGUID 列表,其中可以注册验证者。", + "webAuthnPolicyExtraOriginsHelp": "额外的 Origin 列表,用于非网络应用程序。", "密码策略": { "forceExpiredPasswordChange": "在需要新密码之前,当前密码的有效天数。", "hashIterations": "密码在存储或验证之前被散列的次数。默认值:27,500。", diff --git a/js/apps/admin-ui/src/authentication/policies/WebauthnPolicy.tsx b/js/apps/admin-ui/src/authentication/policies/WebauthnPolicy.tsx index 145ff0dfc2..d70b0b6a97 100644 --- a/js/apps/admin-ui/src/authentication/policies/WebauthnPolicy.tsx +++ b/js/apps/admin-ui/src/authentication/policies/WebauthnPolicy.tsx @@ -349,6 +349,22 @@ export const WebauthnPolicy = ({ addButtonLabel="addAaguids" /> + + } + > + + diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/RealmAdapter.java b/model/jpa/src/main/java/org/keycloak/models/jpa/RealmAdapter.java index 015efe6b5c..cff752cce0 100755 --- a/model/jpa/src/main/java/org/keycloak/models/jpa/RealmAdapter.java +++ b/model/jpa/src/main/java/org/keycloak/models/jpa/RealmAdapter.java @@ -961,6 +961,12 @@ public class RealmAdapter implements LegacyRealmModel, JpaModel { acceptableAaguids = Arrays.asList(acceptableAaguidsString.split(",")); policy.setAcceptableAaguids(acceptableAaguids); + String extraOriginsString = getAttribute(RealmAttributes.WEBAUTHN_POLICY_EXTRA_ORIGINS + attributePrefix); + List extraOrigins = new ArrayList<>(); + if (extraOriginsString != null && !extraOriginsString.isEmpty()) + extraOrigins = Arrays.asList(extraOriginsString.split(",")); + policy.setExtraOrigins(extraOrigins); + return policy; } @@ -1004,6 +1010,14 @@ public class RealmAdapter implements LegacyRealmModel, JpaModel { } else { removeAttribute(RealmAttributes.WEBAUTHN_POLICY_ACCEPTABLE_AAGUIDS + attributePrefix); } + + List extraOrigins = policy.getExtraOrigins(); + if (extraOrigins != null && !extraOrigins.isEmpty()) { + String extraOriginsString = String.join(",", extraOrigins); + setAttribute(RealmAttributes.WEBAUTHN_POLICY_EXTRA_ORIGINS + attributePrefix, extraOriginsString); + } else { + removeAttribute(RealmAttributes.WEBAUTHN_POLICY_EXTRA_ORIGINS + attributePrefix); + } } @Override diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/RealmAttributes.java b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/RealmAttributes.java index 09dc7c0c92..c6d5bbefb6 100644 --- a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/RealmAttributes.java +++ b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/RealmAttributes.java @@ -50,6 +50,7 @@ public interface RealmAttributes { String WEBAUTHN_POLICY_CREATE_TIMEOUT = "webAuthnPolicyCreateTimeout"; String WEBAUTHN_POLICY_AVOID_SAME_AUTHENTICATOR_REGISTER = "webAuthnPolicyAvoidSameAuthenticatorRegister"; String WEBAUTHN_POLICY_ACCEPTABLE_AAGUIDS = "webAuthnPolicyAcceptableAaguids"; + String WEBAUTHN_POLICY_EXTRA_ORIGINS = "webAuthnPolicyExtraOrigins"; String ADMIN_EVENTS_EXPIRATION = "adminEventsExpiration"; diff --git a/model/legacy-private/src/main/java/org/keycloak/storage/datastore/LegacyExportImportManager.java b/model/legacy-private/src/main/java/org/keycloak/storage/datastore/LegacyExportImportManager.java index e8b6675e63..3bd77c9d66 100644 --- a/model/legacy-private/src/main/java/org/keycloak/storage/datastore/LegacyExportImportManager.java +++ b/model/legacy-private/src/main/java/org/keycloak/storage/datastore/LegacyExportImportManager.java @@ -1216,6 +1216,9 @@ public class LegacyExportImportManager implements ExportImportManager { List webAuthnPolicyAcceptableAaguids = rep.getWebAuthnPolicyAcceptableAaguids(); if (webAuthnPolicyAcceptableAaguids != null) webAuthnPolicy.setAcceptableAaguids(webAuthnPolicyAcceptableAaguids); + List webAuthnPolicyExtraOrigins = rep.getWebAuthnPolicyExtraOrigins(); + if (webAuthnPolicyExtraOrigins != null) webAuthnPolicy.setExtraOrigins(webAuthnPolicyExtraOrigins); + return webAuthnPolicy; } @@ -1268,6 +1271,9 @@ public class LegacyExportImportManager implements ExportImportManager { List webAuthnPolicyAcceptableAaguids = rep.getWebAuthnPolicyPasswordlessAcceptableAaguids(); if (webAuthnPolicyAcceptableAaguids != null) webAuthnPolicy.setAcceptableAaguids(webAuthnPolicyAcceptableAaguids); + List webAuthnPolicyExtraOrigins = rep.getWebAuthnPolicyPasswordlessExtraOrigins(); + if (webAuthnPolicyExtraOrigins != null) webAuthnPolicy.setExtraOrigins(webAuthnPolicyExtraOrigins); + return webAuthnPolicy; } public static Map importAuthenticationFlows(KeycloakSession session, RealmModel newRealm, RealmRepresentation rep) { diff --git a/model/map-hot-rod/src/main/java/org/keycloak/models/map/storage/hotRod/realm/entity/HotRodWebAuthnPolicyEntity.java b/model/map-hot-rod/src/main/java/org/keycloak/models/map/storage/hotRod/realm/entity/HotRodWebAuthnPolicyEntity.java index 40e5d9f502..fd656c7ba5 100644 --- a/model/map-hot-rod/src/main/java/org/keycloak/models/map/storage/hotRod/realm/entity/HotRodWebAuthnPolicyEntity.java +++ b/model/map-hot-rod/src/main/java/org/keycloak/models/map/storage/hotRod/realm/entity/HotRodWebAuthnPolicyEntity.java @@ -30,6 +30,8 @@ public class HotRodWebAuthnPolicyEntity extends AbstractHotRodEntity { public List acceptableAaguids; @ProtoField(number = 10) public List signatureAlgorithms; + @ProtoField(number = 11) + public List extraOrigins; @Override public boolean equals(Object o) { return HotRodWebAuthnPolicyEntityDelegate.entityEquals(this, o); diff --git a/model/map/src/main/java/org/keycloak/models/map/datastore/MapExportImportManager.java b/model/map/src/main/java/org/keycloak/models/map/datastore/MapExportImportManager.java index 2715832eff..d1c872c807 100644 --- a/model/map/src/main/java/org/keycloak/models/map/datastore/MapExportImportManager.java +++ b/model/map/src/main/java/org/keycloak/models/map/datastore/MapExportImportManager.java @@ -1419,6 +1419,9 @@ public class MapExportImportManager implements ExportImportManager { List webAuthnPolicyAcceptableAaguids = rep.getWebAuthnPolicyAcceptableAaguids(); if (webAuthnPolicyAcceptableAaguids != null) webAuthnPolicy.setAcceptableAaguids(webAuthnPolicyAcceptableAaguids); + List webAuthnPolicyExtraOrigins = rep.getWebAuthnPolicyExtraOrigins(); + if (webAuthnPolicyExtraOrigins != null) webAuthnPolicy.setExtraOrigins(webAuthnPolicyExtraOrigins); + return webAuthnPolicy; } @@ -1471,6 +1474,9 @@ public class MapExportImportManager implements ExportImportManager { List webAuthnPolicyAcceptableAaguids = rep.getWebAuthnPolicyPasswordlessAcceptableAaguids(); if (webAuthnPolicyAcceptableAaguids != null) webAuthnPolicy.setAcceptableAaguids(webAuthnPolicyAcceptableAaguids); + List webAuthnPolicyExtraOrigins = rep.getWebAuthnPolicyPasswordlessExtraOrigins(); + if (webAuthnPolicyExtraOrigins != null) webAuthnPolicy.setExtraOrigins(webAuthnPolicyExtraOrigins); + return webAuthnPolicy; } public static Map importAuthenticationFlows(KeycloakSession session, RealmModel newRealm, RealmRepresentation rep) { diff --git a/model/map/src/main/java/org/keycloak/models/map/realm/entity/MapWebAuthnPolicyEntity.java b/model/map/src/main/java/org/keycloak/models/map/realm/entity/MapWebAuthnPolicyEntity.java index f9e06b9837..5087ff2070 100644 --- a/model/map/src/main/java/org/keycloak/models/map/realm/entity/MapWebAuthnPolicyEntity.java +++ b/model/map/src/main/java/org/keycloak/models/map/realm/entity/MapWebAuthnPolicyEntity.java @@ -43,6 +43,7 @@ public interface MapWebAuthnPolicyEntity extends UpdatableEntity { entity.setCreateTimeout(model.getCreateTimeout()); entity.setAvoidSameAuthenticatorRegister(model.isAvoidSameAuthenticatorRegister()); entity.setAcceptableAaguids(model.getAcceptableAaguids()); + entity.setExtraOrigins(model.getExtraOrigins()); return entity; } @@ -60,6 +61,8 @@ public interface MapWebAuthnPolicyEntity extends UpdatableEntity { model.setAvoidSameAuthenticatorRegister(entity.isAvoidSameAuthenticatorRegister()); List acceptableAaguids = entity.getAcceptableAaguids(); model.setAcceptableAaguids(acceptableAaguids == null ? new LinkedList<>() : new LinkedList<>(acceptableAaguids)); + List extraOrigins = entity.getExtraOrigins(); + model.setExtraOrigins(extraOrigins == null ? new LinkedList<>() : new LinkedList<>(extraOrigins)); return model; } @@ -75,6 +78,7 @@ public interface MapWebAuthnPolicyEntity extends UpdatableEntity { entity.setCreateTimeout(0); entity.setAvoidSameAuthenticatorRegister(false); entity.setAcceptableAaguids(new LinkedList<>()); + entity.setExtraOrigins(new LinkedList<>()); return entity; } @@ -107,4 +111,7 @@ public interface MapWebAuthnPolicyEntity extends UpdatableEntity { List getAcceptableAaguids(); void setAcceptableAaguids(List acceptableAaguids); + + List getExtraOrigins(); + void setExtraOrigins(List extraOrigins); } diff --git a/server-spi-private/src/main/java/org/keycloak/models/utils/ModelToRepresentation.java b/server-spi-private/src/main/java/org/keycloak/models/utils/ModelToRepresentation.java index fbcfdf00d6..8ffd6674c5 100755 --- a/server-spi-private/src/main/java/org/keycloak/models/utils/ModelToRepresentation.java +++ b/server-spi-private/src/main/java/org/keycloak/models/utils/ModelToRepresentation.java @@ -489,6 +489,7 @@ public class ModelToRepresentation { rep.setWebAuthnPolicyCreateTimeout(webAuthnPolicy.getCreateTimeout()); rep.setWebAuthnPolicyAvoidSameAuthenticatorRegister(webAuthnPolicy.isAvoidSameAuthenticatorRegister()); rep.setWebAuthnPolicyAcceptableAaguids(webAuthnPolicy.getAcceptableAaguids()); + rep.setWebAuthnPolicyExtraOrigins(webAuthnPolicy.getExtraOrigins()); webAuthnPolicy = realm.getWebAuthnPolicyPasswordless(); rep.setWebAuthnPolicyPasswordlessRpEntityName(webAuthnPolicy.getRpEntityName()); @@ -501,6 +502,7 @@ public class ModelToRepresentation { rep.setWebAuthnPolicyPasswordlessCreateTimeout(webAuthnPolicy.getCreateTimeout()); rep.setWebAuthnPolicyPasswordlessAvoidSameAuthenticatorRegister(webAuthnPolicy.isAvoidSameAuthenticatorRegister()); rep.setWebAuthnPolicyPasswordlessAcceptableAaguids(webAuthnPolicy.getAcceptableAaguids()); + rep.setWebAuthnPolicyPasswordlessExtraOrigins(webAuthnPolicy.getExtraOrigins()); CibaConfig cibaPolicy = realm.getCibaPolicy(); Map attrMap = Optional.ofNullable(rep.getAttributes()).orElse(new HashMap<>()); diff --git a/server-spi/src/main/java/org/keycloak/models/WebAuthnPolicy.java b/server-spi/src/main/java/org/keycloak/models/WebAuthnPolicy.java index 4154ad9775..f43909c0ff 100644 --- a/server-spi/src/main/java/org/keycloak/models/WebAuthnPolicy.java +++ b/server-spi/src/main/java/org/keycloak/models/WebAuthnPolicy.java @@ -40,6 +40,7 @@ public class WebAuthnPolicy implements Serializable { protected int createTimeout = 0; // not specified as option protected boolean avoidSameAuthenticatorRegister = false; protected List acceptableAaguids; + protected List extraOrigins; public WebAuthnPolicy() { } @@ -130,4 +131,12 @@ public class WebAuthnPolicy implements Serializable { public void setAcceptableAaguids(List acceptableAaguids) { this.acceptableAaguids = acceptableAaguids; } + + public List getExtraOrigins(){ + return extraOrigins; + } + + public void setExtraOrigins(List extraOrigins) { + this.extraOrigins = extraOrigins; + } } diff --git a/services/src/main/java/org/keycloak/credential/WebAuthnCredentialProvider.java b/services/src/main/java/org/keycloak/credential/WebAuthnCredentialProvider.java index 920fc3b6d6..5b9c228782 100644 --- a/services/src/main/java/org/keycloak/credential/WebAuthnCredentialProvider.java +++ b/services/src/main/java/org/keycloak/credential/WebAuthnCredentialProvider.java @@ -16,15 +16,24 @@ package org.keycloak.credential; -import java.io.IOException; -import java.util.Arrays; -import java.util.List; -import java.util.Set; -import java.util.stream.Collectors; - import com.webauthn4j.WebAuthnAuthenticationManager; +import com.webauthn4j.authenticator.Authenticator; +import com.webauthn4j.authenticator.AuthenticatorImpl; import com.webauthn4j.converter.util.ObjectConverter; +import com.webauthn4j.data.AuthenticationData; +import com.webauthn4j.data.AuthenticationParameters; import com.webauthn4j.data.AuthenticatorTransport; +import com.webauthn4j.data.attestation.authenticator.AAGUID; +import com.webauthn4j.data.attestation.authenticator.AttestedCredentialData; +import com.webauthn4j.data.attestation.authenticator.COSEKey; +import com.webauthn4j.data.client.CollectedClientData; +import com.webauthn4j.data.client.Origin; +import com.webauthn4j.server.ServerProperty; +import com.webauthn4j.util.AssertUtil; +import com.webauthn4j.util.exception.WebAuthnException; +import com.webauthn4j.validator.OriginValidatorImpl; +import com.webauthn4j.validator.exception.BadOriginException; +import org.checkerframework.checker.nullness.qual.NonNull; import org.jboss.logging.Logger; import org.keycloak.authentication.requiredactions.WebAuthnRegisterFactory; import org.keycloak.common.util.Base64; @@ -32,18 +41,16 @@ import org.keycloak.common.util.Time; import org.keycloak.models.KeycloakSession; import org.keycloak.models.RealmModel; import org.keycloak.models.UserModel; - -import com.webauthn4j.authenticator.Authenticator; -import com.webauthn4j.authenticator.AuthenticatorImpl; -import com.webauthn4j.data.AuthenticationData; -import com.webauthn4j.data.AuthenticationParameters; -import com.webauthn4j.data.attestation.authenticator.AAGUID; -import com.webauthn4j.data.attestation.authenticator.AttestedCredentialData; -import com.webauthn4j.data.attestation.authenticator.COSEKey; -import com.webauthn4j.util.exception.WebAuthnException; +import org.keycloak.models.WebAuthnPolicy; import org.keycloak.models.credential.WebAuthnCredentialModel; import org.keycloak.models.credential.dto.WebAuthnCredentialData; +import java.io.IOException; +import java.util.Arrays; +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; + /** * Credential provider for WebAuthn 2-factor credential of the user */ @@ -180,7 +187,7 @@ public class WebAuthnCredentialProvider implements CredentialProvider auths = getWebAuthnCredentialModelList(realm, user); - WebAuthnAuthenticationManager webAuthnAuthenticationManager = new WebAuthnAuthenticationManager(); + WebAuthnAuthenticationManager webAuthnAuthenticationManager = getWebAuthnAuthenticationManager(); AuthenticationData authenticationData = null; try { @@ -233,6 +240,31 @@ public class WebAuthnCredentialProvider implements CredentialProvider origins = policy.getExtraOrigins().stream() + .map(Origin::new) + .collect(Collectors.toSet()); + WebAuthnAuthenticationManager webAuthnAuthenticationManager = new WebAuthnAuthenticationManager(); + webAuthnAuthenticationManager.getAuthenticationDataValidator().setOriginValidator(new OriginValidatorImpl(){ + @Override + protected void validate(@NonNull CollectedClientData collectedClientData, + @NonNull ServerProperty serverProperty) { + AssertUtil.notNull(collectedClientData, "collectedClientData must not be null"); + AssertUtil.notNull(serverProperty, "serverProperty must not be null"); + final Origin clientOrigin = collectedClientData.getOrigin(); + if (serverProperty.getOrigins().contains(clientOrigin)) return; + // https://github.com/w3c/webauthn/issues/1297 + if (origins.contains(clientOrigin)) return; + throw new BadOriginException("The collectedClientData '" + clientOrigin + "' origin doesn't match any of the preconfigured origins."); + } + }); + return webAuthnAuthenticationManager; + } + + protected WebAuthnPolicy getWebAuthnPolicy() { + return session.getContext().getRealm().getWebAuthnPolicy(); + } @Override public String getType() { diff --git a/services/src/main/java/org/keycloak/credential/WebAuthnCredentialProviderFactory.java b/services/src/main/java/org/keycloak/credential/WebAuthnCredentialProviderFactory.java index ff0619a459..c473dc39f5 100644 --- a/services/src/main/java/org/keycloak/credential/WebAuthnCredentialProviderFactory.java +++ b/services/src/main/java/org/keycloak/credential/WebAuthnCredentialProviderFactory.java @@ -16,12 +16,9 @@ package org.keycloak.credential; -import org.keycloak.Config; +import com.webauthn4j.converter.util.ObjectConverter; import org.keycloak.common.Profile; import org.keycloak.models.KeycloakSession; - -import com.webauthn4j.converter.util.ObjectConverter; -import org.keycloak.models.KeycloakSessionFactory; import org.keycloak.provider.EnvironmentDependentProviderFactory; public class WebAuthnCredentialProviderFactory implements CredentialProviderFactory, EnvironmentDependentProviderFactory { diff --git a/services/src/main/java/org/keycloak/credential/WebAuthnPasswordlessCredentialProvider.java b/services/src/main/java/org/keycloak/credential/WebAuthnPasswordlessCredentialProvider.java index d5b91c1ad9..b5cef67626 100644 --- a/services/src/main/java/org/keycloak/credential/WebAuthnPasswordlessCredentialProvider.java +++ b/services/src/main/java/org/keycloak/credential/WebAuthnPasswordlessCredentialProvider.java @@ -21,6 +21,7 @@ package org.keycloak.credential; import com.webauthn4j.converter.util.ObjectConverter; import org.keycloak.authentication.requiredactions.WebAuthnPasswordlessRegisterFactory; import org.keycloak.models.KeycloakSession; +import org.keycloak.models.WebAuthnPolicy; import org.keycloak.models.credential.WebAuthnCredentialModel; /** @@ -51,4 +52,9 @@ public class WebAuthnPasswordlessCredentialProvider extends WebAuthnCredentialPr .removeable(true) .build(getKeycloakSession()); } + + @Override + protected WebAuthnPolicy getWebAuthnPolicy() { + return getKeycloakSession().getContext().getRealm().getWebAuthnPolicyPasswordless(); + } }