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

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,8 @@ jobs:
OSGI-INF/org.forgerock.openidm.identityProviders.xml | grep -q 'bind="bindIdentityProviderConfig"'
unzip -p openidm-authnfilter/target/openidm-authnfilter-*[0-9T].jar \
OSGI-INF/org.forgerock.openidm.authentication.xml | grep -q 'bind="bindIdentityProviderService"'
unzip -p openidm-selfservice/target/openidm-selfservice-*[0-9T].jar \
OSGI-INF/org.forgerock.openidm.selfservice.xml | grep -q 'bind="bindIdentityProviderService"'
- name: Test on Unix
if: runner.os != 'Windows'
run: |
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -250,15 +250,15 @@ public class AuthenticationService implements SingletonResourceProvider, Identit
policy = ReferencePolicy.DYNAMIC,
cardinality = ReferenceCardinality.OPTIONAL,
unbind = "unbindIdentityProviderService")
void bindIdentityProviderService(IdentityProviderService identityProviderService)
synchronized void bindIdentityProviderService(IdentityProviderService identityProviderService)
throws IdentityProviderServiceException {
this.identityProviderService = identityProviderService;
identityProviderService.registerIdentityProviderListener(this);
// no-op until activated; rebuilds the social auth modules if the service arrives later
identityProviderConfigChanged();
}

void unbindIdentityProviderService(IdentityProviderService identityProviderService)
synchronized void unbindIdentityProviderService(IdentityProviderService identityProviderService)
throws IdentityProviderServiceException {
identityProviderService.unregisterIdentityProviderListener(this);
if (this.identityProviderService == identityProviderService) {
Expand Down Expand Up @@ -312,8 +312,10 @@ public JsonValue apply(JsonValue value) {
new Predicate<JsonValue>() {
@Override
public boolean apply(JsonValue jsonValue) {
return jsonValue.get(AUTH_MODULE_NAME_KEY).asString().equals(IDMAuthModule.OPENID_CONNECT.name())
|| jsonValue.get(AUTH_MODULE_NAME_KEY).asString().equals(IDMAuthModule.OAUTH.name());
// a module configured by className alone has no name; the rebuild runs this on every module
final String name = jsonValue.get(AUTH_MODULE_NAME_KEY).asString();
return IDMAuthModule.OPENID_CONNECT.name().equals(name)
|| IDMAuthModule.OAUTH.name().equals(name);
}
};

Expand Down Expand Up @@ -346,7 +348,7 @@ public Map<String, Object> apply(JsonValue jsonValue) {
private static final Function<JsonValue, JsonValue> resolvers = new Function<JsonValue, JsonValue>() {
@Override
public JsonValue apply(JsonValue jsonValue) {
setType.apply(jsonValue);
// the resolver type is set during the rebuild: request threads must not write the published config
return jsonValue.get(AUTH_MODULE_PROPERTIES_KEY).get(AUTH_MODULE_RESOLVERS_KEY);
}
};
Expand Down Expand Up @@ -375,8 +377,9 @@ public boolean apply(JsonValue jsonValue) {
@Override
public JsonValue apply(JsonValue jsonValue) {
final JsonValue resolvers = jsonValue.get(AUTH_MODULE_PROPERTIES_KEY).get(AUTH_MODULE_RESOLVERS_KEY);
if (resolvers.isNotNull()) {
// currently we only support one resolver per auth module
// currently we only support one resolver per auth module; this runs during the rebuild, after the
// filter is set, on disabled modules too, so a malformed resolver must not fail it
if (resolvers.isList() && resolvers.size() > 0 && resolvers.get(0).isMap()) {
return resolvers.get(0).put("type", jsonValue.get(AUTH_MODULE_NAME_KEY).asString());
}
// return with no modification
Expand Down Expand Up @@ -530,17 +533,24 @@ public synchronized void identityProviderConfigChanged() throws IdentityProvider
throw new IdentityProviderServiceException(e.getMessage(), e);
}

// this now runs on DS bind threads while request threads read both fields without a lock,
// so publish complete values only
amendedConfig = newAmendedConfig;
// filter enabled module configs and get their properties;
// then filter those with valid auth properties, and build an authenticator
authenticators = FluentIterable.from(authModuleConfig)
final List<Authenticator> newAuthenticators = FluentIterable.from(authModuleConfig)
.filter(enabledAuthModules)
.transform(toModuleProperties)
.filter(authModulesThatHaveValidAuthenticatorProperties)
.transform(toAuthenticatorFromProperties)
.toList();
// readInstance and getIdentityProviderConfig report the resolver type; set it here, once,
// so that request threads only read the published config
for (final JsonValue authModule : FluentIterable.from(authModuleConfig).filter(oidcAndOauth2Modules)) {
setType.apply(authModule);
}

// this now runs on DS bind threads while request threads read both fields without a lock,
// so publish complete values only
amendedConfig = newAmendedConfig;
authenticators = newAuthenticators;
}

/**
Expand All @@ -553,7 +563,14 @@ public synchronized void activate(final ComponentContext context)
throws AuthenticationException, IdentityProviderServiceException {
logger.info("Activating Authentication Service with configuration {}", context.getProperties());
config = enhancedConfig.getConfigurationAsJson(context);
identityProviderConfigChanged();
try {
identityProviderConfigChanged();
} catch (IdentityProviderServiceException | RuntimeException e) {
// DS calls no deactivate after a failed activate, but it still unbinds the references, and
// unbindIdentityProviderService rebuilds: leave this instance no configuration to rebuild from
config = null;
throw e;
}
logger.debug("OpenIDM Config for Authentication {} is activated.", config.get(Constants.SERVICE_PID));
}

Expand Down Expand Up @@ -586,7 +603,7 @@ public synchronized void deactivate(ComponentContext context) {
* @throws AuthenticationException on missing or incorrect configuration, or failure to construct an auth module
* from the config
*/
private Filter configureAuthenticationFilter(JsonValue jsonConfig) throws AuthenticationException {
Filter configureAuthenticationFilter(JsonValue jsonConfig) throws AuthenticationException {
if (jsonConfig == null || jsonConfig.size() == 0) {
throw new AuthenticationException("No auth modules configured");
}
Expand Down Expand Up @@ -816,7 +833,6 @@ private ProviderConfig getIdentityProviderConfig(final String providerName) thro
.transformAndConcat(resolvers)
.filter(enabledResolvers)
.filter(forProvider(providerName))
.transform(setType)
.transform(ProviderConfigMapper.toProviderConfig)
.first();

Expand Down
Loading
Loading