IdentityProviderService never learns about the identity providers the deployment configured, so
everything built from that list is empty: /identityProviders answers {"providers":[]}, no social
auth module is created, and the social self-service stage is handed no providers.
Cause
IdentityProviderService declares the reference to the provider configurations on a field:
@Reference(
service = IdentityProviderConfig.class,
cardinality = ReferenceCardinality.MULTIPLE,
policy = ReferencePolicy.DYNAMIC)
private final Map<String, List<IdentityProviderConfig>> identityProviders = new ConcurrentHashMap<>();
openidm-identity-provider/src/main/java/org/forgerock/openidm/idp/impl/IdentityProviderService.java:146-150
Declarative Services only injects a field whose type is the service type, a ServiceReference, a
ComponentServiceObjects, Map<String, Object> (the service properties) or a Map.Entry. A
Map<String, List<IdentityProviderConfig>> is none of those, so SCR rejects the reference and logs:
SEVERE: Bundle: org.openidentityplatform.openidm.identity-provider [62]
bundle org.openidentityplatform.openidm.identity-provider:7.1.2 (62)[org.forgerock.openidm.identityProviders(20)]
: Field identityProviders in class class org.forgerock.openidm.idp.impl.IdentityProviderService
has unsupported type java.util.Map
The component still activates, but identityProviders stays empty for the lifetime of the process.
bindIdentityProviderConfig / unbindIdentityProviderConfig are already written right below the
field (:153-197) and are never called, because the annotation sits on the field rather than on them.
Impact
Everything that reads the bound configurations:
IdentityProviderService.readInstance (:322-333) — GET /identityProviders always answers
{"providers":[]};
AuthenticationService (openidm-authnfilter/.../AuthenticationService.java:413-418) — the
OPENID_CONNECT and OAUTH auth modules are generated from that list, so none is created and
social login is not available;
SelfService.amendConfig (openidm-selfservice/.../SelfService.java:190-195) — the
socialUserDetails self-service stage is configured with an empty provider list;
IdentityProviderService.getProfile → getIdentityProvider(name) (:218-243) — answers null
for every name, so ui/bindBehavior.js cannot bind a social account.
Steps to reproduce
On a stock openidentityplatform/openidm:7.1.2:
- add
conf/identityProviders.json ({"providers": []} is enough to start the service) and a
provider instance conf/identityProvider-google.json with "enabled": true;
- wait for
Activating Identity Provider Config with configuration {config.factory-pid=google, ...}
in logs/openidm0.log.0 — the provider configuration component does activate;
curl -u openidm-admin:openidm-admin -H 'X-Requested-With: curl' http://localhost:8080/openidm/identityProviders
Expected: the google provider. Actual:
The SEVERE line above is in the log, and POST /openidm/identityProviders?_action=availableProviders
does answer with the provider, because that action reads providerConfigs from
conf/identityProviders.json instead of the bound components.
Suggested fix
Move the annotation from the field to the existing bind method, which is what the rest of the class
already expects:
@Reference(
service = IdentityProviderConfig.class,
cardinality = ReferenceCardinality.MULTIPLE,
policy = ReferencePolicy.DYNAMIC,
unbind = "unbindIdentityProviderConfig")
protected void bindIdentityProviderConfig(final IdentityProviderConfig config) { ... }
The same declaration is on master; the run above is on the released 7.1.2 image.
IdentityProviderServicenever learns about the identity providers the deployment configured, soeverything built from that list is empty:
/identityProvidersanswers{"providers":[]}, no socialauth module is created, and the social self-service stage is handed no providers.
Cause
IdentityProviderServicedeclares the reference to the provider configurations on a field:openidm-identity-provider/src/main/java/org/forgerock/openidm/idp/impl/IdentityProviderService.java:146-150Declarative Services only injects a field whose type is the service type, a
ServiceReference, aComponentServiceObjects,Map<String, Object>(the service properties) or aMap.Entry. AMap<String, List<IdentityProviderConfig>>is none of those, so SCR rejects the reference and logs:The component still activates, but
identityProvidersstays empty for the lifetime of the process.bindIdentityProviderConfig/unbindIdentityProviderConfigare already written right below thefield (
:153-197) and are never called, because the annotation sits on the field rather than on them.Impact
Everything that reads the bound configurations:
IdentityProviderService.readInstance(:322-333) —GET /identityProvidersalways answers{"providers":[]};AuthenticationService(openidm-authnfilter/.../AuthenticationService.java:413-418) — theOPENID_CONNECTandOAUTHauth modules are generated from that list, so none is created andsocial login is not available;
SelfService.amendConfig(openidm-selfservice/.../SelfService.java:190-195) — thesocialUserDetailsself-service stage is configured with an empty provider list;IdentityProviderService.getProfile→getIdentityProvider(name)(:218-243) — answersnullfor every name, so
ui/bindBehavior.jscannot bind a social account.Steps to reproduce
On a stock
openidentityplatform/openidm:7.1.2:conf/identityProviders.json({"providers": []}is enough to start the service) and aprovider instance
conf/identityProvider-google.jsonwith"enabled": true;Activating Identity Provider Config with configuration {config.factory-pid=google, ...}in
logs/openidm0.log.0— the provider configuration component does activate;curl -u openidm-admin:openidm-admin -H 'X-Requested-With: curl' http://localhost:8080/openidm/identityProvidersExpected: the google provider. Actual:
{"providers":[]}The
SEVEREline above is in the log, andPOST /openidm/identityProviders?_action=availableProvidersdoes answer with the provider, because that action reads
providerConfigsfromconf/identityProviders.jsoninstead of the bound components.Suggested fix
Move the annotation from the field to the existing bind method, which is what the rest of the class
already expects:
The same declaration is on
master; the run above is on the released 7.1.2 image.