From 18c9128ed959697426fe55c4ea690a6f64f10fc6 Mon Sep 17 00:00:00 2001 From: Brock Allen Date: Sat, 13 Feb 2021 11:59:39 -0500 Subject: [PATCH 1/3] Revert "feat: merge openid-configuration and metdata" --- src/MetadataService.js | 24 ++++-------------------- test/unit/MetadataService.spec.js | 31 ++++--------------------------- 2 files changed, 8 insertions(+), 47 deletions(-) diff --git a/src/MetadataService.js b/src/MetadataService.js index f45bdc25..e5c8fad1 100644 --- a/src/MetadataService.js +++ b/src/MetadataService.js @@ -15,7 +15,6 @@ export class MetadataService { this._settings = settings; this._jsonService = new JsonServiceCtor(['application/jwk-set+json']); - this._metadata_promise; } get metadataUrl() { @@ -44,39 +43,24 @@ export class MetadataService { } getMetadata() { - // metadata was preloaded and no url was provided, so use the supplied data. - if (!this.metadataUrl && this._settings.metadata) { + if (this._settings.metadata) { Log.debug("MetadataService.getMetadata: Returning metadata from settings"); return Promise.resolve(this._settings.metadata); } - // no url was provided and settings were not pre-loaded then throw an error. if (!this.metadataUrl) { Log.error("MetadataService.getMetadata: No authority or metadataUrl configured on settings"); return Promise.reject(new Error("No authority or metadataUrl configured on settings")); } - // if we've already started fetching metadata return the existing promise so we don't call it again. - if (this._metadata_promise) { - Log.debug("MetadataService.getMetadata: getting metadata from cache promise", this.metadataUrl); - return this._metadata_promise - } - Log.debug("MetadataService.getMetadata: getting metadata from", this.metadataUrl); - this._metadata_promise = this._jsonService.getJson(this.metadataUrl) + return this._jsonService.getJson(this.metadataUrl) .then(metadata => { Log.debug("MetadataService.getMetadata: json received"); - // overlay .well-known/openid-configuration over seeded setting. this allows consumers to set values - // like end_session_url for Auth0 when it is not available in the configuration endpoint. - // precedence was set on the assumption the issuers hosted configuration is always more accurate - // than what the developer seeded the client with. - if (!this._settings.metadata) this._settings.metadata = {} - Object.assign(this._settings.metadata, metadata); - return this._settings.metadata; + this._settings.metadata = metadata; + return metadata; }); - - return this._metadata_promise; } getIssuer() { diff --git a/test/unit/MetadataService.spec.js b/test/unit/MetadataService.spec.js index 900a8469..561c4d0a 100644 --- a/test/unit/MetadataService.spec.js +++ b/test/unit/MetadataService.spec.js @@ -93,26 +93,24 @@ describe("MetadataService", function() { it("should return metadata from json call", function(done) { settings.metadataUrl = "http://sts/metadata"; - const expected = { test: "test" }; - stubJsonService.result = Promise.resolve(expected); + stubJsonService.result = Promise.resolve("test"); let p = subject.getMetadata(); p.then(result => { - result.should.deep.equal(expected); + result.should.equal("test"); done(); }); }); it("should cache metadata from json call", function(done) { settings.metadataUrl = "http://sts/metadata"; - const expected = { test: "test" }; - stubJsonService.result = Promise.resolve(expected); + stubJsonService.result = Promise.resolve("test"); let p = subject.getMetadata(); p.then(result => { - settings.metadata.should.deep.equal(expected); + settings.metadata.should.equal("test"); done(); }); }); @@ -129,27 +127,6 @@ describe("MetadataService", function() { }); }); - it("should return merge openid-configuration from json call and injected metadata", function(done) { - settings.metadataUrl = "http://sts/metadata"; - settings.metadata = { - property1: "injected", - property2: "injected" - } - const response = { property2: "merged" }; - const expected = { - property1: "injected", - property2: "merged" - } - stubJsonService.result = Promise.resolve(response); - - let p = subject.getMetadata(); - - p.then(result => { - result.should.deep.equal(expected); - done(); - }); - }); - }); describe("_getMetadataProperty", function() { From 2280f3d3d81cd07a59aa80165d80ad14b3328c92 Mon Sep 17 00:00:00 2001 From: Brock Allen Date: Sat, 13 Feb 2021 12:37:11 -0500 Subject: [PATCH 2/3] add metadataSeed to allow merging discovery document into additional metadata --- src/MetadataService.js | 6 +++++- src/OidcClientSettings.js | 9 ++++++++- test/unit/MetadataService.spec.js | 17 +++++++++++++++-- 3 files changed, 28 insertions(+), 4 deletions(-) diff --git a/src/MetadataService.js b/src/MetadataService.js index e5c8fad1..d6d2b97b 100644 --- a/src/MetadataService.js +++ b/src/MetadataService.js @@ -58,7 +58,11 @@ export class MetadataService { return this._jsonService.getJson(this.metadataUrl) .then(metadata => { Log.debug("MetadataService.getMetadata: json received"); - this._settings.metadata = metadata; + + var mergedMetadata = this._settings.metadataSeed || {}; + Object.assign(mergedMetadata, metadata); + + this._settings.metadata = mergedMetadata; return metadata; }); } diff --git a/src/OidcClientSettings.js b/src/OidcClientSettings.js index 1b381b39..530d4c9e 100644 --- a/src/OidcClientSettings.js +++ b/src/OidcClientSettings.js @@ -18,7 +18,7 @@ const DefaultClockSkewInSeconds = 60 * 5; export class OidcClientSettings { constructor({ // metadata related - authority, metadataUrl, metadata, signingKeys, + authority, metadataUrl, metadata, signingKeys, metadataSeed, // client related client_id, client_secret, response_type = DefaultResponseType, scope = DefaultScope, redirect_uri, post_logout_redirect_uri, @@ -44,6 +44,7 @@ export class OidcClientSettings { this._authority = authority; this._metadataUrl = metadataUrl; this._metadata = metadata; + this._metadataSeed = metadataSeed; this._signingKeys = signingKeys; this._client_id = client_id; @@ -172,6 +173,12 @@ export class OidcClientSettings { set metadata(value) { this._metadata = value; } + get metadataSeed() { + return this._metadataSeed; + } + set metadataSeed(value) { + this._metadataSeed = value; + } get signingKeys() { return this._signingKeys; diff --git a/test/unit/MetadataService.spec.js b/test/unit/MetadataService.spec.js index 561c4d0a..ac597094 100644 --- a/test/unit/MetadataService.spec.js +++ b/test/unit/MetadataService.spec.js @@ -105,12 +105,25 @@ describe("MetadataService", function() { it("should cache metadata from json call", function(done) { settings.metadataUrl = "http://sts/metadata"; - stubJsonService.result = Promise.resolve("test"); + stubJsonService.result = Promise.resolve({test:"value"}); + + let p = subject.getMetadata(); + + p.then(result => { + settings.metadata.should.deep.equal({test:"value"}); + done(); + }); + }); + + it("should merge metadata from seed", function(done) { + settings.metadataUrl = "http://sts/metadata"; + settings.metadataSeed = {test1:"one"}; + stubJsonService.result = Promise.resolve({test2:"two"}); let p = subject.getMetadata(); p.then(result => { - settings.metadata.should.equal("test"); + settings.metadata.should.deep.equal({test1:"one", test2:"two"}); done(); }); }); From 162f8a514b74a29e1ab226676de53af2eb4c189c Mon Sep 17 00:00:00 2001 From: Brock Allen Date: Sat, 13 Feb 2021 12:37:20 -0500 Subject: [PATCH 3/3] add sample to show setting metadata --- samples/VanillaJS/public/code-identityserver-sample.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/samples/VanillaJS/public/code-identityserver-sample.js b/samples/VanillaJS/public/code-identityserver-sample.js index d87f77f8..ac8b8996 100644 --- a/samples/VanillaJS/public/code-identityserver-sample.js +++ b/samples/VanillaJS/public/code-identityserver-sample.js @@ -53,7 +53,11 @@ var settings = { filterProtocolClaims: true, loadUserInfo: true, - revokeAccessTokenOnSignout : true + revokeAccessTokenOnSignout : true, + + //metadata: {"issuer":"https://demo.identityserver.io","jwks_uri":"https://demo.identityserver.io/.well-known/openid-configuration/jwks","authorization_endpoint":"https://demo.identityserver.io/connect/authorize","token_endpoint":"https://demo.identityserver.io/connect/token","userinfo_endpoint":"https://demo.identityserver.io/connect/userinfo","end_session_endpoint":"https://demo.identityserver.io/connect/endsession","check_session_iframe":"https://demo.identityserver.io/connect/checksession","revocation_endpoint":"https://demo.identityserver.io/connect/revocation","introspection_endpoint":"https://demo.identityserver.io/connect/introspect","device_authorization_endpoint":"https://demo.identityserver.io/connect/deviceauthorization","frontchannel_logout_supported":true,"frontchannel_logout_session_supported":true,"backchannel_logout_supported":true,"backchannel_logout_session_supported":true,"scopes_supported":["openid","profile","email","api","api.scope1","api.scope2","scope2","policyserver.runtime","policyserver.management","offline_access"],"claims_supported":["sub","name","family_name","given_name","middle_name","nickname","preferred_username","profile","picture","website","gender","birthdate","zoneinfo","locale","updated_at","email","email_verified"],"grant_types_supported":["authorization_code","client_credentials","refresh_token","implicit","password","urn:ietf:params:oauth:grant-type:device_code"],"response_types_supported":["code","token","id_token","id_token token","code id_token","code token","code id_token token"],"response_modes_supported":["form_post","query","fragment"],"token_endpoint_auth_methods_supported":["client_secret_basic","client_secret_post"],"id_token_signing_alg_values_supported":["RS256"],"subject_types_supported":["public"],"code_challenge_methods_supported":["plain","S256"],"request_parameter_supported":true}, + //metadataSeed: {"some_extra_data":"some_value"}, + //signingKeys:[{"kty":"RSA","use":"sig","kid":"5CCAA03EDDE26D53104CC35D0D4B299C","e":"AQAB","n":"3fbgsZuL5Kp7HyliAznS6N0kTTAqApIzYqu0tORUk4T9m2f3uW5lDomNmwwPuZ3QDn0nwN3esx2NvZjL_g5DN407Pgl0ffHhARdtydJvdvNJIpW4CmyYGnI8H4ZdHtuW4wF8GbKadIGgwpI4UqcsHuPiWKARfWZMQfPKBT08SiIPwGncavlRRDgRVX1T94AgZE_fOTJ4Odko9RX9iNXghJIzJ_wEkY9GEkoHz5lQGdHYUplxOS6fcxL8j_N9urSBlnoYjPntBOwUfPsMoNcmIDXPARcq10miWTz8SHzUYRtsiSUMqimRJ9KdCucKcCmttB_p_EAWohJQDnav-Vqi3Q","alg":"RS256"}] }; var mgr = new Oidc.UserManager(settings);