Skip to content

Commit

Permalink
Provide API support to configure fido trusted origins
Browse files Browse the repository at this point in the history
  • Loading branch information
ImalshaG committed Apr 26, 2024
1 parent d1758e5 commit e7e5d30
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 20 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,8 @@
import static org.wso2.carbon.identity.application.authenticator.fido2.util.FIDO2AuthenticatorConstants.FIDO2_CONFIG_MDS_VALIDATION_ATTRIBUTE_NAME;
import static org.wso2.carbon.identity.application.authenticator.fido2.util.FIDO2AuthenticatorConstants.FIDO2_CONFIG_MDS_VALIDATION_DEFAULT_VALUE;
import static org.wso2.carbon.identity.application.authenticator.fido2.util.FIDO2AuthenticatorConstants.FIDO2_CONFIG_RESOURCE_NAME;
import static org.wso2.carbon.identity.application.authenticator.fido2.util.FIDO2AuthenticatorConstants.FIDO2_CONFIG_TRUSTED_ORIGIN_ATTRIBUTE_NAME;
import static org.wso2.carbon.identity.application.authenticator.fido2.util.FIDO2AuthenticatorConstants.FIDO2_CONNECTOR_CONFIG_RESOURCE_NAME;
import static org.wso2.carbon.identity.application.authenticator.fido2.util.FIDO2AuthenticatorConstants.FIDO2_USER;
import static org.wso2.carbon.identity.application.authenticator.fido2.util.FIDO2AuthenticatorConstants.FIDO_CONFIG_RESOURCE_TYPE_NAME;
import static org.wso2.carbon.identity.application.authenticator.fido2.util.FIDO2AuthenticatorConstants.FIRST_NAME_CLAIM_URL;
Expand Down Expand Up @@ -992,32 +994,40 @@ private User getPrivilegedUser() {

private void readTrustedOrigins() {

if (origins == null) {
origins = new ArrayList<>();
origins = new ArrayList<>();
String[] trustedOriginsFromDB = null;
try {
trustedOriginsFromDB = getFIDO2TrustedOrigins();
} catch (FIDO2AuthenticatorServerException e) {
log.error("Error when retrieving FIDO trusted origins from DB. Using the default values from files.");
}
if (trustedOriginsFromDB != null) {
origins.addAll(Arrays.asList(trustedOriginsFromDB));
} else {
Object value = IdentityConfigParser.getInstance().getConfiguration().get(TRUSTED_ORIGINS);
if (value instanceof ArrayList) {
origins.addAll((ArrayList) value);
} else if (value instanceof String) {
origins.add((String) value);
}
origins.replaceAll(IdentityUtil::fillURLPlaceholders);

/*
* Process the list of origins to ensure all variations are covered:
* 1. For each origin, remove the default ports (443 for HTTPS and 80 for HTTP) if they are explicitly
* specified.
* 2. Then, for each origin, add variations with the default ports explicitly appended.
* 3. This ensures that the list contains both versions of each origin (with and without default ports),
* accommodating scenarios where the default port might be omitted or explicitly included in the origin
* string.
*/
List<String> updatedOrigins = origins.stream()
.flatMap(url -> Stream.of(removeDefaultPort(url), appendDefaultPortIfAbsent(url))).distinct()
.collect(Collectors.toList());

origins.clear();
origins.addAll(updatedOrigins);
}
origins.replaceAll(IdentityUtil::fillURLPlaceholders);

/*
* Process the list of origins to ensure all variations are covered:
* 1. For each origin, remove the default ports (443 for HTTPS and 80 for HTTP) if they are explicitly
* specified.
* 2. Then, for each origin, add variations with the default ports explicitly appended.
* 3. This ensures that the list contains both versions of each origin (with and without default ports),
* accommodating scenarios where the default port might be omitted or explicitly included in the origin
* string.
*/
List<String> updatedOrigins = origins.stream()
.flatMap(url -> Stream.of(removeDefaultPort(url), appendDefaultPortIfAbsent(url))).distinct()
.collect(Collectors.toList());

origins.clear();
origins.addAll(updatedOrigins);
}

private String removeDefaultPort(String url) {
Expand Down Expand Up @@ -1271,6 +1281,37 @@ private FIDO2Configuration getAuthenticatorConfigs() throws FIDO2AuthenticatorSe
return new FIDO2Configuration(attestationValidationEnabled, mdsValidationEnabled);
}

private String[] getFIDO2TrustedOrigins() throws FIDO2AuthenticatorServerException {

String[] fidoTrustedOrigins = null;
try {
fidoTrustedOrigins = FIDO2AuthenticatorServiceDataHolder.getInstance().getConfigurationManager()
.getAttribute(FIDO_CONFIG_RESOURCE_TYPE_NAME, FIDO2_CONNECTOR_CONFIG_RESOURCE_NAME,
FIDO2_CONFIG_TRUSTED_ORIGIN_ATTRIBUTE_NAME).getValue().split(",");
} catch (ConfigurationManagementException e) {
if (Objects.equals(e.getErrorCode(), ERROR_CODE_ATTRIBUTE_DOES_NOT_EXISTS.getCode())) {
if (log.isDebugEnabled()) {
log.debug(FIDO2_CONFIG_TRUSTED_ORIGIN_ATTRIBUTE_NAME
+ " attribute doesn't exist for the tenant: "
+ PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId()
+ ". Using the default configuration value from files.");
}
} else if (Objects.equals(e.getErrorCode(), ERROR_CODE_RESOURCE_DOES_NOT_EXISTS.getCode())) {
if (log.isDebugEnabled()) {
log.debug(FIDO2_CONNECTOR_CONFIG_RESOURCE_NAME + " resource doesn't exist for the tenant: "
+ PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId()
+ ". Using the default configuration value from files for the attribute: "
+ FIDO2_CONFIG_TRUSTED_ORIGIN_ATTRIBUTE_NAME + ".");
}
} else {
throw new FIDO2AuthenticatorServerException("Error in retrieving "
+ FIDO2_CONFIG_TRUSTED_ORIGIN_ATTRIBUTE_NAME + " configuration for the tenant: "
+ PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(), e);
}
}
return fidoTrustedOrigins;
}

public boolean isFidoKeyRegistered (String username) throws AuthenticationFailedException {
try {
return !userStorage.getFIDO2RegistrationsByUsername(username).isEmpty();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,10 +62,12 @@ private FIDO2AuthenticatorConstants() {

public static final String FIDO_CONFIG_RESOURCE_TYPE_NAME = "fido-config";
public static final String FIDO2_CONFIG_RESOURCE_NAME = "fido2-validations";
public static final String FIDO2_CONNECTOR_CONFIG_RESOURCE_NAME = "fido-connector";
public static final String FIDO2_CONFIG_ATTESTATION_VALIDATION_ATTRIBUTE_NAME = "AttestationValidation.Enable";
public static final boolean FIDO2_CONFIG_ATTESTATION_VALIDATION_DEFAULT_VALUE = true;
public static final String FIDO2_CONFIG_MDS_VALIDATION_ATTRIBUTE_NAME = "MDSValidation.Enable";
public static final boolean FIDO2_CONFIG_MDS_VALIDATION_DEFAULT_VALUE = false;
public static final String FIDO2_CONFIG_TRUSTED_ORIGIN_ATTRIBUTE_NAME = "FIDO2TrustedOrigins";

/**
* SQL Queries class for FIDO2 Authenticator Constants Util class.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@
import org.wso2.carbon.identity.application.authenticator.fido2.util.FIDOUtil;
import org.wso2.carbon.identity.application.common.model.User;
import org.wso2.carbon.identity.configuration.mgt.core.ConfigurationManager;
import org.wso2.carbon.identity.configuration.mgt.core.exception.ConfigurationManagementException;
import org.wso2.carbon.identity.configuration.mgt.core.model.Attribute;
import org.wso2.carbon.identity.core.util.IdentityConfigParser;
import org.wso2.carbon.identity.core.util.IdentityTenantUtil;
Expand Down Expand Up @@ -121,8 +122,10 @@
import static org.powermock.api.mockito.PowerMockito.whenNew;
import static org.wso2.carbon.identity.application.authenticator.fido2.util.FIDO2AuthenticatorConstants.FIDO2_CONFIG_ATTESTATION_VALIDATION_ATTRIBUTE_NAME;
import static org.wso2.carbon.identity.application.authenticator.fido2.util.FIDO2AuthenticatorConstants.FIDO2_CONFIG_MDS_VALIDATION_ATTRIBUTE_NAME;
import static org.wso2.carbon.identity.application.authenticator.fido2.util.FIDO2AuthenticatorConstants.FIDO2_CONFIG_TRUSTED_ORIGIN_ATTRIBUTE_NAME;
import static org.wso2.carbon.identity.application.authenticator.fido2.util.FIDO2AuthenticatorConstants.FIDO2_CONFIG_RESOURCE_NAME;
import static org.wso2.carbon.identity.application.authenticator.fido2.util.FIDO2AuthenticatorConstants.FIDO_CONFIG_RESOURCE_TYPE_NAME;
import static org.wso2.carbon.identity.application.authenticator.fido2.util.FIDO2AuthenticatorConstants.FIDO2_CONNECTOR_CONFIG_RESOURCE_NAME;
import static org.wso2.carbon.utils.multitenancy.MultitenantConstants.SUPER_TENANT_DOMAIN_NAME;
import static org.wso2.carbon.utils.multitenancy.MultitenantConstants.SUPER_TENANT_ID;

Expand Down Expand Up @@ -214,7 +217,7 @@ public class WebAuthnServiceTest {
private AssertionResult assertionResult;

@BeforeMethod
public void setUp() throws UserStoreException, IOException, FIDO2AuthenticatorServerException {
public void setUp() throws UserStoreException, IOException, FIDO2AuthenticatorServerException, ConfigurationManagementException {

prepareResources();
initMocks(this);
Expand All @@ -230,6 +233,9 @@ public void setUp() throws UserStoreException, IOException, FIDO2AuthenticatorSe
when(FIDO2DeviceStoreDAO.getInstance()).thenReturn(fido2DeviceStoreDAO);
trustedOrigins.add(ORIGIN);
identityConfig.put(FIDO2AuthenticatorConstants.TRUSTED_ORIGINS, trustedOrigins);
when(configurationManager.getAttribute(FIDO_CONFIG_RESOURCE_TYPE_NAME, FIDO2_CONNECTOR_CONFIG_RESOURCE_NAME,
FIDO2_CONFIG_TRUSTED_ORIGIN_ATTRIBUTE_NAME)).thenReturn(
new Attribute(FIDO2_CONFIG_TRUSTED_ORIGIN_ATTRIBUTE_NAME, (String.join(",",trustedOrigins))));
mockStatic(IdentityConfigParser.class);
when(IdentityConfigParser.getInstance()).thenReturn(identityConfigParser);
when(identityConfigParser.getConfiguration()).thenReturn(identityConfig);
Expand Down

0 comments on commit e7e5d30

Please sign in to comment.