WebAuthn support for native applications. Support custom FIDO2 origin validation (#23156)
Closes #23155
This commit is contained in:
parent
6074cbf311
commit
31759f9c37
16 changed files with 145 additions and 20 deletions
|
@ -138,6 +138,7 @@ public class RealmRepresentation {
|
|||
protected Integer webAuthnPolicyCreateTimeout;
|
||||
protected Boolean webAuthnPolicyAvoidSameAuthenticatorRegister;
|
||||
protected List<String> webAuthnPolicyAcceptableAaguids;
|
||||
protected List<String> webAuthnPolicyExtraOrigins;
|
||||
|
||||
// WebAuthn passwordless properties below
|
||||
|
||||
|
@ -151,6 +152,7 @@ public class RealmRepresentation {
|
|||
protected Integer webAuthnPolicyPasswordlessCreateTimeout;
|
||||
protected Boolean webAuthnPolicyPasswordlessAvoidSameAuthenticatorRegister;
|
||||
protected List<String> webAuthnPolicyPasswordlessAcceptableAaguids;
|
||||
protected List<String> webAuthnPolicyPasswordlessExtraOrigins;
|
||||
|
||||
// Client Policies/Profiles
|
||||
|
||||
|
@ -1127,6 +1129,14 @@ public class RealmRepresentation {
|
|||
this.webAuthnPolicyAcceptableAaguids = webAuthnPolicyAcceptableAaguids;
|
||||
}
|
||||
|
||||
public List<String> getWebAuthnPolicyExtraOrigins(){
|
||||
return webAuthnPolicyExtraOrigins;
|
||||
}
|
||||
|
||||
public void setWebAuthnPolicyExtraOrigins(List<String> extraOrigins) {
|
||||
this.webAuthnPolicyExtraOrigins = extraOrigins;
|
||||
}
|
||||
|
||||
// WebAuthn passwordless properties below
|
||||
|
||||
|
||||
|
@ -1210,6 +1220,14 @@ public class RealmRepresentation {
|
|||
this.webAuthnPolicyPasswordlessAcceptableAaguids = webAuthnPolicyPasswordlessAcceptableAaguids;
|
||||
}
|
||||
|
||||
public List<String> getWebAuthnPolicyPasswordlessExtraOrigins(){
|
||||
return webAuthnPolicyPasswordlessExtraOrigins;
|
||||
}
|
||||
|
||||
public void setWebAuthnPolicyPasswordlessExtraOrigins(List<String> extraOrigins) {
|
||||
this.webAuthnPolicyPasswordlessExtraOrigins = extraOrigins;
|
||||
}
|
||||
|
||||
// Client Policies/Profiles
|
||||
|
||||
@JsonIgnore
|
||||
|
|
|
@ -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.",
|
||||
|
|
|
@ -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": "ベンダー",
|
||||
|
|
|
@ -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。",
|
||||
|
|
|
@ -349,6 +349,22 @@ export const WebauthnPolicy = ({
|
|||
addButtonLabel="addAaguids"
|
||||
/>
|
||||
</FormGroup>
|
||||
<FormGroup
|
||||
label={t("webAuthnPolicyExtraOrigins")}
|
||||
fieldId="webAuthnPolicyExtraOrigins"
|
||||
labelIcon={
|
||||
<HelpItem
|
||||
helpText={t("webAuthnPolicyExtraOriginsHelp")}
|
||||
fieldLabelId="webAuthnPolicyExtraOrigins"
|
||||
/>
|
||||
}
|
||||
>
|
||||
<MultiLineInput
|
||||
name={`${namePrefix}ExtraOrigins`}
|
||||
aria-label={t("webAuthnPolicyExtraOrigins")}
|
||||
addButtonLabel="addOrigins"
|
||||
/>
|
||||
</FormGroup>
|
||||
</FormProvider>
|
||||
|
||||
<ActionGroup>
|
||||
|
|
|
@ -961,6 +961,12 @@ public class RealmAdapter implements LegacyRealmModel, JpaModel<RealmEntity> {
|
|||
acceptableAaguids = Arrays.asList(acceptableAaguidsString.split(","));
|
||||
policy.setAcceptableAaguids(acceptableAaguids);
|
||||
|
||||
String extraOriginsString = getAttribute(RealmAttributes.WEBAUTHN_POLICY_EXTRA_ORIGINS + attributePrefix);
|
||||
List<String> 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<RealmEntity> {
|
|||
} else {
|
||||
removeAttribute(RealmAttributes.WEBAUTHN_POLICY_ACCEPTABLE_AAGUIDS + attributePrefix);
|
||||
}
|
||||
|
||||
List<String> 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
|
||||
|
|
|
@ -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";
|
||||
|
||||
|
|
|
@ -1216,6 +1216,9 @@ public class LegacyExportImportManager implements ExportImportManager {
|
|||
List<String> webAuthnPolicyAcceptableAaguids = rep.getWebAuthnPolicyAcceptableAaguids();
|
||||
if (webAuthnPolicyAcceptableAaguids != null) webAuthnPolicy.setAcceptableAaguids(webAuthnPolicyAcceptableAaguids);
|
||||
|
||||
List<String> webAuthnPolicyExtraOrigins = rep.getWebAuthnPolicyExtraOrigins();
|
||||
if (webAuthnPolicyExtraOrigins != null) webAuthnPolicy.setExtraOrigins(webAuthnPolicyExtraOrigins);
|
||||
|
||||
return webAuthnPolicy;
|
||||
}
|
||||
|
||||
|
@ -1268,6 +1271,9 @@ public class LegacyExportImportManager implements ExportImportManager {
|
|||
List<String> webAuthnPolicyAcceptableAaguids = rep.getWebAuthnPolicyPasswordlessAcceptableAaguids();
|
||||
if (webAuthnPolicyAcceptableAaguids != null) webAuthnPolicy.setAcceptableAaguids(webAuthnPolicyAcceptableAaguids);
|
||||
|
||||
List<String> webAuthnPolicyExtraOrigins = rep.getWebAuthnPolicyPasswordlessExtraOrigins();
|
||||
if (webAuthnPolicyExtraOrigins != null) webAuthnPolicy.setExtraOrigins(webAuthnPolicyExtraOrigins);
|
||||
|
||||
return webAuthnPolicy;
|
||||
}
|
||||
public static Map<String, String> importAuthenticationFlows(KeycloakSession session, RealmModel newRealm, RealmRepresentation rep) {
|
||||
|
|
|
@ -30,6 +30,8 @@ public class HotRodWebAuthnPolicyEntity extends AbstractHotRodEntity {
|
|||
public List<String> acceptableAaguids;
|
||||
@ProtoField(number = 10)
|
||||
public List<String> signatureAlgorithms;
|
||||
@ProtoField(number = 11)
|
||||
public List<String> extraOrigins;
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
return HotRodWebAuthnPolicyEntityDelegate.entityEquals(this, o);
|
||||
|
|
|
@ -1419,6 +1419,9 @@ public class MapExportImportManager implements ExportImportManager {
|
|||
List<String> webAuthnPolicyAcceptableAaguids = rep.getWebAuthnPolicyAcceptableAaguids();
|
||||
if (webAuthnPolicyAcceptableAaguids != null) webAuthnPolicy.setAcceptableAaguids(webAuthnPolicyAcceptableAaguids);
|
||||
|
||||
List<String> webAuthnPolicyExtraOrigins = rep.getWebAuthnPolicyExtraOrigins();
|
||||
if (webAuthnPolicyExtraOrigins != null) webAuthnPolicy.setExtraOrigins(webAuthnPolicyExtraOrigins);
|
||||
|
||||
return webAuthnPolicy;
|
||||
}
|
||||
|
||||
|
@ -1471,6 +1474,9 @@ public class MapExportImportManager implements ExportImportManager {
|
|||
List<String> webAuthnPolicyAcceptableAaguids = rep.getWebAuthnPolicyPasswordlessAcceptableAaguids();
|
||||
if (webAuthnPolicyAcceptableAaguids != null) webAuthnPolicy.setAcceptableAaguids(webAuthnPolicyAcceptableAaguids);
|
||||
|
||||
List<String> webAuthnPolicyExtraOrigins = rep.getWebAuthnPolicyPasswordlessExtraOrigins();
|
||||
if (webAuthnPolicyExtraOrigins != null) webAuthnPolicy.setExtraOrigins(webAuthnPolicyExtraOrigins);
|
||||
|
||||
return webAuthnPolicy;
|
||||
}
|
||||
public static Map<String, String> importAuthenticationFlows(KeycloakSession session, RealmModel newRealm, RealmRepresentation rep) {
|
||||
|
|
|
@ -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<String> acceptableAaguids = entity.getAcceptableAaguids();
|
||||
model.setAcceptableAaguids(acceptableAaguids == null ? new LinkedList<>() : new LinkedList<>(acceptableAaguids));
|
||||
List<String> 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<String> getAcceptableAaguids();
|
||||
void setAcceptableAaguids(List<String> acceptableAaguids);
|
||||
|
||||
List<String> getExtraOrigins();
|
||||
void setExtraOrigins(List<String> extraOrigins);
|
||||
}
|
||||
|
|
|
@ -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<String, String> attrMap = Optional.ofNullable(rep.getAttributes()).orElse(new HashMap<>());
|
||||
|
|
|
@ -40,6 +40,7 @@ public class WebAuthnPolicy implements Serializable {
|
|||
protected int createTimeout = 0; // not specified as option
|
||||
protected boolean avoidSameAuthenticatorRegister = false;
|
||||
protected List<String> acceptableAaguids;
|
||||
protected List<String> extraOrigins;
|
||||
|
||||
public WebAuthnPolicy() {
|
||||
}
|
||||
|
@ -130,4 +131,12 @@ public class WebAuthnPolicy implements Serializable {
|
|||
public void setAcceptableAaguids(List<String> acceptableAaguids) {
|
||||
this.acceptableAaguids = acceptableAaguids;
|
||||
}
|
||||
|
||||
public List<String> getExtraOrigins(){
|
||||
return extraOrigins;
|
||||
}
|
||||
|
||||
public void setExtraOrigins(List<String> extraOrigins) {
|
||||
this.extraOrigins = extraOrigins;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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<WebAuthnCr
|
|||
WebAuthnCredentialModelInput context = WebAuthnCredentialModelInput.class.cast(input);
|
||||
List<WebAuthnCredentialModelInput> auths = getWebAuthnCredentialModelList(realm, user);
|
||||
|
||||
WebAuthnAuthenticationManager webAuthnAuthenticationManager = new WebAuthnAuthenticationManager();
|
||||
WebAuthnAuthenticationManager webAuthnAuthenticationManager = getWebAuthnAuthenticationManager();
|
||||
AuthenticationData authenticationData = null;
|
||||
|
||||
try {
|
||||
|
@ -233,6 +240,31 @@ public class WebAuthnCredentialProvider implements CredentialProvider<WebAuthnCr
|
|||
return false;
|
||||
}
|
||||
|
||||
protected WebAuthnAuthenticationManager getWebAuthnAuthenticationManager() {
|
||||
WebAuthnPolicy policy = getWebAuthnPolicy();
|
||||
Set<Origin> 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() {
|
||||
|
|
|
@ -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<WebAuthnCredentialProvider>, EnvironmentDependentProviderFactory {
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue